/* Generic Animation Framework For Extraordinary Results (GAFFER) - Basic Animations (c) 2007 */
var fod=true;

function quadraticAni(v) {
   return v*v;
}

function quadraticOutAni(v) {
   return 1-(1-v)*(1-v);
}

function cubicAni(v) {
   return v*v*v;
}

function cubicOutAni(v) {
   return 1-(1-v)*(1-v)*(1-v);
}

function easeInOutAni(v) {
	if(v<.5) {
		return .5*Math.pow(2*v,3);
	} else {
		return 1-.5*Math.pow(2-2*v,3);
	}
}

/*function bounceOutAni(v) {
   return v * v * (5-4*v);
}*/


function FadeAni(object, stps, from, to, fct) {
   this.steps = stps;
   this.assocObject=object;
   this.onFinish=null;
   this.currStep = 0;
   this.stepFunction = fct;
   var me = this;
   var fadeFrom=from; var fadeTo=to;
   
   function setOpa(value) {
      if(!isIE) {
         me.assocObject.style.opacity=value;
      } else {
         me.assocObject.style.filter="alpha(opacity = " + Math.round((value)*100) + ");";
      }
   }   
   
   this.prepare = function() {
      gaffer_genericPrepare(me);
      return me;
   }
   
   this.start = function() {
      setOpa(fadeFrom);
      gaffer_genericStart(me);
      return me;
   }

   this.nextStep = function() {
      me.currStep++;
      if(me.currStep==me.steps) { me.finish(); return; }

      if(this.stepFunction) {
         setOpa(fadeFrom +(fadeTo-fadeFrom) * this.stepFunction(me.currStep/me.steps));
      } else {
         setOpa(fadeFrom +(fadeTo-fadeFrom) * me.currStep/me.steps);
      }
      return me;
   }

   this.cancel = function() {
      me.finish();
      return me;
   }

   this.finish = function() {
      setOpa(fadeTo);
      gaffer_genericFinish(me);
      return me;
   }

}

function PropAni(object, stps, prop, from, to, fct) {
   this.steps = stps;
   this.assocObject=object;
   this.onFinish=null;
   this.currStep = 0;
   this.property=prop;
   this.stepFunction = fct;
   var me = this;
   var aniFrom=from; var aniTo=to;
   
   
   this.prepare = function() {
      gaffer_genericPrepare(me);
      return me;
   }
   
   this.start = function() {
      setVal(aniFrom);
      gaffer_genericStart(me);
      return me;
   }

   function setVal(val) {
      this.style[me.property] = val + "px";
   }

   this.nextStep = function() {
      me.currStep++;
      if(me.currStep==me.steps) { me.finish(); return; }

      if(this.stepFunction) {
         setVal(aniFrom +(aniTo-aniFrom) * this.stepFunction(me.currStep/me.steps));
      } else {
         setVal (aniFrom +(aniTo-aniFrom) * me.currStep/me.steps);
      }
            
      return me;
   }

   this.cancel = function() {
      me.finish();
      return me;
   }

   this.finish = function() {
      setVal(aniTo);
      gaffer_genericFinish(me);
      return me;
   }

}

function RollDownAni(object, stps, fct) {
   this.steps = stps;
   this.assocObject=object;
   this.onFinish=null;
   this.currStep = 0;
   this.stepFunction = fct;
   var me = this;
   
   this.prepare = function() {
      gaffer_genericPrepare(me);
      return me;
   }
   
   this.start = function() {
      var aO=me.assocObject;
      me.oldH=aO.style.height;
      me.oldOvf=aO.style.overflow;
      gaffer_prepAniCont(aO);
         me.destH=viewHeight(aO);
         aO.style.overflow="hidden";
         if(isIE) aO.style.height="1px"; else aO.style.height="0px";
      gaffer_unprepAniCont(aO);
      gaffer_genericStart(me);
      return me;
   }

   this.nextStep = function() {
      me.currStep++;
      if(me.currStep==me.steps) { me.finish(); return; }

      var hei;
      if(this.stepFunction) {
         hei = this.stepFunction(me.currStep/me.steps)*me.destH;
      } else {
         hei=(me.currStep/me.steps)*me.destH;
      }
      if(isIE && hei<1) hei = 1;
      me.assocObject.style.height=hei + "px";
      return me;
   }

   this.cancel = function() {
      me.finish();
      return me;
   }

   this.finish = function() {
      me.assocObject.style.height=me.oldH;
      me.assocObject.style.overflow=me.oldOvf;
      gaffer_genericFinish(me);
      return me;
   }

}

