//
// jsanim.js
//
// javascript animation tools for div
//
// © nui - loic berthelot - 2009
// contact@libnui.net
//



////////////////////////////////////////////
//
// EXTERN FUNCTIONS
// ________________
//
//
// ja_resizeTo (id, wdest, hdest, step, cbk);
// ja_moveTo (id, x1, y1, x2, y2, step, cbk);
// ja_sequence (id, path, nb, timer, step, cbk)
//
/////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  SEQUENCE OBJECT CLASS AND STORE TABS
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////


var JA_Sequence_Tab  = new Array ();     // index --> object

var JA_Sequence_IndexTab = new Array (); // id    --> index


function JA_Sequence_Obj (id, path, nb, timer, step, cbk)
{
  this.cbk = cbk;	
	
  this.id  = id;
  this.img = jsGetImage (id);
  
  this.path = path;
  this.nb = nb;
  this.timer = timer;
      
  this.step = step;
  
  this.num = 0;
  this.curTimer = 0;
}





///////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  RESIZE OBJECT CLASS AND STORE TABS
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////


var JA_Resize_Tab  = new Array ();     // index --> object

var JA_Resize_IndexTab = new Array (); // id    --> index


function JA_Resize_Obj (id, wdest, hdest, step, cbk)
{
  this.cbk = cbk;	
	
  this.id  = id;
  this.div = jsGetObject (id);
  
  this.wsrc = parseInt(this.div.style.width);
  this.hsrc = parseInt(this.div.style.height);
    
  this.wdest = wdest;
  this.hdest = hdest;
  
  if (this.wsrc > wdest)
  this.wstep = -step; else this.wstep = step;
  
  if (this.hsrc > hdest)
  this.hstep = -step; else this.hstep = step;
  
  
  this.wcur = this.wsrc;
  this.hcur = this.hsrc;
  
  this.wdone = 0;
  this.hdone = 0;
}






//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  MOVE OBJECT CLASS AND STORE TABS
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

var JA_Move_Tab  = new Array ();     // index --> object

var JA_Move_IndexTab = new Array (); // id    --> index

function JA_Move_Obj (id, x1, y1, x2, y2, step, breakvalue, cbk)
{
 
  this.cbk = cbk;
  
  this.id    = id;
  this.div   = jsGetObject (id);
  this.x1    = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2;
  
  this.vertical = (x1 == x2);
  
  // norm of (x1,y1) -- (x2,y2) vector
  this.norm  = Math.sqrt ((Math.pow ((x2-x1), 2) + Math.pow ((y2-y1), 2)), 2);
  
  // angle
  this.alpha = Math.asin ((y2 - y1) / this.norm);

  // line equation  
  this.a     = (y2 - y1) / (x2 - x1);
  this.b     = y1 - (this.a * x1);
  
  this.step  = step;
  this.breakvalue =  breakvalue;
  if (x2 < x1) this.step = (-step);
  if ((this.vertical) && (y2 < y1)) this.step = (-step);
  
  this.r     = this.step;
  
  /////////////////////////////////////////
  
  if (this.vertical)
  this.computeX = function ()
                  { return this.x1; }
  else
  this.computeX = function ()
                  { return ((this.r * Math.cos(this.alpha)) + this.x1); }

  
  if (this.vertical)
  this.computeY = function (x)
                  { return (this.y1 + this.r); }
  else   
  this.computeY = function (x)
                  { return ((this.a * x) + this.b); }
                  
  //////////////////////////////////////////
  
  this.nextStep = function () {this.r += this.step; this.step -= this.breakvalue;};
  
  this.isOver = function () {return (Math.abs(this.r) >= this.norm);}
}







//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  FADE OBJECT CLASS AND STORE TABS
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////


var JA_Fade_Tab      = new Array ();
var JA_Fade_IndexTab = new Array ();


//JA_Fade_Tab.push (null); // first index will be '1'

var JA_FADEIN  = 0;
var JA_FADEOUT = 1


function JA_Fade_Obj (id, type, opacity, step, cbk)
{
  this.id       = id;
  this.obj      = jsGetObject (id);
  
  if (this.obj == null) this.obj = jsGetImage (id);
  
  this.opacity  = opacity;
  
  jsSetOpacity (this.obj, this.opacity);
  
  if (type == JA_FADEIN)
  this.step       = step;
  // JA_FADEOUT
  else this.step  = -step;
  
  this.cbk      = cbk;
  
  
  if (type == JA_FADEIN)
  this.isOver = function ()
                 { var res =  ((this.opacity+this.step) >= 1.0); 
                   if (res) {this.opacity = 1.0; jsSetOpacity(this.obj, 1.0); return 1;}
                   return 0;
                 }
  // JA_FADEOUT
  else
  this.isOver = function ()
                 { var res = ((this.opacity+this.step) <= 0.0); 
                   if (res) {this.opacity = 0.0; jsSetOpacity (this.obj, 0.0); return 1;}
                   return 0;
                 }
}











