 
  var Toolkit = {
	Sandbox : window,
	Canvas : document,
	version : 1.0,
	Log : {} 
};
  
    
Toolkit.Drawing = {}
Toolkit.Math = {
	degToRad: function(x) { return (x*Math.PI) / 180; },
	radToDeg: function(x) { return (angle*180) / Math.PI; },
	
	factorial: function(n) {
		if(n<1) { return 0; }
		var retVal = 1;
		for(var i=1;i<=n;i++) retVal *= i;
		return retVal;
	},

	
	permutations: function(n,k) {
		if(n==0 || k==0) return 1;
		return (Toolkit.Math.factorial(n) / Toolkit.Math.factorial(n-k));
	},

	
	combinations: function(n,r) {
		if(n==0 || r==0) return 1;
		return (Toolkit.Math.factorial(n) / (Toolkit.Math.factorial(n-r) * Toolkit.Math.factorial(r)));
	},
	

	bernstein: function (t,n,i) {
		return ( Toolkit.Math.combinations(n,i) * Math.pow(t,i) * Math.pow(1-t,n-i) );
	}
};

Toolkit.Drawing.Curves = {
	
	Line: function(start, end) {
		this.start = start;
		this.end = end;
		this.dimensions = start.length;
		this.getValue = function(n) {
			var retVal = new Array(this.dimensions);
			for(var i=0;i<this.dimensions;i++)
				retVal[i] = ((this.end[i] - this.start[i]) * n) + this.start[i];
			return retVal;
		}
		return this;
	},

Bezier: function(pnts) {
		this.getValue = function(step) {
			var retVal = new Array(this.p[0].length);
			for(var k=0;j<this.p[0].length;k++) retVal[k]=0;
			for(var j=0;j<this.p[0].length;j++) {
				var C=0; var D=0;
				for(var i=0;i<this.p.length;i++) C += this.p[i][j] * this.p[this.p.length-1][0] * Toolkit.Math.bernstein(step,this.p.length,i);
				for(var l=0;l<this.p.length;l++) D += this.p[this.p.length-1][0] * Toolkit.Math.bernstein(step,this.p.length,l);
				retVal[j] = C/D;
			}
			return retVal;
		}
		this.p = pnts;
		return this;
	}
};

Toolkit.Drawing.animations = new Array();

Toolkit.Drawing.Animation = function(curve,duration,acc) {
	
	if(typeof acc.getValue == "function") this.speedCurve = acc;
	else if(acc) {
		this.acc = acc;
		this.speedCurve = new Toolkit.Drawing.Curves.Bezier([[0],[Math.abs((1+this.acc)/3)],[(2+this.acc)/3],[1]]);
	} else this.acc = 0;
	this.duration = duration;
	this.startTime = 0;
	this.endTime = 0;
	this.percent = 0;
	this.active = false;
	this.lastFrame = new Date().valueOf();
	this.fps = 0;
	this.id = Toolkit.Drawing.animations.length;
	Toolkit.Drawing.animations[this.id] = this;
	this.curve = curve;
	if(!curve.getValue) { alert("[Toolkit.Drawing.Animation] Invalid Curve object"); return; }
	this.onstart = function() {};
	this.onend = function() {};
	this.onanimate = function() {};
	this.onpause = function() {};
	this.onunpause = function() {};
	this.start = function() {
		var coordinates = this.curve.getValue(0);
		var evt = { coordinates: coordinates,
		            startTime: new Date().valueOf(),
		            duration: this.duration,
		            percent: 0
		          };
		this.onstart(evt);
		this.startTime = new Date().valueOf(),
		this.endTime = new Date().valueOf() + this.duration;
		this.percent = 0;
		this.active = true;
		this.cycle();
	}

	this.stop = function(gotoEnd) {
		var curTime = new Date().valueOf();
		var step = (curTime - this.startTime) / (this.endTime - this.startTime);
		if(step>1) step=1;
		this.percent = step*100;
		this.fps = 1000 / ((new Date().valueOf()) - this.lastFrame);
		this.lastFrame = new Date().valueOf();
		this.active = false;
		var substep = step;
		if(this.acc != 0) substep = this.speedCurve.getValue(step)[0];
		var e = null;
		if(gotoEnd) e = { coordinates: this.curve.getValue(1), startTime: this.startTime, duration: this.duration, percent: this.percent, fps: Math.round(this.fps) };
		else e = { coordinates: this.curve.getValue(substep), startTime: this.startTime, duration: this.duration, percent: this.percent, fps: Math.round(this.fps) };
		this.onanimate(e);
		this.onend(e);
	}

	this.cycle = function() {
		var curTime = new Date().valueOf();
		var step = (curTime - this.startTime) / (this.endTime - this.startTime);
		this.percent = step*100;
		this.fps = 1000 / ((new Date().valueOf()) - this.lastFrame);
		this.lastFrame = new Date().valueOf();
		if(step <= 1 && this.active == true) {
			var substep = step;
			if(this.acc != 0) substep = this.speedCurve.getValue(step)[0];
			this.onanimate({ coordinates: this.curve.getValue(substep), startTime: this.startTime, duration: this.duration, percent: this.percent, fps: Math.round(this.fps) });
			setTimeout("Toolkit.Drawing.animations[" + this.id + "].cycle()",5);
		} else if(this.active==true) {
			this.active = false;
			var e = { coordinates: this.curve.getValue(1), startTime: this.startTime, duration: this.duration, percent: this.percent, fps: Math.round(this.fps) };
			this.onanimate(e);
			this.onend(e);

		}
	}

	//return this;
}

 
if( !window.Toolkit ) alert( "Toolkit has to be included before Toolkit.Events." );

