
var MENU_RESIZE_PIXELS = 30;
var MENU_RESIZE_MS = 20;

var MENU_PUBLIC_ID_SEQUENCE = 0;

var MENU_CHOREGRAPHY_DELAY = 100;


/*
	---------------------------------------------------------------
	CLASSE : ElementChoregraphie
	---------------------------------------------------------------
*/
function ElementChoregraphie(_level, _action) {
	this.level = _level;
	this.action = _action;
}




/*
	---------------------------------------------------------------
	CLASSE : Menu
	---------------------------------------------------------------
*/
function Menu() {
	this.elements = new Array();
	
	this.choregraphie = new Array();
	this.choregraphieIndex = 0;

	// Id public
	this.publicId = "Menu" + (++MENU_PUBLIC_ID_SEQUENCE);
	eval("window."+this.publicId+"=this;");
	
	this.minLevel = 999999;
	this.maxLevel = -1;
	
	this.addElement = Menu_addElement;
	this.getElementByLevel = Menu_getElementByLevel;

	this.addChoregraphyElement = Menu_addChoregraphyElement;
	this.executeChoregraphy = Menu_executeChoregraphy;
	this.isChoregraphyRunning = false;
	this.endOfChoregraphyCallback = null;
	this.timer = null;
	
	this.choregraphieMenu = Menu_choregraphieMenu;
}

/*
	Ajoute un element de chorégraphie
*/
function Menu_addChoregraphyElement(elt) {
	with(this) {
		choregraphie[choregraphie.length] = elt;
	}
}


/*
	Execute une chorégraphie sur les éléments du menu/
*/
function Menu_executeChoregraphy() {
	with(this) {
		if (choregraphieIndex>=choregraphie.length) {			
			isChoregraphyRunning = false;
			if (endOfChoregraphyCallback!=null)
				eval(endOfChoregraphyCallback);
			return;
		}
			
		var eltChore = choregraphie[choregraphieIndex];
		var menuElt = getElementByLevel(eltChore.level);
		
		if (isChoregraphyRunning && menuElt.currentlyProcessing) {
			// Element courant pas fini
			timer = setTimeout("window."+publicId+".executeChoregraphy();", MENU_CHOREGRAPHY_DELAY);
			return;
		}
		
		if (!isChoregraphyRunning) {
			// On commence sur ce 1er élément
			isChoregraphyRunning = true;
		}
		else {
			// On passe à l'élément suivant
			choregraphieIndex++;
			if (choregraphieIndex>=choregraphie.length) {
				// Fin de la chorégraphie
				isChoregraphyRunning = false;
				if (endOfChoregraphyCallback!=null)
					eval(endOfChoregraphyCallback);
				return;
			}

			eltChore = choregraphie[choregraphieIndex];
			menuElt = getElementByLevel(eltChore.level);			
		}
		
		// On déclenche le traitement sur l'élément
		menuElt.currentlyProcessing = true;
		//alert(choregraphieIndex+" / "+choregraphie.length+" - Je démarre "+eltChore.action+" sur niveau "+eltChore.level);
		eval("menuElt."+eltChore.action+"()");

		timer = setTimeout("window."+publicId+".executeChoregraphy();", MENU_CHOREGRAPHY_DELAY);
	}
}


/*
	Ajoute une élément au menu.
*/
function Menu_addElement(menuElement) {
	with(this) {
		elements[menuElement.level] = menuElement;
		
		if (minLevel > menuElement.level)
			minLevel = menuElement.level;
			
		if (maxLevel < menuElement.level)
			maxLevel = menuElement.level;
	}
}


/*
	Retourne l'élement de niveau donné ou null si inexistant
*/
function Menu_getElementByLevel(level) {
	with(this) {
		if (typeof(elements[level])=="undefined")
			return null;
		return elements[level];
	}
}


/*
	Choregraphie l'animation des menus quand on clique sur un élément de niveau donné.
*/
function Menu_choregraphieMenu(level, endCallback) {
	with(this) {
		endOfChoregraphyCallback = endCallback;
		
		for(var l=maxLevel; l>level; l--) {
			addChoregraphyElement( new ElementChoregraphie(l, "close") );
			addChoregraphyElement( new ElementChoregraphie(l, "hide") );
		}
		addChoregraphyElement( new ElementChoregraphie(level, "close") );
		
		executeChoregraphy();
	}
}