//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  SEQUENCE  TOOL
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////





//
// Sequence 
//
// animation step controlled by ja_loop
//
function ja_sequenceAnim (dobj)
{
	
  if (dobj.curTimer == dobj.timer)
  {
  	dobj.curTimer = 0;
  	
  	if (dobj.num == dobj.nb)
  	{
  		dobj.num = 0;	
  		if (dobj.cbk) setTimeout (dobj.cbk, 10);
  	}
	else if (dobj.num == (-1))
	{
		dobj.num = dobj.nb - 1;  
		if (dobj.cbk) setTimeout (dobj.cbk, 10);
	}
	
	dobj.img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+dobj.path+dobj.num+".png')";	
	
	dobj.num += dobj.step;
  }
  
  dobj.curTimer++;
}

function ja_sequence_setDynamics (id, timer, step)
{
  // check if the object has already been registered
  var index = JA_Sequence_IndexTab[id];
  
  if (index != null)
  {
    //delete the Object
    dobj = JA_Sequence_Tab[index];	

    dobj.timer = timer;
    dobj.step = step;
    
    dobj.curTimer = 0;
  }
}


//
// Sequence 
//
// Stop the animation
//
function ja_sequenceStop (id)
{
  // check if the object has already been registered
  var index = JA_Sequence_IndexTab[id];
  
  if (index != null)
  {
    //delete the Object
    JA_Sequence_Tab[index] = null;	
    
    //unregister
    JA_Sequence_IndexTab[id] == null;
  }
}




//
// Sequence 
//
// Launch the animation
//
function ja_sequence (id, path, nb, timer, step, cbk)
{
	
  // check if the object has already been registered
  var index = JA_Sequence_IndexTab[id];
  
  // no, get  a new index and register
  if (index == null) 
  {
  	index = JA_Sequence_Tab.length;
  	JA_Sequence_IndexTab[id] = index;
  }
  
  // house cleaning
  JA_Sequence_Tab[index] = null;
    
  // create the object
  JA_Sequence_Tab[index] = new JA_Sequence_Obj (id, path, nb, timer, step, cbk);
  
  // launch anim
  ja_launch ();
}













//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  RESIZE  TOOL
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////





//
// Resize 
//
// animation step controlled by ja_loop
//
function ja_resizeAnim (dobj)
{
  if (dobj.wdone && dobj.hdone) 
  {
  	ja_resizeStop (dobj.id);
  	if (dobj.cbk) setTimeout (dobj.cbk, 10);
  	return;
  }
  
  
  if    ((!dobj.wdone && (dobj.wstep < 0) && ((dobj.wcur + dobj.wstep) < dobj.wdest))
     || (!dobj.wdone && (dobj.wstep > 0) && ((dobj.wcur + dobj.wstep) > dobj.wdest)))
  {
    dobj.wcur = dobj.wdest;
    dobj.wdone = 1;
  }
  else if (!dobj.wdone) dobj.wcur += dobj.wstep;
  
  
  
  if    ((!dobj.hdone && (dobj.hstep < 0) && ((dobj.hcur + dobj.hstep) < dobj.hdest))
     || (!dobj.hdone && (dobj.hstep > 0) && ((dobj.hcur + dobj.hstep) > dobj.hdest)))
  {
    dobj.hcur = dobj.hdest;
    dobj.hdone = 1;
  }
  else  if (!dobj.hdone) dobj.hcur += dobj.hstep;
  
  
  
  dobj.div.style.width = dobj.wcur;
  dobj.div.style.height = dobj.hcur;
}




//
// Resize 
//
// Stop the animation
//
function ja_resizeStop (id)
{
  // check if the object has already been registered
  var index = JA_Resize_IndexTab[id];
  
  if (index != null)
  {
    //delete the Object
    JA_Resize_Tab[index] = null;	
    
    //unregister
    JA_Resize_IndexTab[id] == null;
  }
}




//
// Resize 
//
// Launch the animation
//
function ja_resizeTo (id, wdest, hdest, step, cbk)
{
	
  // check if the object has already been registered
  var index = JA_Resize_IndexTab[id];
  
  // no, get  a new index and register
  if (index == null) 
  {
  	index = JA_Resize_Tab.length;
  	JA_Resize_IndexTab[id] = index;
  }
  
  // house cleaning
  JA_Resize_Tab[index] = null;
    
  // create the object
  JA_Resize_Tab[index] = new JA_Resize_Obj (id, wdest, hdest, step, cbk);
  
  // launch anim
  ja_launch ();
}




//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  MOVE  TOOL
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////



