/**
 * Location:	/backbone/js/effects.js
 * Copyright:	Neist & Felskov, 2009+
 *
 *
 ***********
 *
 * Contains functions used to create moving effects / animations.
 */
/**
 * handleEffects
 *
 **********
 *
 * Provides run effects.
 */
function handleEffects(){
	// Udregn timestamp
	var time=new Date().getTime();
	// Gennemgå alle effekter
	var i=effects.length; var j=i;
	if(i>0)do{effects[j-i] && effects[j-i].loop(time);}while(--i);
}
effects=[];
setInterval(handleEffects,15);
/**
 * Effect
 *
 **********
 *
 * Handles animations and effects to run smoothly.
 *
 **********
 *
 * Parametre:
 * handler (function)					Function to handle the effect.
 * settings (array)						Indstillingerne for effekten:
 *										- duration (int): sekunder effekten skal vare
 *										- ease (boolean): skal der eases ind?
 */
function Effect(handler,settings){
	// Indlæs indstillinger
	this.handler=handler;							// Gem handler-funktionen
	this.duration=(settings.duration||1)*1000;		// Hvor længe skal den vare i millisekunder
	this.ease=settings.ease||false;					// Skal der eases?
	// Klargør variabler
	this.pos=0;										// Vi starter ved position 0
	this.last=new Date().getTime();
	this.first=this.last;
	// Tilføj til effect-handleren
	this.effectID=effects.length;
	effects[this.effectID]=this;
}
/**
 * loop
 *
 **********
 *
 * Loops while effect is active, and udregner status.
 *
 **********
 *
 * Parametre:
 * time (int)							Indeholder det nuværende timestamp.
 */
Effect.prototype.loop=function(time){
	// Udregn status for hvor langt animationen er nået uden easeing
	if(!this.ease){
		this.pos+=(time-this.last)/this.duration;
		var pos=this.pos;
	// Udregn status for hvor langt animationen er nået med easeing
	}else{
		var pos=1-Math.min(1,(time-this.first)/this.duration);
		this.pos=1-Math.pow(pos,3);
		var pos=this.pos;
	}
	// Gem det aktuelle timestamp
	this.last=time;
	// Kør handler-funktionen
	if(pos<1){
		this.handler(pos);
	// Afslut animationen
	}else{
		// Kør handleren med 100%
		this.handler(1);
		// Afbryd intervallet
		delete effects[this.effectID];
		// Ryd hukommelsen
		this.handler=null; this.duration=null; this.ease=null; this.totalFrames=null; this.currentFrame=null; this.start=null; this.effectID=null;
	}
}
/**
 * DragDrop
 *
 **********
 *
 * Håndterer drag'n'drop af elementer.
 *
 **********
 *
 * Parametre:
 * e (eventinfo)						Informationer om brugerens inputs.
 * handlers (array)						Angiv en liste over handler-funktioner.
 *										- drag: Køres ved mousemove.
 *										- drop: Køres ved mouseup.
 */
function DragDrop(e,handlers){
	// Indlæs brugerens inputs
	var e=e||window.event;
	// Klargør variabler
	this.handlers=handlers;
	// Håndter drag'n'drop
	if(document.attachEvent){
		document.attachEvent('onmousemove',DragDrop.prototype.drag);
		document.attachEvent('onmouseup',DragDrop.prototype.drop);
	}else{
		document.addEventListener('mousemove',DragDrop.prototype.drag,false);
		document.addEventListener('mouseup',DragDrop.prototype.drop,false);
	}
	// Register where the user clicked (FF)
	if(e.pageX || e.pageY){
		this.x=e.pageX;
		this.y=e.pageY;
	// ... (IE)
	}else{
		this.x=e.clientX+document.body.scrollLeft-document.body.clientLeft;
		this.y=e.clientY+document.body.scrollTop-document.body.clientTop;
	}
	// Gem informationerne i browserens hukommelse
	dragObject=this;
	// Tell the browser that it should handle drag'n'drop
	stopEvent(e);
}
/**
 * drag
 *
 **********
 *
 * Handles mouse move events, when drag'n'drop.
 *
 **********
 *
 * Parametre:
 * e (eventinfo)						Indeholder informationer om brugerens input.
 */
DragDrop.prototype.drag=function(e){
	// Registrer musens bevægelse
	if(e.pageX || e.pageY){
		var x=e.pageX-dragObject.x;
		var y=e.pageY-dragObject.y;
	// ... (IE)
	}else{
		var x=e.clientX+document.body.scrollLeft-document.body.clientLeft-dragObject.x;
		var y=e.clientY+document.body.scrollTop-document.body.clientTop-dragObject.y;
	}
	// Send informationerne om musens bevægelse tilbage til handleren
	dragObject.handlers.drag(dragObject.handlers.element,x,y);
	// Fortæl browseren, at den ikke skal håndtere drag'n'drop
	stopEvent(e);
}
/**
 * drop
 *
 **********
 *
 * Handles-mouseUp event when drag'n'drop.
 *
 **********
 *
 * Parametre:
 * e (eventinfo)						Indeholder informationer om brugerens input.
 */
DragDrop.prototype.drop=function(e){
	// Registrer musens bevægelse
	if(e.pageX || e.pageY){
		var x=e.pageX-dragObject.x;
		var y=e.pageY-dragObject.y;
	// ... (IE)
	}else{
		var x=e.clientX+document.body.scrollLeft-document.body.clientLeft-dragObject.x;
		var y=e.clientY+document.body.scrollTop-document.body.clientTop-dragObject.y;
	}
	// Send informationerne om musens bevægelse tilbage til handleren
	dragObject.handlers.drop(dragObject.handlers.element,x,y);
	// Afbryd drag'n'drop-håndtering
	if(document.detachEvent){
		document.detachEvent('onmousemove',DragDrop.prototype.drag);
		document.detachEvent('onmouseup',DragDrop.prototype.drop);
	}else{
		document.removeEventListener('mousemove',DragDrop.prototype.drag,false);
		document.removeEventListener('mouseup',DragDrop.prototype.drop,false);
	}
	// Ryd browserens hukommelse
	dragObject=null;
	// Fortæl browseren, at den ikke skal håndtere drag'n'drop
	stopEvent(e);
}
/**
 * stopEvent
 *
 **********
 *
 * Aborting execution of an event at the intersection of browsers.
 *
 **********
 *
 * Parametre:
 * e (eventinfo)						Informationer om brugerens input.
 */
function stopEvent(e){
	// Stop eventet på alle tænkelige måder
	if(e.preventDefault) e.preventDefault();
	if(e.stopPropagation) e.stopPropagation();
	if(e.stop) e.stop();
	if(document.all&&e.keyCode) try{e.keyCode=0;}catch(e){}
	e.cancelBubble=true;
	e.returnValue=false;
}