/*
	---------------------------------------------------------------
	CLASSE : Element de menu
	---------------------------------------------------------------
*/
function MenuElement(_level, _initiallyClosed) {	
	this.level = _level;
	this.initiallyClosed = _initiallyClosed;
	this.isClosed = _initiallyClosed;
	this.isHidden = false;
	this.currentlyProcessing = false;

	// Id public
	this.publicId = "MenuElt" + (++MENU_PUBLIC_ID_SEQUENCE);
	eval("window."+this.publicId+"=this;");

	this.isInitialized = false;
	this.openedHeight = 0;
	this.visibleHeight = 0;
	this.timer = null;
	
	this.flipFlap = MenuElement_flipFlap;
	this.close = MenuElement_close;
	this.open = MenuElement_open;
	this.hide = MenuElement_hide;
	this.show = MenuElement_show;
	this.getMenuObject = MenuElement_getMenuObject;
	this.getContentObject = MenuElement_getContentObject;
	this.setContentVisibleHeight = MenuElement_setContentVisibleHeight;	
	this.init = MenuElement_init;
	
	this.init();
}


/*
	Initialise le menu
*/
function MenuElement_init() {
	with(this) {
		// Hauteur initiale de l'élément
		openedHeight = getHauteurElement(getContentObject());		
		if (isClosed)
			visibleHeight=0;
		else
			visibleHeight=openedHeight;
			
		isInitialized = true;
	}
}



/*
	Renvoie le bloc HTML du menu
*/
function MenuElement_getMenuObject() {
	return getObj("menuLevel"+this.level);
}


/*
	Renvoie le bloc HTML du contenu du menu
*/
function MenuElement_getContentObject() {
	return getObj("menuContent"+this.level);
}


/*
	Change la taille visible du menu
*/
function MenuElement_setContentVisibleHeight(h) {
	with(this) {
		getContentObject().style.height = h+"px";
	}
}



/*
	Ouvre ou ferme le menu, selon son état actuel.
*/
function MenuElement_flipFlap() {
	with(this) {
		if (currentlyProcessing)
			return;
			
		if (isClosed)
			open();
		else
			close();
	}
}


/*
	Ouvre l'élément de menu
*/
function MenuElement_open() {
	with(this) {
		if (!isInitialized)
			init();
	
		if (!isClosed) {
			currentlyProcessing=false;
			return;
		}
	
		visibleHeight = Math.min(visibleHeight + MENU_RESIZE_PIXELS, openedHeight);		
		setContentVisibleHeight(visibleHeight);
		rendVisible(getContentObject());
		
		if (visibleHeight==openedHeight) {
			currentlyProcessing=false;
			isClosed = false;
			getMenuObject().className="opened menu";
			return;
		}

		// On poursuit le traitement après un délai
		if (timer!=null)
			clearTimeout(timer);
		timer = setTimeout(publicId+".open();", MENU_RESIZE_MS);
	}
}

/*
	Ferme l'élément de menu
*/
function MenuElement_close() {
	with(this) {
		if (!isInitialized)
			init();
	
		if (isClosed) {
			currentlyProcessing=false;
			return;
		}

		visibleHeight = Math.max(visibleHeight - MENU_RESIZE_PIXELS, 0);		
		setContentVisibleHeight(visibleHeight);
		
		if (visibleHeight==0) {
			currentlyProcessing=false;
			isClosed = true;
			rendInvisible(getContentObject());
			getMenuObject().className="closed menu";
			return;
		}

		// On poursuit le traitement après un délai
		if (timer!=null)
			clearTimeout(timer);
		timer = setTimeout("window."+publicId+".close();", MENU_RESIZE_MS);
	}
}



/*
	Montre l'élément de menu
*/
function MenuElement_show() {
	with(this) {
		if (!isInitialized)
			init();
	
		if (!isHidden) {
			currentlyProcessing=false;
			return;
		}
	
		getMenuObject().style.display="block";
		isHidden = false;
		
		currentlyProcessing=false;
	}
}



/*
	Cache l'élément de menu
*/
function MenuElement_hide() {
	with(this) {
		if (!isInitialized)
			init();
			
		if (isHidden) {
			currentlyProcessing=false;
			return;
		}

		getMenuObject().style.display="none";
		isHidden = true;
		
		currentlyProcessing=false;
	}
}


 
function rendInvisible(obj) {
	obj.style.visibility="hidden";
	obj.style.zIndex="-11000";
	obj.style.position="absolute";
}
 

function rendVisible(obj) {
	obj.style.visibility="visible";
	obj.style.zIndex="1";
	obj.style.position="relative";
}




