function AnimationFrame(left, top, width, height, time)
{
  this.Left = left;
  this.Top = top;
  this.Width = width;
  this.Height = height;
  this.Time = time;
 
  this.Copy = function(frame)
  {
    this.Left = frame.Left;
    this.Top = frame.Top;
    this.Width = frame.Width;
    this.Height = frame.Height;
    this.Time = frame.Time;
  }
 
  this.Apply = function(element)
  {
    element.style.left = Math.round(this.Left) + 'px';
    element.style.top = Math.round(this.Top) + 'px';
    element.style.width = Math.round(this.Width) + 'px';
    element.style.height = Math.round(this.Height) + 'px';
  }
}

function AnimationObject(element)
{
  if(typeof(element) == "string")
    element = document.getElementById(element);
 
  var frames = null; 
  var timeoutID = -1;
  var running = 0;
  var currentFI = 0;
  var currentData = null;
  var lastTick = -1;
  var callback = null;
 
  var prevDir = 0;
 
  this.AddFrame = function(frame)
  {
    frames.push(frame);
  }
 
  this.SetCallback = function(cb)
  {
    callback = cb;
  }
 
  this.ClearFrames = function()
  {
    if(running != 0)
      this.Stop();
    frames = new Array();
    frames.push(new AnimationFrame(0,0,0,0,0));
    frames[0].Time = 0;
    frames[0].Left = parseInt(element.style.left);
    frames[0].Top = parseInt(element.style.top);
    frames[0].Width = parseInt(element.style.width);
    frames[0].Height = parseInt(element.style.height);
    currentFI = 0;
    prevDir = 0;
    currentData = new AnimationFrame(0,0,0,0,0);   
  }
 
  this.ResetToStart = function()
  {
    if(running != 0)
      this.Stop();
    currentFI = 0;
    prevDir = 0;
    currentData = new AnimationFrame(0,0,0,0,0);
    frames[0].Apply(element);
  }
 
  this.ResetToEnd = function()
  {
    if(running != 0)
      this.Stop();
    currentFI = 0;
    prevDir = 0;
    currentData = new AnimationFrame(0,0,0,0,0);
    frames[frames.length - 1].Apply(element);
  }
 
  this.Stop = function()
  {
    if(running == 0)
      return;
    if(timeoutID != -1)
      clearTimeout(timeoutID);
    prevDir = running;
    running = 0;
  }
 
  this.RunForward = function()
  {
    if(running == 1)
      return;
    if(running == -1)
      this.Stop();
    if(frames.length == 1 || element == null)
      return; 
     
    lastTick = new Date().getTime();

    // Start from the begining
    if(prevDir == 0)
    {
      currentFI = 1;
      currentData.Time = 0;
      currentData.Left = parseInt(element.style.left);
      currentData.Top = parseInt(element.style.top);
      currentData.Width = parseInt(element.style.width);
      currentData.Height = parseInt(element.style.height);
      frames[0].Copy(currentData);
    }
    else if(prevDir != 1)
    {
      currentFI++;
      currentData.Time =
          frames[currentFI].Time - currentData.Time;
    }
     
    running = 1;
    animate();
  }
 
  this.RunBackward = function()
  {
    if(running == -1)
      return;
    if(running == 1)
      this.Stop();
    if(frames.length == 1 || element == null)
      return;
       
    lastTick = new Date().getTime();
   
    // Start from the end
    if(prevDir == 0)
    {
      currentFI = frames.length-2;
      currentData.Left = parseInt(element.style.left);
      currentData.Top = parseInt(element.style.top);
      currentData.Width = parseInt(element.style.width);
      currentData.Height = parseInt(element.style.height);
      currentData.Time = frames[frames.length-1].Time;
      frames[frames.length-1].Copy(currentData);
      currentData.Time = 0;
    }
    else if(prevDir != -1)
    {
      currentData.Time =
          frames[currentFI].Time - currentData.Time;
      currentFI--;
    }
     
    running = -1;
    animate();
  }
   
  function animate()
  {
    if(running == 0)
      return;
    var curTick = new Date().getTime();
    var tickCount = curTick - lastTick;
    lastTick = curTick;
   
    var timeLeft =
       frames[((running == -1) ? currentFI+1 : currentFI)].Time
       - currentData.Time;
   
    while(timeLeft <= tickCount)
    {
      currentData.Copy(frames[currentFI]);
      currentData.Time = 0;
      currentFI += running;
      if(currentFI>= frames.length || currentFI <0)
      {
        currentData.Apply(element);
        lastTick = -1;
        running = 0;
        prevDir = 0;
        if(callback != null)
          callback();
        return;
      }
      tickCount = tickCount - timeLeft;
      timeLeft =
        frames[((running == -1) ? currentFI+1 : currentFI)].Time
        - currentData.Time;
    }
   
    if(tickCount != 0)
    {
      currentData.Time += tickCount;
      var ratio = currentData.Time/
        frames[((running == -1) ? currentFI+1 : currentFI)].Time;

      currentData.Left = frames[currentFI-running].Left +
         (frames[currentFI].Left
         - frames[currentFI-running].Left)
         * ratio;

      currentData.Top = frames[currentFI-running].Top +
         (frames[currentFI].Top
         - frames[currentFI-running].Top)
         * ratio;
      currentData.Width = frames[currentFI-running].Width +
         (frames[currentFI].Width
         - frames[currentFI-running].Width)
         * ratio;

      currentData.Height = frames[currentFI-running].Height +
         (frames[currentFI].Height
         - frames[currentFI-running].Height)
         * ratio;
    }
   
    currentData.Apply(element);

    timeoutID = setTimeout(animate, 33);
  }
 
  this.ClearFrames();
}

