/** Menu déroulant v.1 par Romain Berton pour www.alsacreations.com */

(function() { var AlsaMenu = function() {}; var Ap = AlsaMenu.prototype = {
	/** Classes CSS associées */
	'Menus': 'menus', // Classe CSS permettant l'identification d'un menu
	'Style': 'menus Surv', // Classes css affectées au(x) menu(s) lorsque JS est actif
	'Montre': 'Montre', // Affichage des sous-menus
	'Cache': 'Cache', // Masquage 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
	
	/** Ap.bTest -> Teste les méthodes recquises. Retourne un booléen */
	'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.contains(container, containee) -> Teste si un élément est inclus dans un autre. */
	contains: function(container, containee) {
		if(container && containee) {
			var n = containee;
			for(n; n && n != container; n = n.parentNode) {}
			return n;
		}
		return false;
	},

	/** 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 on = function(e) { Ap.ctrlDisplayOn(oMenus, e); };
		var out = function(e) { Ap.ctrlDisplayOut(oMenus, e); };
		Ap.connect(oMenus, 'mouseover', on, false);
		Ap.connect(oMenus, 'mouseout', out, false);
		var aA = Ap.aTag(oMenus, 'a');
		var iI = aA.length;
		if(iI === 0)
			return;
		while(iI-- > 0) {
			Ap.connect(aA[iI], 'focus', on, false);
			Ap.connect(aA[iI], 'blur', out, false);
		}
		return oMenus;
	},

	/** Ap.initStyle(oMenus) -> Définit les styles affectés au menu lorsque JS est actif. */
	initStyle: function(oMenus) {
		if(!oMenus)
			return;
		oMenus.className = Ap['Style'];
		var aUls = Ap.aTag(oMenus, 'ul');
		var iI = aUls.length;
		if(iI === 0)
			return;
		do aUls[--iI].className = Ap['Cache'];
		while(iI > 0)
		return oMenus;
	},

	/** Ap.actif() -> Affecte des liens de contrôle, des styles et un comportement au menu. */
	actif: function() {
		var aUls = Ap.aTag(document, 'ul');
		var iUl = aUls.length;
		do if(aUls[--iUl].className == Ap['Menus']) {
			var oMenus = aUls[iUl];
			if(!oMenus)
				return;
			if(Ap.insertCtrlLinks(oMenus))
				if(Ap.initStyle(oMenus))
					Ap.initCptMenu(oMenus);
		} while(iUl > 0);
		return;
	},

	/** Ap.ctrlDisplayOn(oMenus, e) -> Repère l'élément d'où l'événement a été généré et renvoie une demande d'affichage. */
	ctrlDisplayOn: function(oMenus, e) {
		if(oMenus && e) {
			var oRelatedNode = e.fromElement;
			return Ap.ctrlDisplay(oMenus, e, oRelatedNode, Ap['Montre']);
		}
		return false;
	},

	/** Ap.ctrlDisplayOut(oMenus, e) -> Repère l'élément sur lequel on arrive à la suite d'un événement et renvoie une demande de masquage. */
	ctrlDisplayOut: function(oMenus, e) {
		if(oMenus && e) {
			var oRelatedNode = e.toElement;
			return Ap.ctrlDisplay(oMenus, e, oRelatedNode, Ap['Cache']);
		}
		return false;
	},

	/** Ap.ctrlDisplay(oMenus, e, RelatedNode, css) -> Contrôle l'affichage / masquage des sous-menus. */
	ctrlDisplay: function(oMenus, e, oRelatedNode, css) {
		var oRelatedNode = e.relatedTarget || oRelatedNode;
		var oSource = Ap.getSource(e);
		while(oSource && oSource != oMenus) {
			var oUl = Ap.aTag(oSource, 'ul')[0];
			var oParentSource = oSource.parentNode;
			var iI;
			if(!Ap.contains(oSource, oRelatedNode) && oUl) {
				if(e.type === 'mouseout' || e.type === 'blur')
					oUl.parentNode.firstChild.className = Ap['BT'];
				if(e.type === 'mouseover' || e.type === 'focus')
					oUl.parentNode.firstChild.className = Ap['FT'];
				oUl.className = css;
			}
			if(oSource.nodeName.toLowerCase() === 'a')
				if(e.type === 'focus' || e.type === 'mouseover')
					oSource.className = (oParentSource.parentNode != oMenus)?
						Ap['FL']:
						Ap['FT'];
				else if(e.type === 'blur' || e.type === 'mouseout')
					oSource.className = (oParentSource.parentNode != oMenus)?
						Ap['BL']:
						oSource.className;
			oSource = oParentSource;
		}
		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();
})();