///////////////////////////////////////////////////////////////////////////////////////
//
// Blocs toggle - Gestion de l'affichage de la liste deroulante d'acces aux marques
//                et du formulaire de connexion
//
// Note : Ce script est prevu pour etre portable ; il ne depend d'aucune bibliotheque
//        et peut etre externalise si necessaire.
//
////

// Protection
(function() {
	
	// Extension du prototype de Array si necessaire
	if(typeof Array.prototype.forEach === 'undefined') {
	
		Array.prototype.forEach = function(fn) {
			
			for(var iKey = 0, _iCount = this.length; iKey < _iCount; iKey++) {
			
				fn(this[iKey], iKey, this);
				
			}
			
			return true;
			
		}
		
	}
	
	// Espace de nom
	var CCToggle = window.CCToggle || {};

	// Methode d'initialisation
	CCToggle.init = function(oHashmap) {
		
		CCToggle.addJSStyles(oHashmap);
		CCToggle.addEvent(window, 'load', CCToggle.addBehaviours(oHashmap));

	};

	// Methode d'ajout de styles lie au JS
	CCToggle.addJSStyles = function(oHashmap) {

		var _sHTMLClass = document.documentElement.className;
		var _rJSStylesClass = new RegExp('\\b' + oHashmap['jsStylesClass'] + '\\b');
		
		if(!_rJSStylesClass.test(_sHTMLClass)) {
		
			_sHTMLClass += (_sHTMLClass == '' ? '' : ' ') + oHashmap['jsStylesClass'];
			return true;
			
		}
		
		return false;
		
	};

	// Methode d'ajout de gestionnaire d'evenement
	CCToggle.addEvent = function(oEl, sEvType, fn, bCapture) {
	
		return sEvType.length > 2 && sEvType.slice(0, 2) == 'on' ?
			CCToggle.fns.push([sEvType.slice(2, 3).toLowerCase() + sEvType.slice(3), fn]):
			document.addEventListener ?
				oEl.addEventListener(sEvType, fn, bCapture || false):
				oEl.attachEvent ?
					oEl.attachEvent('on' + sEvType, fn):
					false;

	};
	
	// Tableau de callbacks
	CCToggle.fns = [];
	
	// Methode qui execute le callback associe a l'evenement indique en lui passant des parametres
	CCToggle.fireEvent = function(sEvent, aBinds, iDelay) {
		
		CCToggle.fns.forEach(function(aEvent) {
		
			if(aEvent[0] == sEvent) {
			
				var _aBinds = aEvent[2] || aBinds || [];
				var _fnEvent = aEvent[1];
				
				if(typeof _fnEvent !== 'function') {
				
					throw new Error();
					
				}
				
				iDelay ?
					setTimeout(
						function() {
						
							_fnEvent.apply(null, _aBinds);
							
						},
						iDelay
					):
					_fnEvent.apply(null, _aBinds);
					
			}
			
		});
		
		return this;
		
	};
	
	// Annulation de la propagation d'un evenement et de l'action par defaut d'un element
	CCToggle.stopEvent = 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; // Indispensable pour Safari
		
	};
	
	// Methode recuperant la source d'un evenement
	CCToggle.getSrc = function(e) {
	
		return e.target || e.srcElement;
	
	};
	
	// Methode d'ajout des gestionnaires d'evenements du script
	CCToggle.addBehaviours = function(oHashmap) {
	
		return function(e) {
		
			// Determination des 2 controleurs
			var _oUserBarre = document.getElementById(oHashmap['containerId']);
	
			if(_oUserBarre) {
			
				var _aEls = _oUserBarre.getElementsByTagName(oHashmap['containerCtrlTag']);
				var _rBrands = new RegExp('\\b' + oHashmap['brandsClass'] + '\\b');
				var _rConnectedBrands = new RegExp('\\b' + oHashmap['brandsConnectedClass'] + '\\b');
				var _rConnexion = new RegExp('\\b' + oHashmap['connexionClass'] + '\\b');
				var _rDisconnexion = new RegExp('\\b' + oHashmap['disconnexionClass'] + '\\b');
				
				for(var _iEl = 0, _iCountEls = _aEls.length; _iEl < _iCountEls; _iEl++) {
				
					if(_rBrands.test(_aEls[_iEl].className) || _rConnectedBrands.test(_aEls[_iEl].className)) {
					
						var _oBrandsCtrl = _aEls[_iEl].getElementsByTagName(oHashmap['ctrlTag'])[0];
					
					}
					else if(_rConnexion.test(_aEls[_iEl].className)) {
					
						var _oConnexionCtrl = _aEls[_iEl].getElementsByTagName(oHashmap['ctrlTag'])[0];
					
					}
					else if(_rDisconnexion.test(_aEls[_iEl].className)) {

						var _oDisconnexionCtrl = _aEls[_iEl].getElementsByTagName(oHashmap['ctrlTag'])[0];
					
					}
				
				}
				
			}
			
			// Si les 2 conteneurs existent, on ajoute les gestionnaires d'evenements
			if(_oConnexionCtrl || _oDisconnexionCtrl) {

				// Evenements personnalises
				[
					'hideBrands',
					'showBrands',
					'desactivateBrands',
					'closeBrandsContainer',
					'isConnexionContainerMustBeClose',
					'activateBrands',
					'openBrandsContainer',
					'hideConnexion',
					'showConnexion',
					'desactivateConnexion',
					'closeConnexionContainer',
					'isBrandsContainerMustBeClose',
					'activateConnexion',
					'openConnexionContainer',
					'showPubs',
					'hidePubs',
					'openContainer',
					'closeContainer'
				].forEach(function(sMethod) {
				
					CCToggle.addEvent(CCToggle, 'on' + sMethod.slice(0, 1).toUpperCase() + sMethod.slice(1), CCToggle[sMethod]);
				
				});
				
				// Evenements utilisateurs
				CCToggle.addEvent(document.documentElement, 'click', CCToggle.hideEachContainer(oHashmap));
				if(_oBrandsCtrl) {
					
					CCToggle.addEvent(_oBrandsCtrl, 'click', CCToggle.brandsBridge(oHashmap));
				
				}
				if(_oConnexionCtrl) {

					CCToggle.addEvent(_oConnexionCtrl, 'click', CCToggle.connexionBridge(oHashmap));
					
				}
				
			}
		
		};
		
	};

	// Animation d'ouverture de conteneur
	CCToggle.openContainer = function(oHashmap, oContainer) {
	
		oContainer.style.overflow = 'hidden';
		oContainer.style.height = 0;
		oContainer.style.display = 'block';
		var _iTotalHeight = oContainer.scrollHeight;
		var _iStart = (new Date()).getTime();
		var _iEnd = _iStart + oHashmap['period'];
		
		var _animation = setInterval(
			function() {
			
				var _iCurrent = (new Date()).getTime();
				oContainer.style.height = (_iCurrent - _iStart) * _iTotalHeight / (_iEnd - _iStart) + 'px';
			
			},
			10
		);
		setTimeout(
			function() {
			
				clearInterval(_animation);
				oContainer.style.height = '';
				oContainer.style.overflow = '';
			
			},
			oHashmap['period']
		);
	
	};

	// Animation de fermeture de conteneur
	CCToggle.closeContainer = function(oHashmap, oContainer) {
		
		oContainer.style.overflow = 'hidden';
		var _iTotalHeight = oContainer.scrollHeight;
		var _iStart = (new Date()).getTime();
		var _iEnd = _iStart + oHashmap['period'];
		
		var _animation = setInterval(
			function() {
			
				var _iCurrent = (new Date()).getTime();
				oContainer.style.height = _iTotalHeight - ((_iCurrent - _iStart) * _iTotalHeight / (_iEnd - _iStart)) + 'px';
			
			},
			10
		);
		setTimeout(
			function() {
			
				clearInterval(_animation);
				oContainer.style.display = 'none';
				oContainer.style.height = '';
				oContainer.style.overflow = '';
			
			},
			oHashmap['period']
		);
	
	};
	
	// Gestion du masquage de l'ensemble des conteneurs
	CCToggle.hideEachContainer = function(oHashmap) {
	
		return function(e) {
			
			// Verification de l'affichage des marques
			CCToggle.fireEvent('isBrandsContainerMustBeClose', [oHashmap, CCToggle.getSrc(e)]);
			
			// Verification de l'affichage du formulaire de connexion
			CCToggle.fireEvent('isConnexionContainerMustBeClose', [oHashmap, CCToggle.getSrc(e)]);
			
			// Affichage du conteneur des pubs
			CCToggle.fireEvent('showPubs', [oHashmap, CCToggle.getSrc(e)]);
			
		};
	
	};
	
	// Verifie si un element est contenu dans un autre
	CCToggle.contains = function(oContainer, oContainee) {
	
		if(!oContainer || !oContainee) {
			
			return;
			
		}
		
		for(var _oN = oContainee; _oN && _oN != oContainer; _oN = _oN.parentNode);
		
		return _oN;
		
	};
	
	// Verification de l'affichage du conteneur des marques et masquage le cas echeant
	CCToggle.isBrandsContainerMustBeClose = function(oHashmap, oTarget) {
		
		var _oContainer = document.getElementById(oHashmap['brandsContainerId']);
		
		// Si le conteneur existe, est ouvert et que l'utilisateur n'a pas clique dedans
		if(_oContainer && _oContainer.style.display == 'block' && !CCToggle.contains(_oContainer, oTarget)) {
			
			var _oUserBarre = document.getElementById(oHashmap['containerId']);
	
			if(_oUserBarre) {
			
				var _aEls = _oUserBarre.getElementsByTagName(oHashmap['containerCtrlTag']);
				var _rBrands = new RegExp('\\b' + oHashmap['brandsClass'] + '\\b');
				var _rConnectedBrands = new RegExp('\\b' + oHashmap['brandsConnectedClass'] + '\\b');
				
				for(var _iEl = 0, _iCountEls = _aEls.length; _iEl < _iCountEls; _iEl++) {
				
					if(_rBrands.test(_aEls[_iEl].className) || _rConnectedBrands.test(_aEls[_iEl].className)) {
					
						CCToggle.fireEvent('desactivateBrands', [oHashmap, _aEls[_iEl]]);
					
					}
				
				}
				
				if(arguments[2]) {
				
					_oContainer.style.display = 'none';
					
				}
				else {
				
					CCToggle.fireEvent('closeBrandsContainer', [oHashmap]);
					
				}
				
			}
		
		}
	
	};
	
	// Gestion de l'affichage des marques
	CCToggle.brandsBridge = function(oHashmap) {
	
		return function(e) {

			var _oTarget = CCToggle.getSrc(e);
			var _oParentTarget = _oTarget.parentNode;
			var _rBrands = new RegExp('\\b' + oHashmap['brandsClass'] + '\\b');
			var _rConnectedBrands = new RegExp('\\b' + oHashmap['brandsConnectedClass'] + '\\b');
			var _rActiveBrands = new RegExp('\\b' + oHashmap['activeBrands'] + '\\b');
			var _rActiveConnectedBrands = new RegExp('\\b' + oHashmap['activeConnectedBrands'] + '\\b');
			
			while(_oParentTarget && !(_rBrands.test(_oParentTarget.className) || _rConnectedBrands.test(_oParentTarget.className))) {
			
				_oParentTarget = _oParentTarget.parentNode;
			
			}
			
			// Declenchement d'une action en fonction de l'affichage actuel
			CCToggle.fireEvent(_rActiveBrands.test(_oParentTarget.className) || _rActiveConnectedBrands.test(_oParentTarget.className) ?
				'hideBrands':
				'showBrands',
				[oHashmap, _oTarget, _oParentTarget]
			);
			
			// Annulation de la propagation et de l'action par defaut
			return CCToggle.stopEvent(e);
			
		};
	
	};
	
	// Masquage des marques
	CCToggle.hideBrands = function(oHashmap, oTarget, oParentTarget) {
		
		// Desactivation du controleur
		CCToggle.fireEvent('desactivateBrands', [oHashmap, oParentTarget]);
		
		// Masquage du conteneur
		CCToggle.fireEvent('closeBrandsContainer', [oHashmap]);
		
		// Affichage des pubs
		CCToggle.fireEvent('showPubs', [oHashmap]);
	
	};
	
	// Affichage des marques
	CCToggle.showBrands = function(oHashmap, oTarget, oParentTarget) {
		
		// Verification de l'affichage du formulaire de connexion
		CCToggle.fireEvent('isConnexionContainerMustBeClose', [oHashmap, oTarget, 'directly']);
		
		// Masquage des pubs
		CCToggle.fireEvent('hidePubs', [oHashmap]);
		
		// Activation du controleur
		CCToggle.fireEvent('activateBrands', [oHashmap, oParentTarget]);
		
		// Ouverture du conteneur des marques
		CCToggle.fireEvent('openBrandsContainer', [oHashmap]);
	
	};
	
	// Desactivation du controleur des marques
	CCToggle.desactivateBrands = function(oHashmap, oParentTarget) {
	
		var _rBrandsConnectedClass = new RegExp('\\b' + oHashmap['brandsConnectedClass'] + '\\b');
		oParentTarget.className = oParentTarget.className.replace(' ' + (oHashmap[_rBrandsConnectedClass.test(oParentTarget.className) ? 'activeConnectedBrands' : 'activeBrands']), '');
	
	};
	
	// Activation du controleur des marques
	CCToggle.activateBrands = function(oHashmap, oParentTarget) {
	
		var _rBrandsConnectedClass = new RegExp('\\b' + oHashmap['brandsConnectedClass'] + '\\b');
		oParentTarget.className += ' ' + oHashmap[_rBrandsConnectedClass.test(oParentTarget.className) ? 'activeConnectedBrands' : 'activeBrands'];
	
	};
	
	// Fermeture du conteneur des marques
	CCToggle.closeBrandsContainer = function(oHashmap) {
		
		var _oContainer = document.getElementById(oHashmap['brandsContainerId']);
		
		if(_oContainer) {
		
			CCToggle.fireEvent('closeContainer', [oHashmap, _oContainer]);
		
		}
	
	
	};
	
	// Ouverture du conteneur des marques
	CCToggle.openBrandsContainer = function(oHashmap) {
		
		var _oContainer = document.getElementById(oHashmap['brandsContainerId']);
		
		if(_oContainer) {
		
			CCToggle.fireEvent('openContainer', [oHashmap, _oContainer]);
			
		}
	
	};
	
	// Verification de l'affichage du conteneur du formulaire de connexion et masquage le cas echeant
	CCToggle.isConnexionContainerMustBeClose = function(oHashmap, oTarget) {
		
		var _oContainer = document.getElementById(oHashmap['connexionContainerId']);
		
		// Si le conteneur existe, est ouvert et que l'utilisateur n'a pas clique dedans
		if(_oContainer && _oContainer.style.display == 'block' && !CCToggle.contains(_oContainer, oTarget)) {
		
			var _oUserBarre = document.getElementById(oHashmap['containerId']);
	
			if(_oUserBarre) {
			
				var _aEls = _oUserBarre.getElementsByTagName(oHashmap['containerCtrlTag']);
				var _rConnexion = new RegExp('\\b' + oHashmap['connexionClass'] + '\\b');
				
				for(var _iEl = 0, _iCountEls = _aEls.length; _iEl < _iCountEls; _iEl++) {
				
					if(_rConnexion.test(_aEls[_iEl].className)) {
					
						CCToggle.fireEvent('desactivateConnexion', [oHashmap, _aEls[_iEl]]);
					
					}
				
				}
			
				if(arguments[2]) {
				
					_oContainer.style.display = 'none';
					
				}
				else {
				
					CCToggle.fireEvent('closeConnexionContainer', [oHashmap]);
					
				}
				
			}
		
		}
	
	};
	
	// Gestion de l'affichage du formulaire de connexion
	CCToggle.connexionBridge = function(oHashmap) {
	
		return function(e) {
	
			var _oTarget = CCToggle.getSrc(e);
			var _oParentTarget = _oTarget.parentNode;
			var _rConnexion= new RegExp('\\b' + oHashmap['connexionClass'] + '\\b');
			var _rActiveConnexion = new RegExp('\\b' + oHashmap['activeConnexion'] + '\\b');
			
			while(_oParentTarget && !_rConnexion.test(_oParentTarget.className)) {
			
				_oParentTarget = _oParentTarget.parentNode;
			
			}
			
			// Declenchement d'une action en fonction de l'affichage actuel
			CCToggle.fireEvent(_rActiveConnexion.test(_oParentTarget.className) ?
				'hideConnexion':
				'showConnexion',
				[oHashmap, _oTarget, _oParentTarget]
			);
			
			// Annulation de la propagation et de l'action par defaut
			return CCToggle.stopEvent(e);
			
		};
	
	};
	
	// Masquage du formulaire de connexion
	CCToggle.hideConnexion = function(oHashmap, oTarget, oParentTarget) {
		
		// Desactivation du controleur
		CCToggle.fireEvent('desactivateConnexion', [oHashmap, oParentTarget]);
		
		// Masquage du conteneur
		CCToggle.fireEvent('closeConnexionContainer', [oHashmap]);
		
		// Affichage des pubs
		CCToggle.fireEvent('showPubs', [oHashmap]);
	
	};
	
	// Affichage du formulaire de connexion
	CCToggle.showConnexion = function(oHashmap, oTarget, oParentTarget) {
		
		// Verification de l'affichage des marques
		CCToggle.fireEvent('isBrandsContainerMustBeClose', [oHashmap, oTarget, 'directly']);
		
		// Masquage des pubs
		CCToggle.fireEvent('hidePubs', [oHashmap]);
		
		// Activation du controleur
		CCToggle.fireEvent('activateConnexion', [oHashmap, oParentTarget]);
		
		// Ouverture du conteneur du formulaire de connexion
		CCToggle.fireEvent('openConnexionContainer', [oHashmap]);
	
	};

	// Desactivation du controleur du formulaire de connexion
	CCToggle.desactivateConnexion = function(oHashmap, oParentTarget) {
	
		oParentTarget.className = oParentTarget.className.replace(' ' + oHashmap['activeConnexion'], '');
	
	};
	
	// Activation du controleur du formulaire de connexion
	CCToggle.activateConnexion = function(oHashmap, oParentTarget) {
	
		oParentTarget.className += ' ' + oHashmap['activeConnexion'];
	
	};
	
	// Fermeture du conteneur du formulaire de connexion
	CCToggle.closeConnexionContainer = function(oHashmap) {
		
		var _oContainer = document.getElementById(oHashmap['connexionContainerId']);
		
		if(_oContainer) {
		
			CCToggle.fireEvent('closeContainer', [oHashmap, _oContainer]);
		
		}
	
	};
	
	// Ouverture du conteneur du formulaire de connexion
	CCToggle.openConnexionContainer = function(oHashmap) {
		
		var _oContainer = document.getElementById(oHashmap['connexionContainerId']);
		
		if(_oContainer) {
		
			CCToggle.fireEvent('openContainer', [oHashmap, _oContainer]);
		
		}
	
	};
	
	// Masquage des pubs
	CCToggle.hidePubs = function(oHashmap) {
		
		var _oPubContainer = document.getElementById(oHashmap['pubContainerId']);
		
		if(_oPubContainer) {

			_oPubContainer.style.visibility = 'hidden';
			
		}
	
	};
	
	// Affichage des pubs
	CCToggle.showPubs = function(oHashmap, oSrc) {

		// Si la source n'est pas transmise a la methode showPubs ou si la source se trouve en dehors des deux conteneurs, on affiche la pub
		if(!oSrc || (!CCToggle.contains(document.getElementById(oHashmap['brandsContainerId']), oSrc) && !CCToggle.contains(document.getElementById(oHashmap['connexionContainerId']), oSrc))) {
		
			var _oPubContainer = document.getElementById(oHashmap['pubContainerId']);
			
			if(_oPubContainer) {
			
				_oPubContainer.style.visibility = 'visible';
				
			}
			
		}
	
	};
	
	// Initialisation du script par l'intermediaire d'une hashmap passee en parametre
	CCToggle.init({
		'jsStylesClass': 'hasJS', // Classe des styles lies au JS et appliques des le chargement de la page
		'containerId': 'userBarreContent', // Id du conteneur global
		'containerCtrlTag': 'li', // Tag du conteneur des boutons
		'brandsClass': 'accesMarques', // Classe du conteneur du bouton d'acces aux marques en mode deconnecte
		'brandsConnectedClass': 'accesMarquesConnected', // Classe du conteneur du bouton d'acces aux marques en mode connecte
		'brandsContainerId': 'accesMarques', // Id du conteneur d'acces aux marques
		'connexionClass': 'userconnexion', // Classe du conteneur du bouton de connexion
		'disconnexionClass': 'clubCara_Toolbar_Deconnect', // Classe du conteneur du bouton de deconnexion
		'connexionContainerId': 'authent', // Id du conteneur du formulaire de connexion
		'ctrlTag': 'a', // Tag des boutons
		'activeBrands': 'actifMarques', // Classe d'activation de l'acces aux marques en mode deconnecte
		'activeConnectedBrands': 'actifMarquesConnected', // Classe d'activation de l'acces aux marques en mode connecte
		'activeConnexion': 'actifConnexion', // Classe d'activation du formulaire de connexion
		'period': 250, // Temps d'ouverture/fermeture de chaque conteneur
		'pubContainerId': 'pubTop' // Id du conteneur de pub a afficher/masquer
	});
	
	// Mise a disposition de l'objet CCToggle
	return CCToggle;
	
})();

///////////////////////////////////////////////////////////////////////////////////////
