/********************************/
//	Dynamic Dependant Project
//	FX Stuff
//	Requires the foundation code
/********************************/

var ddp;
if(!ddp) ddp = {};
ddp.fx = {};

/********************************/
//	DDP -> FX
/********************************/
(function() {

//current animation operations
var currentOps = {};

function getFxStatus(Id){
  return currentOps[Id] || null;
}

function getPosStatus(el){
  return el.ddpFxPosOpId ? getFxStatus(el.ddpFxPosOpId) : null;
}


function doPosChangeMem(elem,startPos,endPos,steps,intervals,powr, complete, aborted, allowOverrideStartPos)
{
  var thisOp;
  var ppx = document.layers ? "" : "px";
  var opId = elem.ddpFxPosOpId;
  if(allowOverrideStartPos == undefined)
    allowOverrideStartPos = true;
  
  if(allowOverrideStartPos){
    if(opId && currentOps[opId] && currentOps[opId].currentPos){
      startPos = currentOps[opId].currentPos;
    }
  }
  
  if(!startPos){
    if(elem.style.top.length && elem.style.left.length)
      //plus signs are "unary operators" (implicitly converts the string to a number)
      startPos = [+elem.style.left.replace('px', ''), +elem.style.top.replace('px', '')];
    else{
      var l = ddp.f.getEffectiveStyle(elem, 'left').replace('px', '');
      var t = ddp.f.getEffectiveStyle(elem, 'top').replace('px', '');
      if(l != '' && t != '')
        //plus signs are "unary operators" (implicitly converts the string to a number)
        startPos = [+l, +t];
      else
        throw 'ddp.fx.doPosChangeMem - valid startPos was not supplied and element has no top and left style set: <' + elem.tagName + '> :' + elem.id;
    }
  }
  
  //console.log(startPos);
  
  if(opId){
    //the old Operation tracking object
    thisOp = currentOps[opId];
    window.clearInterval(thisOp.posChangeMemInt);
    if(thisOp.aborted)
      thisOp.aborted(thisOp.currentPos, thisOp.actStep);
    delete currentOps[opId];
  }
  
  elem.ddpFxPosOpId = opId = ddp.f.GUID();
  currentOps[opId] = thisOp = {
    "type": "position",
    "complete": complete,
    "aborted": aborted,
    "actStep": 0
  };
  
  if(startPos[0] == endPos[0] && startPos[1] == endPos[1]){
    if(thisOp.complete)
      thisOp.complete(thisOp.currentPos);
    elem.ddpFxPosOpId = undefined;
    currentOps[opId] = undefined;
    try{
      delete elem.ddpFxPosOpId;
      delete currentOps[opId];
    }
    catch(e){}
    thisOp = null;
  }
  else{
  	thisOp.posChangeMemInt = window.setInterval(
  		function() {
  			thisOp.currentPos = [
  			  easeInOut(startPos[0],endPos[0],steps,thisOp.actStep,powr),
  			  easeInOut(startPos[1],endPos[1],steps,thisOp.actStep,powr)
        ];
  
  			elem.style.left = thisOp.currentPos[0]+ppx;
  			elem.style.top = thisOp.currentPos[1]+ppx;
  
  			thisOp.actStep++;
  			if(thisOp.actStep > steps){
          if(thisOp.complete)
            thisOp.complete(thisOp.currentPos);
          window.clearInterval(thisOp.posChangeMemInt);
          elem.ddpFxPosOpId = undefined;
          currentOps[opId] = undefined;
          try{
            delete elem.ddpFxPosOpId;
            delete currentOps[opId];
          }
          catch(e){}
          thisOp = null;
        }
  		},
  		intervals
    );
    
    return opId;
  }
  return null;
}


function doSizeChangeMem(elem, startSize, endSize, steps, intervals, powr, complete, aborted, allowOverrideStartSize)
{
  var thisOp;
  var ppx = document.layers ? "" : "px";
  var opId = elem.ddpFxSizeOpId;
  if(allowOverrideStartSize == undefined)
    allowOverrideStartSize = true;
  
  if(allowOverrideStartSize){
    if(opId && currentOps[opId] && currentOps[opId].currentSize){
      startSize = currentOps[opId].currentSize;
    }
  }
  
  if(!startSize){
    if(elem.style.width.length && elem.style.height.length)
      //plus signs are "unary operators" (implicitly converts the string to a number)
      startSize = [+elem.style.width.replace('px', ''), +elem.style.height.replace('px', '')];
    else{
      var w = ddp.f.getEffectiveStyle(elem, 'width').replace('px', '');
      var h = ddp.f.getEffectiveStyle(elem, 'height').replace('px', '');
      if(w != '' && h != '')
        //plus signs are "unary operators" (implicitly converts the string to a number)
        startSize = [+w, +h];
      else
        throw 'ddp.fx.doSizeChangeMem - valid startSize was not supplied and element has no top and left style set: <' + elem.tagName + '> :' + elem.id;
    }
  }
  
  //console.log(startSize);
  
  if(opId){
    //the old Operation tracking object
    thisOp = currentOps[opId];
    window.clearInterval(thisOp.sizeChangeMemInt);
    if(thisOp.aborted)
      thisOp.aborted(thisOp.currentSize, thisOp.actStep);
    delete currentOps[opId];
  }
  
  elem.ddpFxSizeOpId = opId = ddp.f.GUID();
  currentOps[opId] = thisOp = {
    "type": "size",
    "complete": complete,
    "aborted": aborted,
    "actStep": 0
  };
  
  if(startSize[0] == endSize[0] && startSize[1] == endSize[1]){
    if(thisOp.complete)
      thisOp.complete(thisOp.currentSize);
    elem.ddpFxSizeOpId = undefined;
    currentOps[opId] = undefined;
    try{
      delete elem.ddpFxSizeOpId;
      delete currentOps[opId];
    }
    catch(e){}
    thisOp = null;
  }
  else{
  	thisOp.sizeChangeMemInt = window.setInterval(
  		function() {
  			thisOp.currentSize = [
  			  easeInOut(startSize[0],endSize[0],steps,thisOp.actStep,powr),
  			  easeInOut(startSize[1],endSize[1],steps,thisOp.actStep,powr)
        ];
  
  			elem.style.width = thisOp.currentSize[0]+ppx;
  			elem.style.height = thisOp.currentSize[1]+ppx;
  
  			thisOp.actStep++;
  			if(thisOp.actStep > steps){
          if(thisOp.complete)
            thisOp.complete(thisOp.currentSize);
          window.clearInterval(thisOp.sizeChangeMemInt);
          elem.ddpFxSizeOpId = undefined;
          currentOps[opId] = undefined;
          try{
            delete elem.ddpFxSizeOpId;
            delete currentOps[opId];
          }
          catch(e){}
          thisOp = null;
        }
  		},
  		intervals
    );
    
    return opId;
  }
  return null;
}








/***************************************************************/

function doOpacityChangeMem(elem, startOpacity, endOpacity, steps, intervals, powr, complete, aborted, allowOverrideStartOpacity) 
{
  var opId = elem.ddpFxOpaOpId;
  var thisOp;
  
  if(allowOverrideStartOpacity == undefined)
    allowOverrideStartOpacity = true;
  
  if(allowOverrideStartOpacity){
    if(opId && currentOps[opId] && currentOps[opId].currentOpacity){
      startOpacity = currentOps[opId].currentOpacity;
    }
  }
  
  if(opId){
    thisOp = currentOps[opId];
    if(thisOp.aborted)
      thisOp.aborted(thisOp.currentOpacity);
    window.clearInterval(thisOp.opacityMemInt);
    elem.ddpFxOpaOpId = undefined;
    currentOps[opId] = undefined;
    try{
      delete currentOps[opId];
      delete elem.ddpFxOpaOpId;
    }
    catch(e){}
    opId = null;
  }
  
  if(startOpacity === null || startOpacity == undefined){
    startOpacity = 100;
  }


  elem.ddpFxOpaOpId = opId = ddp.f.GUID();
  currentOps[opId] = thisOp = {
    "type": "opacity",
    "complete": complete,
    "aborted": aborted,
    "actStep": 0
  };
  
	thisOp.opacityMemInt = window.setInterval(
		function() {
			elem._ddpCurrentOpacity = thisOp.currentOpacity = easeInOut(startOpacity,endOpacity,steps,thisOp.actStep,powr);
			//elem.currentOpacity = _ddpCurrentOpacity;
			if(typeof elem.style.opacity == "string"){
				elem.style.opacity = thisOp.currentOpacity/100;
			}
			else{
				elem.style.filter="alpha(opacity="+thisOp.currentOpacity+")";
			}
			
			thisOp.actStep++;
			if (thisOp.actStep > steps){
        if(thisOp.complete)
          thisOp.complete();
        window.clearInterval(thisOp.opacityMemInt);
        elem.ddpFxOpaOpId = undefined;
        currentOps[opId] = undefined;
        try{
          delete currentOps[opId];
          delete elem.ddpFxOpaOpId;
        }
        catch(e){}
        opId = null;
      }
		},
		intervals
  );
  
  return opId;
}





function doBGFadeMem(elem,startRGB,endRGB,steps,intervals,powr) 
{
	if (elem.bgFadeMemInt) window.clearInterval(elem.bgFadeMemInt);
	var actStep = 0;
	elem.bgFadeMemInt = window.setInterval(
		function() {
			elem.currentbgRGB = [
				easeInOut(startRGB[0],endRGB[0],steps,actStep,powr),
				easeInOut(startRGB[1],endRGB[1],steps,actStep,powr),
				easeInOut(startRGB[2],endRGB[2],steps,actStep,powr)
				];
			elem.style.backgroundColor = "rgb("+
				elem.currentbgRGB[0]+","+
				elem.currentbgRGB[1]+","+
				elem.currentbgRGB[2]+")";
			actStep++;
			if (actStep > steps) window.clearInterval(elem.bgFadeMemInt);
		}
		,intervals)
}


/***************************************************************/

function easeInOut(minValue,maxValue,totalSteps,actualStep,powr) {
//Generic Animation Step Value Generator By www.hesido.com
	var delta = maxValue - minValue;
	var stepp = minValue+(Math.pow(((1 / totalSteps)*actualStep),powr)*delta);
	return Math.ceil(stepp)
}

/***************************************************************/

function slideChange(obj,startpos,endpos,steps,interval) 
{
  /*
	if (!obj.currentPos) obj.currentPos = startpos; //if no mem is set, set it first;
	doPosChangeMem(obj,obj.currentPos,endpos,steps,interval,0.5);
  */
  doPosChangeMem(obj,startpos,endpos,steps,interval,0.5);
}

function slideRestore(obj,pos,steps,interval) 
{
  /*
	if (!obj.currentPos) return;	//avoid error if mouseout an element occurs before the mosueover
										//(e.g. the pointer already in the object when onload)
	doPosChangeMem(obj,obj.currentPos,pos,steps,interval,0.5);
  */
  doPosChangeMem(obj,null,pos,steps,interval,0.5);
}

/***************************************************************/

function fadeChange(obj,startOpacity,endOpacity,steps,interval)
{
	if (!obj.currentOpacity) obj.currentOpacity = startOpacity;
		doOpacityChangeMem(obj,startOpacity,endOpacity,steps,interval,0.5);
}

function fadeRestore(obj,endOpacity,steps,interval)
{	
	if (!obj.currentOpacity) return;
		doOpacityChangeMem(obj,obj.currentOpacity,endOpacity,steps,interval,0.5);	
}

/***************************************************************/

function slideFadeChange(obj,startpos,endpos) 
{
	//if (!obj.currentPos) obj.currentPos = startpos; 
	//doPosChangeMem(obj,obj.currentPos,endpos,20,10,0.5);
  doPosChangeMem(obj,startpos,endpos,20,10,0.5);
	if (!obj.currentOpacity) obj.currentOpacity = 0;
		doOpacityChangeMem(obj,obj.currentOpacity,100,50,10,0.5);	
}

function slideFadeRestore(obj,pos) 
{
  /*
	if (!obj.currentPos) return;
	doPosChangeMem(obj,obj.currentPos,pos,20,10,0.5);	
	if (!obj.currentOpacity) return;
	doOpacityChangeMem(obj,obj.currentOpacity,0,50,10,0.5);
  */
	doPosChangeMem(obj,null,pos,20,10,0.5);	
	if (!obj.currentOpacity) return;
	doOpacityChangeMem(obj,obj.currentOpacity,0,50,10,0.5);
}

/****************************************************************/



/**************************************************/
//Export the public functions to a public namespace
/**************************************************/

//Exports go here
var ddpns = ddp.fx;
ddpns.doPosChangeMem = doPosChangeMem;
ddpns.doSizeChangeMem = doSizeChangeMem;
ddpns.doBGFadeMem = doBGFadeMem;
ddpns.slideChange = slideChange;
ddpns.slideRestore = slideRestore;
ddpns.doOpacityChangeMem = doOpacityChangeMem;
ddpns.fadeChange = fadeChange;
ddpns.fadeRestore = fadeRestore;
ddpns.slideFadeChange = slideFadeChange;
ddpns.slideFadeRestore = slideFadeRestore;
ddpns.easeInOut = easeInOut;


})();
