function AnimationManager(intervalPeriod)
{
	//create unique id
	if (document.animationManagers==null) document.animationManagers=new Array();
	this._id=document.animationManagers.length;
	document.animationManagers.push(this);
	this._initialized=false;

	//Items
	this.items=new Object();

	//Interval
	this._intervalId=null;
	this._intervalPeriod=this.intervalPeriod!=null?intervalPeriod:10;
	this._intervalItems=new Array();

	//Collection methods
	this.addItem=AnimationManager_AddItem;
	this.containsItem=AnimationManager_ContainsItem;
	this.removeItem=AnimationManager_RemoveItem;
	this.getChildrenItems=AnimationManager_GetChildrenItems;
	this.hasChildrenItems=AnimationManager_HasChildrenItems;

	//Methods
	this.hideItemChildren=AnimationManager_HideItemChildren;
	this.continueAnimation=AnimationManager_ContinueAnimation;
	this.startAnimation=AnimationManager_StartAnimation;
	this.endAnimation=AnimationManager_EndAnimation;
	this.documentClick=AnimationManager_DocumentClick;
	this.windowUnload=AnimationManager_WindowUnload;
	this.windowLoad=AnimationManager_WindowLoad;
	this.getInitialized=AnimationManager_GetInitialized;

	//Events handlers
	this._intervalCallBack=new Function("document.animationManagers["+this._id+"].continueAnimation();");
	addEvent(window,"load",new Function("document.animationManagers["+this._id+"].windowLoad();"),false);
	addEvent(window,"unload",new Function("document.animationManagers["+this._id+"].windowUnload();"),false);
	addEvent(document,"click",new Function("document.animationManagers["+this._id+"].documentClick();"),false);
}

function AnimationManager_AddItem(item,parentItem)
{
	if (this.containsItem(item,parentItem)) throw "Can't add the same item twice to items.";

	var items=this.items;
	items[item.getItemId()]=item;
	item.setOwner(this);
	item.setParentItem(parentItem);
	return this.getChildrenItems(parentItem).length;
}

function AnimationManager_ContainsItem(item,parentItem)
{
	var items=this.getChildrenItems(parentItem);
	return HashObject.contains(items,item);	
}

function AnimationManager_RemoveItem(item,parentItem)
{
	if (!this.containsItem(item,parentItem)) throw "Can't remove item because it not belong to items.";
	
	var items=this.items;
	HashObject.removeValue(items,item);
	item.setOwner(null);
	item.setParentItem(null);
	return this.getChildrenItems(parentItem).length;
}

function AnimationManager_GetChildrenItems(item)
{
	var children=new Object();
	var items=this.items;
	for (var itemId in items)
	{
		var item1=items[itemId];
		if (item1.getParentItem()==item) children[itemId]=item1;
	}
	return children;
}

function AnimationManager_HasChildrenItems(item)
{
    var items=this.items;
    for (var itemId in items)
	{
		var item1=items[itemId];
		if (item1.getParentItem()==item) return true;
	}
	return false;
}

function AnimationManager_GetInitialized()
{
    return this._initialized;
}

function AnimationManager_WindowLoad(e)
{
	this._initialized=true;
	var items=this.items;
	for (var itemId in items) 
	{
	    var item=items[itemId];
	    item.initItemSource();
	}
}

function AnimationManager_WindowUnload(e)
{
	if (this._intervalId!=null) window.clearInterval(this._intervalId);
	this._initialized=false;
	var items=this.items;
	for (var itemId in items) 
	{
	    var item=items[itemId];
	    item.dispose();
	}
}

function AnimationManager_DocumentClick(e)
{
	var items=this.items;
	for (var itemId in items)
	{
		var item=items[itemId];
		item.onDocumentClick();
	}
}

function AnimationManager_HideItemChildren(item,exceptChildItem,recursive)
{
	var children=this.getChildrenItems(item);
	for (var childItemId in children)
	{
		var childItem=children[childItemId];
		if (childItem.getVisible() && childItem!=exceptChildItem)
		{
			childItem.radioBehaviourHide();
			if (recursive) this.hideItemChildren(childItem,null,recursive);
		}
	}
}

function AnimationManager_StartAnimation(item,show)
{
	var parentItem=item.getParentItem();
	if (parentItem) parentItem.childrenStartAnimation(item,show);

	if (this._intervalItems.indexOf(item)==-1)
	{
		this._intervalItems.push(item);
		if (this._intervalId==null) this._intervalId=window.setInterval(this._intervalCallBack,this._intervalPeriod);
	}
}

function AnimationManager_ContinueAnimation()
{
	var items=new Array();
	for(var num1=0;num1<this._intervalItems.length;num1++) items.push(this._intervalItems[num1]);
	for (var num1=0;num1<items.length;num1++) items[num1].continueAnimation();
}

function AnimationManager_EndAnimation(item)
{
	var parentItem=item.getParentItem();
	if (parentItem) parentItem.childrenEndAnimation(item);
	
	var index=this._intervalItems.indexOf(item);
	if (index>-1) this._intervalItems.splice(index,1);
	if (this._intervalItems.length==0) 
	{
		window.clearInterval(this._intervalId);
		this._intervalId=null;
	}
}