Toolkit.Events = {
	addListener : function( object, eventName, listener, thisObj ) {
		if( thisObj == null || thisObj == undefined ) thisObj = window;
		if( typeof object[ eventName + "listeners" ] == "undefined" ) this._prepareForListeners( object, eventName );
		var listeners = object[ eventName + "listeners" ];
		var setListener = true;
		for( var i = 0; setListener && i < listeners.length; i++ ) {
			if( listeners[ i ][ 0 ] == listener && listeners[ i ][ 1 ] == thisObj ) {
				setListener = false;
			}
		}
		if( setListener ) listeners[ listeners.length ] = [ listener, thisObj ];
		return false;
	},


	removeListener : function( object, eventName, listener, thisObj ) {
		if( thisObj == null || thisObj == undefined ) thisObj = window;
		var listeners = object[ eventName + "listeners" ];
		if( listeners ) {
			for( var i = 0; i < listeners.length; i++ ) {
				if( listeners[ i ][ 0 ] == listener && listeners[ i ][ 1 ] == thisObj ) {
					for( var j = i; j < listeners.length - 1; j++ ) {
						listeners[ j ] = listeners[ j + 1 ];
					}
					listeners.length--;
					break;
				}
			}
		}
		return false;
	},


	clearListeners : function( object, eventName ) {
		object[ eventName + "listeners" ] = [];
		return false;
	},


	_prepareForListeners : function( object, eventName ) {
		object[ eventName + "listeners" ] = [];
		if( typeof object[ eventName ] == "function" ) {
			object[ eventName + "listeners" ][ 0 ] = [ object[ eventName ], object ];
		}
		object[ eventName ] = function() {
			var i;
			var argumentsCopy = [];
			for( i = 0; i < arguments.length; i++ ) argumentsCopy[ i ] = arguments[ i ];
			if( arguments.length == 0 && window.event ) {
				argumentsCopy[ 0 ] = Toolkit.Events._patchEvent( window.event, this );
			}
			else if( arguments[ 0 ] && typeof arguments[ 0 ] == "object"
									&& arguments[ 0 ].toString().search( /event/i ) != -1 ) {
				argumentsCopy[ 0 ] = Toolkit.Events._patchEvent( arguments[ 0 ], this );
			}

			
			var listeners = this[ eventName + "listeners" ];
			var listenersCopy = [];
			for( i = 0; i < listeners.length; i++ ) listenersCopy[ i ] = listeners[ i ];
			for( i = 0; i < listenersCopy.length; i++ ) {
				listenersCopy[ i ][ 0 ].apply( listenersCopy[ i ][ 1 ], argumentsCopy );
			}
		};
	},


	_patchEvent : function( evt, currentTarget ) {
		if( !evt.target ) evt.target = evt.srcElement;
		if( !evt.currentTarget ) evt.currentTarget = currentTarget;
		if( typeof evt.layerX == "undefined" ) evt.layerX = evt.offsetX;
		if( typeof evt.layerY == "undefined" ) evt.layerY = evt.offsetY;
		if( typeof evt.clientX == "undefined" ) evt.clientX = evt.pageX;
		if( typeof evt.clientY == "undefined" ) evt.clientY = evt.pageY;
		if( !evt.stopPropagation ) {
			evt.stopPropagation = function() { this.cancelBubble = true; };
		}
		if( !evt.preventDefault ) {
			evt.preventDefault = function() { this.returnValue = false; };
		}
		return evt;
	},

	cancelEvents : function (evt) {
		evt = Toolkit.Events._patchEvent(evt);

		
		if( evt.stopPropagation ) evt.stopPropagation();
		if( evt.cancelBubble == false ) evt.cancelBubble = true;
	}
}