function switchMouse(header, navitem){
	//alert(navitem + " :: " + header.expanded);
	switch(navitem){
		case "navitem1":
			if(header.expanded){
				//alert("do nothing");
			} else {
                                MM_swapImage('navitem1', '', rf_template_dir + 'nav1_open.gif', 1);
			}
			break;
		case "navitem2":
			if(header.expanded){
				//alert("do nothing");
			} else {
                                MM_swapImage('navitem2', '', rf_template_dir + 'nav2_open.gif', 1);
			}
			break;
		case "navitem3":
			if(header.expanded){
				//alert("do nothing");
			} else {
                                MM_swapImage('navitem3', '', rf_template_dir + 'nav3_open.gif', 1);
			}
			break;
	}
}
function offMouse(header, navitem){
	//alert(navitem + " :: " + header.expanded);
	switch(navitem){
		case "navitem1":
			if(header.expanded){
                                MM_swapImage('navitem1', '', rf_template_dir + 'nav1_open.gif', 1);
                                MM_swapImage('navitem1', '', rf_template_dir + 'nav1_open.gif', 1);
			} else {
                                MM_swapImage('navitem1', '', rf_template_dir + 'nav1_closed.gif', 1);
			}
			break;
		case "navitem2":
			if(header.expanded){
                                MM_swapImage('navitem2', '', rf_template_dir + 'nav2_open.gif', 1);
			} else {
                                MM_swapImage('navitem2', '', rf_template_dir + 'nav2_closed.gif', 1);
			}
			break;
		case "navitem3":
			if(header.expanded){
                                MM_swapImage('navitem3', '', rf_template_dir + 'nav3_open.gif', 1);
			} else {
                                MM_swapImage('navitem3', '', rf_template_dir + 'nav3_closed.gif', 1);
			}
			break;
	}
}

function runAnimation(animation, header, navitem){
	switch(navitem){
		case "navitem1":
			MM_swapImage('navitem1', '', rf_template_dir + 'nav1_open.gif', 1);
			MM_swapImage('navitem2', '', rf_template_dir + 'nav2_closed.gif', 1);
			MM_swapImage('navitem3', '', rf_template_dir + 'nav3_closed.gif', 1);
			break;
		case "navitem2":
			MM_swapImage('navitem1', '', rf_template_dir + 'nav1_closed.gif', 1);
			MM_swapImage('navitem2', '', rf_template_dir + 'nav2_open.gif', 1);
			MM_swapImage('navitem3', '', rf_template_dir + 'nav3_closed.gif', 1);
			break;
		case "navitem3":
			MM_swapImage('navitem1', '', rf_template_dir + 'nav1_closed.gif', 1);
			MM_swapImage('navitem2', '', rf_template_dir + 'nav2_closed.gif', 1);
			MM_swapImage('navitem3', '', rf_template_dir + 'nav3_open.gif', 1);
			break;
	}
	if(header.expanded){
		animation.RunBackward();
		header.expanded = false;
	} else {
		animation.RunForward();
		header.expanded = true;
	}
}

function runClose(animation, header){
	if(header.expanded){
		animation.RunBackward();
		header.expanded = false;
	}
}

function MM_swapImgRestore() { // v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_preloadImages() { // v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_findObj(n, d) { // v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { // v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}