function AnimatedItem(itemId,element,source,radioBehaviour,hideOnDocumentClick)
{
	//Fields
	this._itemId=itemId;
	this._element=element;
	this._source=source;
	this._radioBehaviour=radioBehaviour;
	this._hideOnDocumentClick=hideOnDocumentClick;
	
	this._owner=null;
	this._direction=0;
	this._parentItem=null;
	this._isShowing=false;
	this._isInAnimation=false;
	this._itemSource=getElement(this._source);
	this._itemElement=getElement(this._element);
	if (this._itemElement) this._itemElement.animatedItem=this;

	//Properties
	this.getItemId=function(){return this._itemId;}
	this.getParentItem=function(){return this._parentItem;}
	this.setParentItem=function(parentItem){this._parentItem=parentItem;}
	this.getOwner=function(){if (this._owner==null) this.autoAddToManager(); return this._owner;}
	this.setOwner=function(owner){if (this._owner!=null && this._owner!=owner) this._owner.removeItem(this); this._owner=owner;}
	this.getDirection=function(){return this._direction;}
	this.setDirection=function(direction){this._direction=direction;}
	this.getIsShowing=function(){return this._isShowing;}
	this.setIsShowing=function(show){this._isShowing=show;}
	this.getVisible=function(){return this._itemElement && this._itemElement.style.display!="none";}
	this.setVisible=function(visible){if (this._itemElement) this._itemElement.style.display=visible?"block":"none";}
	this.getHideOnDocumentClick=function(){return this._hideOnDocumentClick;}
	this.setHideOnDocumentClick=function(hideOnDocumentClick){this._hideOnDocumentClic=hideOnDocumentClick;}
	this.getIsInAnimation=function(){return this._isInAnimation;}
	this.setIsInAnimation=function(isInAnimation){this._isInAnimation=isInAnimation;}
	this.getRadioBehaviour=function(){return this._radioBehaviour;}
	this.setRadioBehaviour=function(radioBehaviour){this._radioBehaviour=radioBehaviour;}
	
	//Collection Methods
	this.addItem=AnimatedItem_AddItem;
	this.containsItem=AnimatedItem_ContainsItem;
	this.indexOfItem=AnimatedItem_IndexOfItem;
	this.removeItem=AnimatedItem_RemoveItem;
	this.getItems=AnimatedItem_GetItems;
	this.hasItems=AnimatedItem_HasItems

	//Others methods
	this.autoAddToManager=AnimatedItem_AutoAddToManager;
	this.initItemSource=AnimatedItem_InitItemSource;
	this.dispose=AnimatedItem_Dispose;
	this.startAnimation=AnimatedItem_StartAnimation;
	this.continueAnimation=AnimatedItem_ContinueAnimation;
	this.endAnimation=AnimatedItem_EndAnimateOut;
	this.childrenStartAnimation=AnimatedItem_ChildrenStartAnimation;
	this.childrenEndAnimation=AnimatedItem_ChildrenEndAnimation;
	this.onDocumentClick=AnimatedItem_OnDocumentClick;
	this.hanldeRadioBehaviour=AnimatedItem_HanldeRadioBehaviour;
	this.radioBehaviourHide=AnimatedItem_RadioBehaviourHide;
}

function AnimatedItem_AddItem(item)
{
	return this.getOwner().addItem(item,this);
}

function AnimatedItem_ContainsItem(item)
{
	return this.getOwner().containsItem(item,this);
}

function AnimatedItem_IndexOfItem(item)
{
	return this.getOwner().indexOfItem(item,this);
}

function AnimatedItem_RemoveItem(item)
{
	return this.getOwner().removeItem(item,this);
}

function AnimatedItem_GetItems()
{
	return this.getOwner().getChildrenItems(this);
}

function AnimatedItem_HasItems()
{
	return this.getOwner().hasChildrenItems(this);
}

function AnimatedItem_AutoAddToManager()
{
	if (document.animationManagers==null) this._owner=new AnimationManager();
	document.animationManagers[0].addItem(this);
}

function AnimatedItem_InitItemSource()
{	
    this._switchFunction=new Function("AnimatedItem_Switch('"+this._element+"',this);")
	addEvent(this._itemSource,"click",this._switchFunction,true);
}

function AnimatedItem_Dispose()
{	
    if (this._switchFunction) removeEvent(this._itemSource,"click",this._switchFunction,true);
}

function AnimatedItem_HanldeRadioBehaviour() 
{
    var owner=this.getOwner();
    if (this.getRadioBehaviour()) owner.hideItemChildren(this.getParentItem(),this,true);
}

function AnimatedItem_RadioBehaviourHide()
{
    this.startAnimation(false);
}

function AnimatedItem_OnDocumentClick()
{
    if (this.getHideOnDocumentClick() && this.getVisible()) this.startAnimation(false);
}

function AnimatedItem_Hide(item,source)
{
	var animatedItem=getElementProperty(getElement(item),"animatedItem");
	if (animatedItem) animatedItem.startAnimation(false,source);
}

function AnimatedItem_Show(item,source)
{
	var animatedItem=getElementProperty(getElement(item),"animatedItem");
	if (animatedItem) animatedItem.startAnimation(true,source);
}

function AnimatedItem_Switch(item,source)
{
	var animatedItem=getElementProperty(getElement(item),"animatedItem");
	if (animatedItem) animatedItem.startAnimation(!animatedItem.getIsShowing(),source);
}

function AnimatedItem_StartAnimation(show,source) { }
function AnimatedItem_ContinueAnimation() { }
function AnimatedItem_EndAnimateOut() { }
function AnimatedItem_ChildrenStartAnimation(animatedItem,show) {}
function AnimatedItem_ChildrenEndAnimation(animatedItem) {}