// JavaScript Document

var NUMMILLISECONDS = 30;
var gListOfItemsAnimatingArray = new Array();
var gWrapperHoldingTheCurrentlyAnimatingList = new Object();
var gAnimatedListManagerInstance;
var gIsListItem;
var gIsAnimating = false;

function AnimatedListManager()
{
this.PrevListIndex = 0;
this.PrevList = new Array();
this.NextListIndex = 0;
this.NextList = new Array();
this.TempIndex = 0;
this.TempArray = new Array();
gAnimatedListManagerInstanceObject = this;
}

// strListItem - A single string that begins with '<li...' and ends with '</li>'.  Must be valid HTML.
AnimatedListManager.prototype.AddItem=function(strListItem)
{
var strPrevList = "";
if( 0 < this.TempIndex ) strPrevList = this.TempArray[this.TempIndex - 1];
this.TempArray[this.TempIndex] = strPrevList + strListItem;
this.TempIndex++;
}

//oListWrapperObject - any object that has an innerHTML property that can be set by JavaScript
//UniqueLevelIdentifier - must be a heirarchical number.  Must be explicitly set for each level.  Without this, the object will not know which level to add the list to.
AnimatedListManager.prototype.Commit=function(oListWrapperObjectId, UniqueLevelIdentifier)
{
this.NextList[this.NextListIndex] = new ListToAnimate(this.TempArray, UniqueLevelIdentifier, oListWrapperObjectId);
this.TempArray = new Array();
this.TempIndex = 0;
this.NextListIndex++;
}

AnimatedListManager.prototype.Animate=function()
{
  if( !gIsAnimating && 0 < this.NextListIndex )
  {
	this.CallBackManager();
  }
}

AnimatedListManager.prototype.CallBackManager=function()
{
  var bReadyToExpand = true;
  if ( !gIsAnimating )
  {
	  //If The new list to add is at a particular level, then all lists lower than that need to be collapsed.
	  if ( 0 < this.PrevListIndex ) // We don't need to check if there are no previous lists.
	  {
		  //if ( 2 != this.NextListIndex && ( 1 != this.NextListIndex && 0 != this.NextList[0].UID ) ) // We don't collapse the top level, so no need to decrement there.
		  //{
			
			if ( this.PrevList[this.PrevListIndex - 1].UID > this.NextList[0].UID || ( this.PrevList[this.PrevListIndex - 1].UID == 0 && ( this.PrevList[this.PrevListIndex - 1].UID == this.NextList[0].UID ) ) )
			{
			  this.PrevListIndex--;
			  gListOfItemsAnimatingArray = this.PrevList[this.PrevListIndex].IterationList;
			  
			  gWrapperHoldingTheCurrentlyAnimatingList = document.getElementById(this.PrevList[this.PrevListIndex].FillObjectId);
			  
			  gIsAnimating = true;
			  
			  bReadyToExpand = false;
			  ListCollapse(this.PrevList[this.PrevListIndex].IterationList.length - 1);
			  this.PrevList[this.PrevListIndex] = null;
			}
		  //}
	  }
	  if ( true == bReadyToExpand )
	  {
		if ( 2 == this.NextListIndex ) // checking if we have committed two levels in one go.
		{
		  if ( 0 < this.PrevListIndex ) this.PrevListIndex--;
		  // We have to replace the calling list as well as the display list.
		  // The exception to this is at the top level, when we collapse it anyway.
		  this.PrevList[this.PrevListIndex] = this.NextList[0];

          var oFillObject = document.getElementById(this.NextList[0].FillObjectId);
		  oFillObject.innerHTML = '<ul>' + this.NextList[0].IterationList[this.NextList[0].IterationList.length - 1] + '</ul>';
		  oFillObject.height = 'auto';
		  this.PrevListIndex++;
		  this.PrevList[this.PrevListIndex] = this.NextList[1];
		}
		else
		{
		  this.PrevList[this.PrevListIndex] = this.NextList[0];
		}
        if ( 2 == this.NextListIndex || ( 1 == this.NextListIndex && 0 == this.NextList[0].UID ) )
		{
			//alert(' this.NextListIndex ' + this.NextListIndex );
			//alert(' this.NextList[0].UID ' + this.NextList[0].UID );
		  this.PrevListIndex++;
		  gListOfItemsAnimatingArray = this.NextList[this.NextListIndex - 1].IterationList;
		  gWrapperHoldingTheCurrentlyAnimatingList = document.getElementById(this.NextList[this.NextListIndex - 1].FillObjectId);
		  gWrapperHoldingTheCurrentlyAnimatingList.style.height = 'auto';
		  gIsAnimating = true;
		  ListExpand(0);
		}
		else
		{
          var oFillObject = document.getElementById(this.NextList[0].FillObjectId);
		  oFillObject.innerHTML = '<ul>' + this.NextList[0].IterationList[this.NextList[0].IterationList.length - 1] + '</ul>';
		  oFillObject.height = 'auto';
	      this.ClearCurrent();
		}
	  }
  }
}

AnimatedListManager.prototype.ClearCurrent=function()
{
this.TempIndex = 0;
this.TempArray = new Array();
this.NextList = new Array();
this.NextListIndex = 0;
// this.CurrentObjectToFill = null;
// this.CurrentLevelIdentifier = null;
}

AnimatedListManager.prototype.ClearAll=function()
{
this.ClearCurrent();
this.PrevListIndex = 0;
this.PrevList = new Array();
}

function ListCollapse(Index)
{
  var strList;
  if ( 0 <= Index )
  {
    gWrapperHoldingTheCurrentlyAnimatingList.innerHTML = '<ul>' + gListOfItemsAnimatingArray[Index] + '</ul>';
	  
    Index--;
    setTimeout('ListCollapse(' + Index + ')', NUMMILLISECONDS);
  }
  else
  {
	gWrapperHoldingTheCurrentlyAnimatingList.innerHTML = '';
	gIsAnimating = false;
    gAnimatedListManagerInstanceObject.CallBackManager();
  }
}

function ListExpand(Index)
{
  if ( gListOfItemsAnimatingArray.length > Index )
  {
    gWrapperHoldingTheCurrentlyAnimatingList.innerHTML = '<ul>' + gListOfItemsAnimatingArray[Index] + '</ul>';
    Index++;
    setTimeout('ListExpand(' + Index + ')', NUMMILLISECONDS);
  }
  else
  {
	gAnimatedListManagerInstanceObject.ClearCurrent();
    gIsAnimating = false;
  }
}

// strArray - Array of strings.  The confusing part is that each item of the Array includes all the previous items in the string.  This is to make it less programatically intense to collapse the list because the string does not need to be recreated for each level on collapse.
// UniqueLevelIdentifier - Just holds the Level so that the AnimatedListManager knows how many levels need to be collapsed.
function ListToAnimate(strArray, UniqueLevelIdentifier, oWrapperId)
{
this.UID = UniqueLevelIdentifier;
this.IterationList = strArray;
this.FillObjectId = oWrapperId;
}