function RollUpAni(object, stps, fct) {
   this.steps = stps;
   this.assocObject=object;
   this.onFinish=null;
   this.currStep = 0;
   this.stepFunction = fct;
   var me = this;
   
   this.prepare = function() {
      gaffer_genericPrepare(me);
      return me;
   }
   
   this.start = function() {
      me.oldHVal=me.assocObject.style.height;
      me.oldH=viewHeight(me.assocObject);
      me.oldOvf=me.assocObject.style.overflow;
      me.assocObject.style.overflow="hidden";
      gaffer_genericStart(me);
      return me;
   }

   this.nextStep = function() {
      me.currStep++;
      if(me.currStep==me.steps) { me.finish(); return; }

      if(this.stepFunction) {
         me.assocObject.style.height=this.stepFunction(1-me.currStep/me.steps)*me.oldH + "px";
      } else {
         me.assocObject.style.height=(1-me.currStep/me.steps)*me.oldH + "px";
      }
      return me;
   }

   this.cancel = function() {
      me.finish();
      return me;
   }

   this.finish = function() {
      me.assocObject.style.display="none";
      me.assocObject.style.height=me.oldHVal;
      me.assocObject.style.overflow=me.oldOvf;
      gaffer_genericFinish(me);
      return me;
   }

}


function CombinedAni(obj, anis) {
   this.animations=anis;
   //this.steps = stps;
   this.assocObject=obj;
   this.onFinish=null;
   var me = this;
   var running=0;

   for(var i = 0; i<me.animations.length; i++) {
      me.animations[i].inCombination=true;
      me.animations[i].onFinish = function() { running-- }
      running++;
   } 
   
   this.prepare = function() {
      for(var i = 0; i<me.animations.length; i++) {
         me.animations[i].prepare();
      } 
      gaffer_genericPrepare(me);
      return me;
   }
   
   this.start = function() {
      for(var i = 0; i<me.animations.length; i++) {
         me.animations[i].start();
      } 
      gaffer_genericStart(me);
      return me;
   }

   this.nextStep = function() {
      for(var i = 0; i<me.animations.length; i++) {
         if(!me.animations[i].finished) {
            me.animations[i].nextStep();
         }
      } 
      if(running==0) me.finish();
      return me;
   }

   this.cancel = function() {
      for(var i = 0; i<me.animations.length; i++) {
         if(!me.animations[i].finished) {
            me.animations[i].cancel();
         }
      }
      me.finish(); 
      return me;
   }

   this.finish = function() {
      gaffer_genericFinish(me);
      return me;
  }

}

function aniRollDown(obj, steps, onFinish, fct) {
  var ani = new RollDownAni(obj, steps, fct);
  ani.onFinish = onFinish;
  ani.prepare().start();
}

function aniRollUp(obj, steps, onFinish, fct) {
  var ani = new RollUpAni(obj, steps, fct);
  ani.onFinish = onFinish;
  ani.prepare().start();
}

function aniFade(obj, steps, from, to, onFinish, fct) {
  var ani = new FadeAni(obj, steps, from, to, fct);
  ani.onFinish = onFinish;
  ani.prepare().start();
}

function aniFadeIn(obj, steps, onFinish, fct) {
  var ani = new FadeAni(obj, steps, 0, 1, fct);
  ani.onFinish = onFinish;
  ani.prepare().start();
  obj.style.display="block";
}

function aniFadeOut(obj, steps, onFinish, fct) {
  var ani = new FadeAni(obj, steps, 1, 0, fct);
  var ofi=onFinish;
  ani.onFinish = function() {
     obj.style.display="none";
     if(ofi!=null) ofi();
  }
  ani.prepare().start();
}

function aniProp(obj, steps, prop, from, to, onFinish, fct) {
  var ani = new PropAni(obj, steps, prop, from, to, fct);
  ani.onFinish = onFinish;
  ani.prepare().start();
}


function aniFadeDown(obj, steps, onFinish, fct) {
  var ani = new CombinedAni(obj, new Array(new FadeAni(obj, steps, 0, 1, fct), new RollDownAni(obj, steps, fct)));
  ani.onFinish = onFinish;
  ani.prepare().start();
}

function aniFadeUp(obj, steps, onFinish, fct) {
  var ani = new CombinedAni(obj, new Array(new FadeAni(obj, steps, 1, 0, fct), new RollUpAni(obj, steps, fct)));
  ani.onFinish = onFinish;
  ani.prepare().start();
}

function aniMoveSize(obj, steps, fromLeft,toLeft,fromTop,toTop,fromWidth,toWidth,fromHeight,toHeight, onFinish, fct) {
  var ani = new CombinedAni(obj, new Array(  new PropAni(obj, steps, "left", fromLeft, toLeft, fct),
                                             new PropAni(obj, steps, "top", fromTop, toTop, fct),
                                             new PropAni(obj, steps, "width", fromWidth, toWidth, fct),
                                             new PropAni(obj, steps, "height", fromHeight, toHeight, fct)
  ));
  ani.onFinish = onFinish;
  ani.prepare().start();
}

