(function() { var AlsaMenu = function() {}; var Ap = AlsaMenu.prototype = {
	/** Comportement du (ou des) menus - Indiquer oui ou non en face de chaque label */
	'Fluid': 'oui',
	'Alone': 'oui',

	/** Intervalle de temps associé */
	'Interval': 10, // Intervalle entre deux itérations de mouvement (ms)
	
	/** Classes CSS associées (affectées via JS) */
	'Menus': 'menus', // Classe CSS permettant l'identification d'un menu
	'Cache': 'Cache', // Masquage des sous-menus
	'Montre': 'Montre', // Affichage des sous-menus
	'FL': 'focusLink', // Style des liens des sous-menus à la prise de focus
	'FT': 'focusTitle', // Style de l'entête des sous-menus à la prise de focus
	'BL': 'blurLink', // Style des liens des sous-menus à la perte de focus
	'BT': 'blurTitle', // Style de l'entête des sous-menus à la perte de focus
	
	/** Navigateur buggué */
	'isSafari': (/webkit/.test(navigator.userAgent.toLowerCase())),
	
	/** Ap.bTest -> Booléen testant les méthodes recquises. */
	'bTest': (document.getElementById && document.getElementsByTagName && document.createElement && document.createTextNode),
	
	/** Ap.oId(sId) -> Retourne l'élément dont l'id est sId. */
	oId: function(sId) {
		return document.getElementById(sId);
	},

	/** Ap.aTag(oEl, sTag) -> Retourne un tableau des éléments nommés sTag et inclus dans l'élément oEl. */
	aTag: function(oEl, sTag) {
		return oEl.getElementsByTagName(sTag);
	},
	
	/** Ap.bElemNotLink(oEl) -> Teste si la valeur de l'élément oEl est non nulle et si c'est un lien. Retourne un booléen */
	bElemNotLink: function(oEl) {
		return oEl.nodeValue != null && oEl.nodeName.toLowerCase() != 'a';
	},
	
	/** Ap.cancelClick(e) -> Annule la propagation d'un événement */
	cancelClick: function(e) {
		if(e && e.stopPropagation && e.preventDefault) {
			e.stopPropagation();
			e.preventDefault();
		}
		else if(e && window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
		}
		return false;
	},
	
	/** Ap.oElem(sEl, oProp) -> Retourne un élément avec différents attributs et un texte inclus. */
	oElem: function(sEl, oProp) {
		var oEl = false;
		if(sEl && typeof(sEl) == 'string') {
			oEl = document.createElement(sEl);
			if(oProp && typeof(oProp) == 'object')
				for(var sParam in oProp)
					switch(sParam) {
						case 'text':
							oEl.appendChild(document.createTextNode(oProp[sParam]));
						break;
						case 'class':
							Ap.css('add', oEl, oProp[sParam]);
						break;
						default:
							oEl.setAttribute(sParam, oProp[sParam]);
					}
		}
		return oEl;
	},
	
	/** Ap.connect(oElem, sEvType, fn, bCapture) -> Attache un événement à une action. */
	connect: function(oElem, sEvType, fn, bCapture) {
		return document.addEventListener?
			oElem.addEventListener(sEvType, fn, bCapture):
			oElem.attachEvent?
				oElem.attachEvent('on' + sEvType, fn):
				false;
	},

	/** Ap.getSource(e) -> Récupère la source d'un événement. */
	getSource: function(e) {
		return e.target || e.srcElement;
	},
	
	/** Ap.insertCtrlLinks(oMenus) -> Transforme les entêtes des sous-menus en liens de contrôle. */
	insertCtrlLinks: function(oMenus) {
		if(!oMenus)
			return;
		var aLis = Ap.aTag(oMenus, 'li');
		var iI = aLis.length;
		if(iI == 0)
			return;
		while(iI-- > 0) {
			var oChildLi = aLis[iI].firstChild;
			if(!oChildLi)
				return;
			if(Ap.bElemNotLink(oChildLi)) {
				var oA = Ap.oElem('a', {'text': oChildLi.nodeValue, 'href': '#ssmenu'});
				aLis[iI].replaceChild(oA, oChildLi);
				Ap.connect(oA, 'click', Ap.cancelClick, false);
			}
		}
		return oMenus;
	},
	
	/** Ap.initCptMenu(oMenus) -> Définit le comportement du menu en fonction de l'événement et de l'élément affecté. */
	initCptMenu: function(oMenus) {
		if(!oMenus)
			return;
		var aA = Ap.aTag(oMenus, 'a');
		var iI = aA.length;
		var func1 = function(e) { Ap.ctrlDisplay(oMenus, e); };
		var func2 = function(e) { Ap.ctrlStyle(oMenus, e); };
		while(iI-- > 0) {
			Ap.connect(aA[iI], 'click', func1, false);
			Ap.connect(aA[iI], 'focus', func2, false);
			Ap.connect(aA[iI], 'blur', func2, false);
			Ap.connect(aA[iI], 'mouseover', func2, false);
			Ap.connect(aA[iI], 'mouseout', func2, false);
		}
		return oMenus;
	},
	
	/** Ap.initStyle(oMenus, instance) -> Définit les styles affectés au menu lorsque JS est actif. */
	initStyle: function(oMenus, instance) {
		if(!oMenus || !instance)
			return;
		var aUls = Ap.aTag(oMenus, 'ul');
		var iI = aUls.length;
		if(iI == 0)
			return;
		do {
			aUls[--iI].id = 'menu' + instance + 'ssmenu' + iI;
			if(!Ap.isSafari)
				aUls[iI].hauteur = aUls[iI].offsetHeight;
			if(aUls[iI].className != Ap['Montre'])
				aUls[iI].className = Ap['Cache'];
		} while(iI > 0);
		return oMenus;
	},
	
	/** Ap.actif() -> Affecte des liens de contrôle, des styles et un comportement aux menus. */
	actif: function() {
		var aUls = Ap.aTag(document, 'ul');
		var iUl = aUls.length;
		var instance = 0;
		do if(aUls[--iUl].className == Ap['Menus']) {
			var oMenus = aUls[iUl];
			if(!oMenus)
				return;
			if(Ap.insertCtrlLinks(oMenus))
				if(Ap.initStyle(oMenus, ++instance))
					Ap.initCptMenu(oMenus);
		} while(iUl > 0);
		return;
	},
	
	/** Ap.compareSsMenu(oMenus, oUl) -> Retourne le numéro d'ordre du sous-menu demandé parmi l'ensemble des sous-menus. */
	compareSsMenu: function(oMenus, oUl) {
		if(!oMenus || !oUl)
			return;
		var aUls = Ap.aTag(oMenus, 'ul');
		var iI = aUls.length;
		while(iI-- > 0)
			if(aUls[iI] == oUl)
				return iI;
		return;
	},
	
	/** Ap.ctrlDisplay(oMenus, e) -> Contrôle l'affichage / masquage des sous-menus. */
	ctrlDisplay: function(oMenus, e) {
		if(!oMenus || !e)
			return;
		var oSource = Ap.getSource(e);
		var oUl = Ap.aTag(oSource.parentNode, 'ul')[0];
		if(!oUl)
			return true;
		if((iI = Ap.compareSsMenu(oMenus, oUl)) != null)
			if(oUl.className == Ap['Cache']) {
				oUl.className = Ap['Montre'];
				if(Ap['Alone'] == 'oui')
					Ap.hideLastList(oMenus);
				if(Ap['Fluid'] == 'oui')
					Ap.roll(oUl.id, 0, oUl.hauteur, Ap['Interval']);
				else
					oUl.className = Ap['Montre'];
				if(!window.event)
					oSource.blur();
			}
			else {
				if(Ap['Fluid'] == 'oui')
					Ap.roll(oUl.id, oUl.hauteur, 0, Ap['Interval']);
				else
					oUl.className = Ap['Cache'];
				if(!window.event)
					oSource.blur();
			}
		return;
	},
	
	/** Ap.ctrlStyle(oMenus, e) -> Contrôle le style des liens des sous-menus. */
	ctrlStyle: function(oMenus, e) {
		if(!oMenus || !e)
			return;
		var oSource = Ap.getSource(e);
		var oParentSource = oSource.parentNode;
		if(e.type == 'focus' || e.type == 'mouseover')
			oSource.className = (oParentSource.parentNode != oMenus)?
				Ap['FL']:
				oSource.className;
		else if(e.type == 'blur' || e.type == 'mouseout')
			oSource.className = (oParentSource.parentNode != oMenus)?
				Ap['BL']:
				oSource.className;
	},
	
	/** Ap.hideLastList(oMenus) -> Cache la liste précédemment ouverte */
	hideLastList: function(oMenus) {
		if(!oMenus)
			return;
		var aUls = Ap.aTag(oMenus, 'ul');
		var iI = aUls.length;
		while(iI-- > 0)
			aUls[iI].className != Ap['Cache']?
				Ap.roll(aUls[iI].id, aUls[iI].hauteur, 0, Ap['Interval']):
				aUls[iI].parentNode.firstChild.className = Ap['BT'];
		return;
	},
	
	/** Ap.roll(id, initHeight, finalHeight, interval) -> Anime la hauteur d'un élément. */
	roll: function(id, initHeight, finalHeight, interval) {
		var oElem = Ap.oId(id);
		if(!oElem)
			return;
		if(Ap.isSafari && !oElem.testSafari && oElem.className == Ap['Cache']) {
			oElem.className = Ap['Montre'];
			finalHeight = oElem.offsetHeight;
			oElem.testSafari = true;
		}
		if(oElem.style.overflow != 'hidden') {
			oElem.style.overflow = 'hidden';
			oElem.style.height = 0;
		}
		if(oElem.movement)
			clearTimeout(oElem.movement);
		var iDimY = parseInt(oElem.style.height);
		if(iDimY == finalHeight) {
			if(!oElem.test && finalHeight != 0)
				oElem.test = true;
			else {
				oElem.style.height = '';
				oElem.style.overflow = '';
				if(window.attachEvent) {
					var nav = navigator.userAgent.toLowerCase();
					if(parseInt(navigator.appVersion) == 4 && nav.indexOf("msie 5.0") != -1)
						oElem.style.height = finalHeight + 'px';
					else
						oElem.style.zoom = '1';
				}
				oElem.test = null;
				oElem.testSafari = null;
			}
			if(iDimY < 2) {
				oElem.parentNode.firstChild.className = Ap['BT'];
				oElem.className = Ap['Cache'];
			}
			return;
		}
		if(finalHeight != 0) {
			oElem.parentNode.firstChild.className = Ap['FT'];
			oElem.className = Ap['Montre'];
		}
		if(iDimY < finalHeight)
			iDimY = iDimY + Math.ceil((finalHeight - iDimY)/10);
		if(iDimY > finalHeight)
			iDimY = iDimY - Math.ceil((iDimY - finalHeight)/10);
		oElem.style.height = iDimY + 'px';
		var repeat = function() { Ap.roll(id, initHeight, finalHeight, interval); };
		oElem.movement = setTimeout(repeat, interval);
		return;
	},
	
	/** Ap.init() -> Initialisation de l'objet */
	init: function() {
		if(Ap.bTest)
			document.addEventListener?
				Ap.connect(window, 'DOMContentLoaded', Ap.actif, false):
				Ap.connect(window, 'load', Ap.actif, false);
	}
};
var monMenu = new AlsaMenu;
monMenu.init();
})();
