var fadingStatus=new Object();
fadingStatus.nextId=0;

//--------------------------------------------------------------------------

// Helper function
function GetAnimationObjectName(item)
{
  var id=TrimStr(item.id);
  if(id!='')
  {
    // Create name from identifier
    id='obj_'+id;
  }
  else
    if(item.sourceIndex!=undefined)
    {
      // Create name from identifier
      id="obj_"+item.sourceIndex;
    }
    else
    {
      var re=/^objx_[0-9]+/;
      for(var n in fadingStatus)
      {
        if(n.search(re)>=0)
        {
          var temp=fadingStatus[n];
          if(temp.item==item)
          {
            // Return name of existing object
            return n;
          }
        }
      }
      // Generate new name
      id='objx_'+fadingStatus.nextId++;
    }
  return id;
}

// Helper function
function StopAnimationByInternalId(id, setDestXY, setDestO)
{     
  var obj=fadingStatus[id];
  if(obj)
  {
    if(obj.handle)
    {
      window.clearTimeout(obj.handle);
      obj.handle=undefined;
    }

    if(setDestXY)
    {
      SetPosX(obj.item, obj.destX);
      SetPosY(obj.item, obj.destY);
    }
    
    if(setDestO)
    {
      SetOpacity(obj.item, obj.destO);
    }

    fadingStatus[id]=undefined;
  }
}

// Helper function
function DoFadeAnimation(id)
{
  var obj=fadingStatus[id];

  obj.steps--;
  if(obj.steps>0)
  {
    obj.curX+=obj.incX;
    obj.curY+=obj.incY;
    obj.curO+=obj.incO;
  }
  else
  {
    // To avoid rounding errors
    obj.curX=obj.destX;
    obj.curY=obj.destY;
    obj.curO=obj.destO;
  }
  SetPosX(obj.item, obj.curX);
  SetPosY(obj.item, obj.curY);
  SetOpacity(obj.item, obj.curO);

  if(obj.steps>0)
    obj.handle=window.setTimeout('DoFadeAnimation(\''+id+'\');', obj.interval);
}

function DoFade(id)
{
  var obj=fadingStatus[id];

  obj.steps--;
  if(obj.steps>0)
  {
    obj.curO+=obj.incO;
  }
  else
  {
    // To avoid rounding errors
    obj.curO=obj.destO;
  }

  SetOpacity(obj.item, obj.curO);

  if(obj.steps>0)
    obj.handle=window.setTimeout('DoFade(\''+id+'\');', obj.interval);
}
//--------------------------------------------------------------------------

function StartAnimation(item, deltaX, deltaY, destOpacity, duration)
{
  var c_minInterval=20;
  
  var id=GetAnimationObjectName(item);
  var obj=fadingStatus[id];
  if(obj)
  {
    if(obj.handle)
    {
      window.clearTimeout(obj.handle);
      obj.handle=undefined;
    }
  }

  if(duration<0)
    duration=0;

  var startOpacity=GetOpacity(item);
  var deltaO=destOpacity-startOpacity;

  var maxDeltaOld=
    Math.max(Math.abs(deltaO),
    Math.max(Math.abs(deltaX), Math.abs(deltaY)));

  if(obj)
  {
    deltaX+=obj.destX-obj.curX;
    deltaY+=obj.destY-obj.curY;
  }

  var maxDelta=
    Math.max(Math.abs(deltaO),
    Math.max(Math.abs(deltaX), Math.abs(deltaY)));

  if(maxDelta>0)
  {
    var d=maxDeltaOld-maxDelta;
    if(d!=0 && maxDeltaOld!=0)
      duration*=maxDelta/maxDeltaOld;

    obj=new Object();
    obj.item=item;
    obj.handle=undefined;
    obj.curX=GetPosX(item);
    obj.curY=GetPosY(item);
    obj.curO=startOpacity;
    obj.destX=obj.curX+deltaX;
    obj.destY=obj.curY+deltaY;
    obj.destO=destOpacity;
   
    obj.interval=duration/maxDelta;
    if(obj.interval<c_minInterval)
      obj.interval=c_minInterval;

    obj.steps=Math.round(duration/obj.interval);
    obj.incX=deltaX/obj.steps;
    obj.incY=deltaY/obj.steps;
    obj.incO=deltaO/obj.steps;

    fadingStatus[id]=obj;
    DoFadeAnimation(id);
  }
}

function StartFading(item, destOpacity, duration)
{
  var c_minInterval=20;
  
  var id=GetAnimationObjectName(item);
  var obj=fadingStatus[id];
  if(obj)
  {
    if(obj.handle)
    {
      window.clearTimeout(obj.handle);
      obj.handle=undefined;
    }
  }

  if(duration<0)
    duration=0;

  var startOpacity=GetOpacity(item);
  var deltaO=destOpacity-startOpacity;

  var maxDeltaOld=
    Math.max(Math.abs(deltaO));


  var maxDelta=
    Math.max(Math.abs(deltaO));

  if(maxDelta>0)
  {
    var d=maxDeltaOld-maxDelta;
    if(d!=0 && maxDeltaOld!=0)
      duration*=maxDelta/maxDeltaOld;

    obj=new Object();
    obj.item=item;
    obj.handle=undefined;
    obj.curO=startOpacity;
    obj.destO=destOpacity;
   
    obj.interval=duration/maxDelta;
    if(obj.interval<c_minInterval)
      obj.interval=c_minInterval;

    obj.steps=Math.round(duration/obj.interval);
    obj.incO=deltaO/obj.steps;

    fadingStatus[id]=obj;
    DoFade(id);
  }
}

function CancelAnimation(item)
{
  var id=GetAnimationObjectName(item);
  StopAnimationByInternalId(id, false, false);
}

function StopAnimation(item)
{
  var id=GetAnimationObjectName(item);
  StopAnimationByInternalId(id, true, true);
}

//--------------------------------------------------------------------------