if( !Function.prototype.apply ) {
	Function.prototype.apply = function( thisObj, params ) {
		if( thisObj == null || thisObj == undefined ) thisObj = window;
		if( !params ) params = [];
		var args = [];
		for( var i = 0; i < params.length; i++ ) {
			args[ args.length ] = "params[" + i + "]";
		}
		thisObj.__method__ = this;
		var returnValue = eval( "thisObj.__method__(" + args.join( "," ) + ");" );
		thisObj.__method__ = null;
		return returnValue;
	};
} 

var LWin = {

	resized:	-1,
	tracerAnim:	null,
	timer:		null,
	aniLen:     450,
	acc:		0.989,
	hideTimer:  null,
	minYPos:	35,
	showShadow:	1,
	showAni:	1,
	setup:		function() {
					if(!document.getElementsByTagName || !document.createElement || !document.appendChild) return false;
					if (this.showAni == -1) this.aniLen = 0;
					this.gRef = "LWin";
					this.LWinLoader = document.getElementById("LWDiv");
					if(document.body.filters && this.showShadow == 1){
						this.shadowDiv = document.createElement("div");
						this.shadowDiv.setAttribute("id", "shadowIE");
						this.LWinLoader.appendChild(this.shadowDiv);
						this.shadow = document.getElementById("shadowIE").style;
					}else if (this.showShadow == 1){
						this.shadowDiv = document.createElement("img");
						this.shadowDiv.setAttribute("id", "shadow");
						this.shadowDiv.setAttribute("src", "images/tausta.png");
						this.LWinLoader.appendChild(this.shadowDiv);
						this.shadow = document.getElementById("shadow").style;
					}
					this.LoaderSetSize(70,150);
					this.LoaderMoveTo(-400, -400);
					this.LWcontainer = document.getElementById("LWDivContainer");
					this.loadtxt = document.getElementById("Loadtxt").style;
					this.loadtxt.visibility="hidden";
					//alert(this.LWcontainer.style.width);
					return true;
	},
	load:		function(url){
					//this.LWcontainer.innerHTML=" ";
					this.ContainerMoveTo(-1400,-1400);
					if (this.showShadow == 1){LWin.shadow.visibility ="hidden";}
					this.resized = 0;
					this.LWcontainer.innerHTML="<IFRAME id=\"buffer\" style=\"height:100px;width:100px;z-index:100;\" name=\"buffer\" src="+ url +" frameborder=0 scrolling=\"no\"></IFRAME>";
					this.ContainerSetSize(110,110);
					this.LoaderSetSize(100,35);
					this.center();
					this.loadtxt.visibility="visible";
					if (LWin.showShadow == 1){
						//alert("varjo");
						LWin.shadow.visibility ="visible";
						var sHeight = parseInt(LWin.LWinLoader.style.height) + Math.round(parseInt(LWin.LWinLoader.style.height)/100*12);
						LWin.shadow.height = sHeight;
					}
	},
	cancel:		function(){
					if(this.hideTimer){window.clearTimeout(this.hideTimer);}
					//this.LWcontainer.innerHTML="";
					this.ContainerMoveTo(-1400,-1400);
					this.resized = -1;
					this.LoaderMoveTo(-1000,-1000)
	},
	displayExternal:function(w,h){
					this.loadtxt.visibility="hidden";
					if (LWin.showShadow == 1){
						LWin.shadow.visibility ="hidden";
						//alert("varjo piilotetaan ennen suurennusta");
					}
					this.resize(w,h);
				
	},
	ready:function(){
					this.ContainerSetSize(parseInt(LWin.LWinLoader.style.width),parseInt(LWin.LWinLoader.style.height));
					this.ContainerMoveTo(parseInt(LWin.LWinLoader.style.left),parseInt(LWin.LWinLoader.style.top));
	},
	resize:	function(endW,endH) {
				if(this.LWrAnim != null) this.LWAnim.stop();
				var startW = parseInt(this.LWinLoader.style.width);
				var startH = parseInt(this.LWinLoader.style.height);
				var line = new Toolkit.Drawing.Curves.Line([startW,startH],[endW,endH]);
				this.LWAnim = new Toolkit.Drawing.Animation(line,this.aniLen,this.acc);
				Toolkit.Events.addListener(this.LWAnim,"onanimate",this.drawAnimation);
				Toolkit.Events.addListener(this.LWAnim,"onend",this.stopAnimation);
				this.LWAnim.start();
	},
	drawAnimation:function(animobj) {
				var w =	 Math.round(animobj.coordinates[0]);
				var h =  Math.round(animobj.coordinates[1]);
				LWin.LoaderSetSize(w,h);
				LWin.center();
	},
	ContainerSetSize:function(w,h){
			if(!isNaN(w)) document.getElementById("buffer").style.width = w + "px";
			if(!isNaN(h)) document.getElementById("buffer").style.height = h + "px";
	},
	ContainerSetSize:function(w,h){
			if(!isNaN(w)) this.LWcontainer.style.width = w + "px";
			if(!isNaN(h)) this.LWcontainer.style.height = h + "px";
			if(!isNaN(h)) document.getElementById("buffer").style.width = w + "px";
			if(!isNaN(h)) document.getElementById("buffer").style.height = h + "px";
	},
	LoaderSetSize:function(w,h){
			if(!isNaN(w)) this.LWinLoader.style.width = w + "px";
			if(!isNaN(h)) this.LWinLoader.style.height = h + "px";
	},
	center:function(){
			var windowHeight = this.getWinHeight(); 
			var curYPos = this.getCurYPos();
			var windowWidth  = this.getWinWidth();			
			var NewX = Math.round((windowWidth-parseInt(LWin.LWinLoader.style.width))/2);
			var NewY = Math.round((windowHeight-parseInt(LWin.LWinLoader.style.height))/2 + curYPos);
			if (NewY < this.minYPos) NewY = this.minYPos;
			this.LoaderMoveTo(NewX, NewY);
	},
	LoaderMoveTo:function(x,y){
			this.LWinLoader.style.left = x + "px";
			this.LWinLoader.style.top = y + "px";
	},
	ContainerMoveTo:function(x,y){
			this.LWcontainer.style.left = x + "px";
			this.LWcontainer.style.top = y + "px";
	},
	getCurYPos:function(){
			var scrOfY = 0;
			if( typeof( window.pageYOffset ) == 'number' ) {
				scrOfY = window.pageYOffset;
			} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
				scrOfY = document.body.scrollTop;
			} else if( document.documentElement &&
				  ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
				scrOfY = document.documentElement.scrollTop;
			}
			return scrOfY;
	},
	getWinHeight:function(){
			var myHeight = 0;
			  if( typeof( window.innerHeight ) == 'number' ) {
				myHeight = window.innerHeight;
			  } else if( document.documentElement &&
				  ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
				myHeight = document.documentElement.clientHeight;
			  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
				myHeight = document.body.clientHeight;
			  }
			return myHeight;
	},
	getWinWidth:function(){
			var myWidth = 0;
			  if( typeof( window.innerWidth ) == 'number' ) {
				myWidth = window.innerWidth;
				} else if( document.documentElement &&
				  ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
				myWidth = document.documentElement.clientWidth;
				
			  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
				myWidth = document.body.clientWidth;
				}
		return myWidth;
		
	},
	stopAnimation:	function(){
				this.LWAnim = null;
				LWin.resized = 1;
				
				if (LWin.showShadow == 1){
					LWin.shadow.visibility ="visible";
					var sHeight = parseInt(LWin.LWinLoader.style.height) + Math.round(parseInt(LWin.LWinLoader.style.height)/100*8);
					LWin.shadow.height = sHeight;
				}
				this.LWin.ready();
			}
}
  