//
// Move 
//
// animation step controlled by ja_loop
//
function ja_moveAnim (process)
{
   if (process.isOver())
   {
   	ja_moveStop (process.id);
   	
   	process.div.style.left = process.x2;
   	process.div.style.top = process.y2;
   	
   	if (process.cbk) setTimeout (process.cbk, 10);
   	
   }
   else
   {
     x = process.computeX ();
     y = process.computeY (x);
     x = Math.floor (x);
     y = Math.floor (y);
     
     process.div.style.left = x;
     process.div.style.top = y;
     
     process.nextStep ();
   }
}




//
// Move 
//
// Stop the animation
//
function ja_moveStop (id)
{
  // check if the object has already been registered
  var index = JA_Move_IndexTab[id];
  
  if (index != null)
  {
    //delete the Object
    JA_Move_Tab[index] = null;	
    
    //unregister
    JA_Move_IndexTab[id] == null;
  }
}




//
// Move 
//
// Launch the animation
//
function ja_moveTo (id, x1, y1, x2, y2, step, breakvalue, cbk)
{
  // check if the object has already been registered
  var index = JA_Move_IndexTab[id];
  
  // no, get  a new index and register
  if (index == null) 
  {
  	index = JA_Move_Tab.length;
  	JA_Move_IndexTab[id] = index;
  }
  
  // house cleaning
  JA_Move_Tab[index] = null;
    
  // create the object
  JA_Move_Tab[index] = new JA_Move_Obj (id, x1, y1, x2, y2, step, breakvalue, cbk);
  
  // launch anim
  ja_launch ();
}












//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  FADE TOOL
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////



//
// Fade 
//
// animation step
//
function ja_fadeAnim (obj)
{
   if (obj.isOver())
   {
      ja_fadeStop (obj.id);
      
      jsSetOpacity (obj.obj, obj.opacity);
            
      if (obj.cbk) setTimeout (obj.cbk, 10);  
      
      return;	
   }
   
   obj.opacity += 0.5 * Math.sin(obj.step);
   jsSetOpacity (obj.obj, obj.opacity);
}



//
// Fade 
//
// Stop the animation
//
function ja_fadeStop (id)
{
  // check if the object has already been registered
  var index = JA_Fade_IndexTab[id];
  
  if (index != null)
  {
    JA_DONE = 1;
    
    //delete the Object
    JA_Fade_Tab[index] = null;	
    
    //unregister
    JA_Fade_IndexTab[id] == null;
  }
}



function ja_fadeTo (id, type, opacity, step, cbk)
{
	
  // check if the object has already been registered
  var index = JA_Fade_IndexTab[id];
  
  // no, get  a new index and register
  if (index == null) 
  {
  	index = JA_Fade_Tab.length;
  	JA_Fade_IndexTab[id] = index;
  }
  
  // house cleaning
  JA_Fade_Tab[index] = null;
    
  // create the object
  JA_Fade_Tab[index] = new JA_Fade_Obj (id, type, opacity, step, cbk);
  
  // launch anim
  ja_launch ();	
}






//
// Fade In 
//
// Launch the animation
//
function ja_fadeIn (id, step, cbk)
{
  ja_fadeTo (id, JA_FADEIN, 0.0, step, cbk);
}


//
// Fade Out 
//
// Launch the animation
//
function ja_fadeOut (id, step, cbk)
{
  ja_fadeTo (id, JA_FADEOUT, 1.0, step, cbk);
}





//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//
//
//  ANIMATION LOOP PROCESS
//
//
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

var JA_PROCESS = 0;
var JA_DONE    = 0;

function ja_launch ()
{
  if (JA_PROCESS == 0)
  {
    JA_PROCESS = 1;
    JA_DONE    = 0;
    ja_loop ();	
  }	  
}



function ja_loop ()
{
  var i;
  var obj;
  
  if (JA_DONE) 
  {
  	JA_PROCESS = 0;
  	return;
  }
  
  JA_DONE = 1;
  
  
  
  //
  // Sequence loop
  //
  for (i=0;  i < JA_Sequence_Tab.length; i++)
  {
    obj = JA_Sequence_Tab[i];
    if (obj != null)
    {
      JA_DONE = 0;
      ja_sequenceAnim (obj);
    }
  }
  
  
  //
  // Resize loop
  //
  for (i=0;  i < JA_Resize_Tab.length; i++)
  {
    obj = JA_Resize_Tab[i];
    if (obj != null)
    {
      JA_DONE = 0;
      ja_resizeAnim (obj);
    }
  }


  //
  // Move loop
  //
  for (i=0;  i < JA_Move_Tab.length; i++)
  {
    obj = JA_Move_Tab[i];
    if (obj != null)
    {
      JA_DONE = 0;
      ja_moveAnim (obj);
    }
  }



  //
  // Fade loop
  //
  for (i=0;  i < JA_Fade_Tab.length; i++)
  {
    obj = JA_Fade_Tab[i];
    if (obj != null)
    {
      JA_DONE = 0;
      ja_fadeAnim (obj);
    }
  }


  
  
  
  // loop
  setTimeout ("ja_loop()", 30);
}


