/* ajout classe hasJS des le chargement du fichier JS, cette classe sert à l'accessibilite et permet de cacher des elements seulement quand le JS existe */
document.documentElement.className += ' hasJS';
/*************************
* classes de fonctions
*************************/
var $n = {
	/* 	$n.hasAttr : retourne true si l'element passe en parametre correspond a tous les attributs passes, on peut aussi donner des attributs que l'on ne veut pas, afin de filtrer tous les elements
		ex : if ($n.hasAttr(div, {nodeName:"div", className:"foobar"), {className:"idontwant"} ) doStuff();
		ici on recherche tous les DIV qui on la classe "foobar", mais on ne prend pas ceux qui ont la classe "idontwant" ex : <div class="foobar idontwant"> ne sera pas recupere.
	*/
	hasAttr : function(n, a, not) {
		if (n.nodeType!=1 && not && this.check(n,not)) return false;
		if (this.check(n,a)) return true;
		return false;
	},
	check:function(n,attr) {
		for (var i in attr) {
			if (!attr[i].test(n[i]))
				return false;
		}
		return true;
	},
	setAttr : function(attr) {
		for (var i in attr) {
			attr[i] = (typeof (attr[i])=='string') ?  new RegExp("\\b" + attr[i] + "\\b") : attr[i];
		}
		return attr;
	},
	/* getByTagName : equivalent a element.getElementsByTagName, mais compatible avec IE5 et IE5.5 pour l'histoire du "*" */
	getByTagName : function(n, tag) {
		return  (tag=="*" && n.all) ? n.all : n.getElementsByTagName(tag);
	},
	/* fonction qui retourne le premier element correspondant aux attributs donnes */
	node : function(n, a, not) {
		return this.nodes(n, a, not, true);
	},
	/* fonction qui retourne tous les elements correspondant selon "a" */
	nodes : function(n, a, not, oneNode, arrElms) {
		var aRetElms=[];
		if (!a) a = {};
		if (typeof a == "string") a = {nodeName:a}; //si une chaine de caracteres passee en parametre, cela signifie qu'on ne veut que recuperer des tags
		if (a.nodeName && a.nodeName=="*") delete a.nodeName;
		if (a.nodeName instanceof RegExp) {
			var elms = this.getByTagName(n, "*");
		} else {
			var elms = arrElms || this.getByTagName(n, (a.nodeName || "*"));
		}
		if (elms.length>0) delete a.nodeName;
		a=this.setAttr(a); not=this.setAttr(not);
		for (var i=0; i<elms.length; i++) {
			var x = elms[i];
			if (this.hasAttr(x, a, not)) {
				if (oneNode) return x;
				else aRetElms.push(x);
			}
		}
		if (oneNode) return null;
		return aRetElms;
	},
	/* childs : retourne tous les noeuds enfants de l'element  */
	childs : function(n, a, not) {
		return this.nodes(n, a, not, false, n.childNodes);
	},
	firstChild : function(n, a, not) {
		return this.nodes(n, a, not, true, n.childNodes);
	},
	lastChild : function(n, a, not) {
		var node = this.nodes(n, a, not, false, n.childNodes);
		return node[node.length-1];
	},
	move : function(n, a, not, action) {
		a=this.setAttr(a); not=this.setAttr(not);
		do {
			n = n[action];
		} while(!this.hasAttr(n, a, not));
		return n;
	},
	previous : function(n, a, not) {
		return this.move(n, a, not, "previousSibling");
	},
	next : function(n, a, not) {
		return this.move(n, a, not, "nextSibling");
	},
	parent : function(n, a, not) {
		return this.move(n, a, not, "parentNode");
	}

}

if (!window.$extend) {
	function $extend(original, extended){
		for (var key in (extended || {})) original[key] = extended[key];
		return original;
	};
}

function $protoTypeExtend(original, extended){
	for (var key in (extended || {})) {
		if (!original[key]) original[key] = extended[key];
	}
	return original;
};

/* Array extend */
$protoTypeExtend(Array.prototype, {
	forEach : function(fun) {
		var len = this.length;
		if (typeof fun != "function") throw new TypeError();
		var thisp = arguments[1];
		for (var i = 0; i<len; i++) {
			if (i in this)
				fun.call(thisp, this[i], i, this);
		}
	},
	each : function(fun) {
		this.forEach.call(this, fun);
	}
});

/* String Extends */
$protoTypeExtend(String.prototype, {
	trim : function() { return this.replace(/^\s+|\s+$/g, '')}
});

/************************
* Framework
*************************/
var FW  = {};


/* browser : objet browser contenant des booleens propres aux navigateurs, tous ne sont pas integres car pas utiles en temps normal
	@use: if (FW.browser.ie) // msie
*/
FW.browser = {
	ie : (document.all && window.print && !window.opera) || false,
	opera : window.opera  || false
};
FW.browser.ie6 = (FW.browser.ie && /MSIE [56]/.test(navigator.userAgent))  || false;
FW.browser.ieQuirks = (FW.browser.ie6 && document.compatMode && document.compatMode=="BackCompat")  || false;


/* globales : quelques variables globales utilisees */
FW.heightStyle = FW.browser.ieQuirks || FW.browser.ie6 ? 'height' : 'minHeight';


/* decorations */
FW.decoration = function(name, attributes, firstChilds, lastChilds) {
	//if (attributes.nodeName) FW.initializer.addNodeName(attributes.nodeName);
	firstChilds = FW.strToNodes(firstChilds);
	lastChilds = FW.strToNodes(lastChilds);
	FW.Module(
		'decoration_'+ name,
		attributes,
		{
			initialize : function(elm) {
				FW.createDecorations(elm,  firstChilds, lastChilds);
			}
		}
	)
}
FW.createDecorations = function(element, firstChilds, lastChilds) {
	for (var i=lastChilds.length-1; i>=0; i--) {
		element.appendChild(lastChilds[i].cloneNode(true));
	}
	for (var i=0; i<firstChilds.length; i++) {
		if (!element.firstChild) {
			element.appendChild(firstChilds[i].cloneNode(true));
		} else 
			element.insertBefore(firstChilds[i].cloneNode(true), element.firstChild);
	}
}
FW.strToNodes = function(str) {
	if (!str) return [];
	var div = document.createElement('div');
	div.innerHTML = str;
	var returns = [];
	while(div.firstChild)
		returns.push(div.removeChild(div.firstChild));
	return returns;
}
FW.initAttributes = function(attr) {
	for (var i in attr) 
		attr[i] = (typeof (attr[i])=='string') ?  new RegExp("\\b(" + attr[i].replace(/,/g,'|') + ")\\b") : attr[i];
	return attr;
}

/* Modules : gestion des modules du framework */
FW.modules = [];
FW.Module = function(moduleName,attributes, modProto) {
	if (attributes.nodeName) FW.initializer.addNodeName(attributes.nodeName);
	try {delete attributes.nodeName} catch(e){attributes.nodeName=null} //suppression du nodeName qui devient inutile a checker
	attributes = FW.initAttributes(attributes);
	var ModuleObj = function() {
		this.initialize.apply(this, arguments);
	};
	ModuleObj.prototype = modProto;
	FW.modules.push({
		name : moduleName,
		attributes : attributes,
		moduleObject : ModuleObj
	})
}
FW.initializer = {
	nodeNames : [],
	launch : function(parent) {
		parent = parent || document.body;
		for (var i=0; i<this.nodeNames.length; i++) {
			var nodes = parent.getElementsByTagName(this.nodeNames[i]);
			for (var j=0; j<nodes.length; j++) {
				for (var m=0; m<FW.modules.length; m++) {
					if (this.check(nodes[j], FW.modules[m].attributes)) {
						new FW.modules[m].moduleObject(nodes[j]);
					}
				}
			}
		}
	},
	addNodeName : function(nodeName) {
		if (nodeName=='*') return;
		nodeName = nodeName.toLowerCase();
		for (var i=0; i<this.nodeNames.length; i++) {
			if (this.nodeNames[i]==nodeName)
				return;
		}
		this.nodeNames.push(nodeName);
	},
	check:function(n,attr) {
		for (var i in attr) {
			if (attr[i].test(n[i]))
				return true;
		}
		return false;
	}
}

/* FW.$ : Equivalent du $ des library en general, mais celui retourne un objet avec l'element associe 
  cela permet de ne pas etendre l'element et de ne pas rentrer en conflit avec d'autre libs
  
*/
FW.$ = function() {
	var aArgs = arguments;
	if(aArgs.length > 1 && typeof aArgs[1] == 'string') {
		return new FW.Wrap(typeof aArgs[0] == 'string' ?
			document.getElementById(aArgs[0]).getElementsByTagName(aArgs[1]):
			aArgs[0].getElementsByTagName(aArgs[1])
		);
	}
	else switch(typeof aArgs[0]) {
		case 'string':
			return new FW.Wrap(document.getElementById(aArgs[0]));
		case 'object':
			return new FW.Wrap(aArgs[0]);
	}
	return false;
}


/* FW.Wrap : objet associe a un DOM Element, surlequel toutes les methodes s'appliquement sur l'element associe et retourneront ce wrapper
  ex : FW.$(elm).addClass('pouet').addEvent('click', function() {}).removeClass('pouet');
*/
FW.Wrap = function(el) {
	this.el = el;
}
FW.Wrap.prototype = {
	/* === className functions ===  */
	removeClass: function(sClass) {
		var rep = this.el.className.match(' ' + sClass) ? ' ' + sClass : sClass;
		this.el.className = this.el.className.replace(rep, '');
		return this;
	},
	addClass: function(sClass) {
		if(!this.hasClass(sClass))
			this.el.className += this.el.className ? ' ' + sClass : sClass;
		return this;
	},
	swapClass: function(sClass1, sClass2) {
		this.el.className = this.hasClass(sClass1) ?
			this.el.className.replace(sClass1, sClass2):
			this.el.className.replace(sClass2, sClass1);
		return this;
	},
	toggleClass: function(sClass) {
		this.hasClass(sClass) ? this.removeClass(sClass) : this.addClass(sClass);
		return this;
	},
	hasClass: function(sClass) {
		return typeof sClass == 'string' ?
			new RegExp('\\b' + sClass + '\\b').test(this.el.className):
			sClass.test(this.el.className);
	},
	
	/* === events Functions ===  */
	addEvent: function(evType, func, bCapture) {
		if(evType == 'domready' && this.el==window)
			FW.event.domready(func);
		document.addEventListener ?
			this.el.addEventListener(evType, func, bCapture || false):
			this.el.attachEvent ?
				this.el.attachEvent('on' + evType, func):
				false;
		return this;
	},
	// Suppression d'un gestionnaire d'evenement sur un element pour un evenement donne
	removeEvent: function(sEvType, fn, bCapture) {
		document.addEventListener ?
			this.el.removeEventListener(sEvType, fn, bCapture || false):
			this.el.detachEvent ?
				this.el.detachEvent('on' + sEvType, fn):
				false;
		return this;
	},
	
	/* === dom functions ===  */
	getElement:function(attr, not) {
		var el = $n.node(this.el, attr, not);
		return el ? new FW.Wrap(el) : null;
	},
	getElements:function(attr, not) {
		var els = $n.nodes(this.el, attr, not);
		return els;
	},
	getParent : function(attr, not) {
		var el = $n.parent(this.el, attr, not);
		return el ? new FW.Wrap(el) : null;
	},
	getNext : function(attr,not) {
		var el = $n.next(this.el, attr, not);
		return el ? new FW.Wrap(el) : null;
	},
	
	/* styles CSS functions */
	getStyle: function(strCssRule) {
		var oElm = this.el;
		var strValue = "";
		if(document.defaultView && document.defaultView.getComputedStyle) {
			try{
				strValue = document.defaultView.getComputedStyle(oElm, null).getPropertyValue(strCssRule);
			}
			catch(e) { strValue = ""; }
		}
		else if(oElm.currentStyle) {
			try{
				strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
					return p1.toUpperCase();
				});
				strValue = oElm.currentStyle[strCssRule];
			} catch(e) {
				strValue = "";
			}
		}
		return strValue;
	},
	
	getIntStyle: function(strCSSRule) {
		var val = parseInt(this.getStyle(strCSSRule));
		if (isNaN(val)) val=0;
		return val;
	},
	getVStyle: function(elm) {
		return FW.browser.ieQuirks ?
			0 :
			this.getIntStyle("padding-top") + this.getIntStyle("padding-bottom") +
			this.getIntStyle("border-top-width") + this.getIntStyle("border-bottom-width");
	},
	// Retourne la somme de tous les styles horizontaux appliques (border-width+padding)
	getHStyle: function(elm) {
		return FW.browser.ieQuirks ?
			0 :
			this.getIntStyle("padding-left") + this.getIntStyle("padding-right") +
			this.getIntStyle("border-left-width") + this.getIntStyle("border-right-width");
	},
	
	getPosition : function(overflown) {
		var obj = this.el;
		var curleft = 0,
			 curtop = 0;
		if (obj.offsetParent) {
			do {
				curleft += obj.offsetLeft + (overflown ? -obj.scrollLeft : 0) ;
				curtop += obj.offsetTop + (overflown ? -obj.scrollTop : 0) ;
			} while (obj = obj.offsetParent);
			return {x:curleft,y:curtop};
		}
	}
}

/* FW.event : extendeur de l'objet event. Dans un premier temps ce ne seront que des fonctions liées aux events */
FW.event = {
	domready: function(fn) {
		// Internet Explorer 
		if(window.attachEvent) {
			document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
			document.getElementById('ieScriptLoad').onreadystatechange = function() {
				if(this.readyState == 'complete')
					FW.event.init(fn);
			};
		}
		// Mozilla/Opera 9 
		if(document.addEventListener)
			document.addEventListener('DOMContentLoaded', function() { FW.event.init(fn); }, false);
		// Safari 
		if(navigator.userAgent.search(/WebKit/i) != -1){
		    FW.event.loadTimer = setInterval(function (){
				if(document.readyState.search(/loaded|complete/i) != -1)
					FW.event.init(fn);
			}, 10);
		}
		// Other web browsers
		FW.$(window).addEvent('load', function() { FW.event.init(fn); });
	},
	
	// Initialise le script
	init: function(fn) {
		if (arguments.callee.done) return;
		arguments.callee.done = true;
		if (FW.event.loadTimer) clearInterval(FW.event.loadTimer);
			fn();
	},
	
	// Annulation de la propagation d'un evenement et de l'action par defaut d'un element
	stop: 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
	},
	// Retourne la source de l'evenement
	getSrc: function(e) {
		return e.target || e.srcElement;
	},
	relSrc: function(e) {
		switch(e.type) {
			case 'mouseover': // Retourne l'element survole precedent l'element source de l'evenement
				return e.relatedTarget || e.fromElement;
			case 'mouseout': // Retourne l'element survole suivant l'element source de l'evenement
				return e.relatedTarget || e.toElement;
		}
	}
}


/**********************
 Modules declarations
**********************/
/* module : resize des blocks */
FW.resize = function(parentBlock, smoothResize) { //smoothResize is a boolean for only resizing blocks that are alone in a unit beceause while loading if resize is made on a lot of blocks it's not good
	smoothResize = smoothResize===true ? smoothResize : false; //forcer cet variable a etre clairement un booleen (pour gerer les pb via les addEvent)
	function last(array) {
		return array[array.length-1];
	}
	function size(block, size){
		if (size<=0) return;
		if (block){
			var body = block.className.match(/\bblock\b/) ? $n.node(block, {nodeName: "div", className: "body"}) : block; //si on a une line ou bien un block
			if (body) body.style[FW.heightStyle] = body.offsetHeight + size - FW.$(body).getVStyle() + "px";
		}
	};
	var arrayLines = FW.resize.lines;
	if (parentBlock && parentBlock.nodeType && parentBlock.nodeType==1) {
		arrayLines = $n.nodes(parentBlock, {nodeName: 'ul', className: "line"});
		arrayLines = arrayLines.concat($n.nodes(parentBlock, {nodeName: 'div', className: "line"}));
	}
	for (var i=arrayLines.length-1; i>=0; i--) {
		var line = arrayLines[i];
		var units = $n.childs(line, {className: /\b(last)?unit\b/}, {className: "noresize"});
		//remove the Bspace classe on last block of each unit
		units.each(function(unit) {
			var last = $n.lastChild(unit, {className: "(block|line)"});
			if (last) last.className = last.className.replace(/Bspace/g, '');
		});
		units.each(function(unit) {
			var blocks = $n.childs(unit, {className: "(block|line)"}, {className: "noresize"});
			unit.blocks = blocks;
			var sizeToApply = line.clientHeight-unit.clientHeight;
			var sizePerBlock = parseInt(sizeToApply/blocks.length);
			if (blocks.length > 1 &&  smoothResize) return;
			blocks.each(function(block) {
				size(block, sizePerBlock);
			});
			//sur une division on tombe parfois sur un calcul pas precis, on resize le dernier element d'un unit, afin que le calcul soit correct
			if (blocks.length > 1) size(last(blocks), line.clientHeight-unit.clientHeight);
		});
	}
}
FW.resize.lines = [];
FW.Module('blocksResize',{nodeName:'div', className:'line'},{initialize : function(line) {FW.resize.lines.push(line);}});
FW.$(window).addEvent('load', FW.resize);


/* module swapContent */
FW.Module(
	'swapContent', 
	{nodeName:'a', className:'swapContent' },  
	{
		initialize : function(button) {
			var _self = this;
			this.button = button;
			FW.$(button).addEvent('click', function(e) {
				FW.event.stop(e);
				_self.swap();
			});
		},
		swap : function() {
			var contenu = FW.$(this.button).getNext({className:'contentSwapped'});
			contenu.toggleClass('contentSwappedOpen');
			FW.$(this.button).toggleClass('swapContentOpen');
		}
	}
);

FW.Module(
	'blockToggle', 
	{nodeName:'div', className:'blockToggle' },  
	{
		initialize : function(block) {
			var _self = this;
			this.block = block;
			FW.$(block).getElement({className:'head'})
								.getElement({nodeName:'a'})
								.addEvent('click', function(e) {
									FW.event.stop(e);
									_self.toggle();
								});
		},
		toggle : function() {
			FW.$(this.block).toggleClass('blockToggleClosed');
		}
	}
);

FW.Module(
	'openAssociate', 
	{nodeName:'input', className:/openAssociate/},  
	{
		initialize : function(elm) {
			var _self = this;
			this.elm = elm;
			if (_self.elm.className.match(/\bopenAssociate_(.*)\b/))
				this.block = FW.$(RegExp.$1);
			
			FW.$(this.elm).addEvent('click', function(e) {
				_self.check();
			})
			_self.check();
		},
		check : function(){
			this.elm.checked ? this.block.removeClass('hidden') : this.block.addClass('hidden');
		}
	}
);

FW.Module(
	'arrayHoverLine',
	{nodeName:'tr', className:'arrayHoverLine'},
	{
		initialize : function(elm) {
			FW.$(elm).addEvent('mouseover', function() {
				FW.$(elm).addClass('hover');
			})
			.addEvent('mouseout', function() {
				FW.$(elm).removeClass('hover');
			});
		}
	}
);

FW.Module(
	'tipBox', 
	{nodeName:'a', className:'helper'},  
	{
		initialize : function(elm) {
			var $ = FW.$;
			this.timeout = 10;
			var _self = this;
			this.clone = null;
			this.elm = elm;
			this.box = $(this.elm.rel);
			$(this.elm).addEvent('mouseover', function(e) {
				_self.showBox();
			})
			$(this.elm).addEvent('mouseout', function(e) {
				_self.hideBox();
			})
			
		},
		updateBoxPosition : function(){
			var pos = FW.$(this.elm).getPosition();
			this.clone.style.left = pos.x + 36 + 'px';
			this.clone.style.top = pos.y + 0 + 'px';
		},
		showBox : function(){
			if (this.clone) return;
		
			this.cloneBox();
			this.clone.style.display = 'block';
			
			var _self = this;
			FW.$(this.clone).addEvent('mouseover', function(e) {
				clearTimeout(_self.timerHide);
			});
			FW.$(this.clone).addEvent('mouseout', function(e) {
				_self.hideBox();
			});
		},
		hideBox : function(){
			var _self = this;
			this.timerHide = setTimeout(function() {
				_self .trashClone();
			}, this.timeout);
		},
		cloneBox : function(){
			this.clone = this.box.el.cloneNode(true);
			FW.$('page').el.appendChild(this.clone);
			this.clone.appendChild(document.createElement('span'));
			this.updateBoxPosition();
		},
		trashClone : function(){
			if (!this.clone) return;
			this.clone.parentNode.removeChild(this.clone);
			this.clone = null;
		}
	}
);

/* actionLine : module qui s'applique seulement à une ligne seule */



FW.Module(
	'actionLine', 
	{nodeName:'tr', className:'actionLine' },  
	{
		initialize : function(block) {
			var _self = this;
			this.block = block;
			
			this.actionInput = new ActionInput(FW.$(block).getElement({nodeName:'input'}).el, this.block);
			this.actionInput.checkState();
		}
	}
);

FW.Module(
	'actionGroup', 
	{nodeName:'div', className:'actionFormGroup' },  
	{
		initialize : function(block) {
			var _self = this;
			this.block = block;
				
			this.actionInputs = [];
			FW.$(block).getElements({nodeName:'tr'}).each(function(tr) {
				var input = FW.$(tr).getElement({nodeName:'input'});
				var actionInput = new ActionInput(input.el, tr);
				input.addEvent('click', function() {
					_self.checkOthers();
				})
				_self.actionInputs.push(actionInput);
				actionInput.checkState();
			})
		},
		
		checkOthers : function() {
			this.actionInputs.each(function(actionInput) {
				actionInput.checkState();
			})
		}
		
	}
);

/* switchForfait */
FW.Module(
	'switchForfait', 
	{nodeName:'ul', className:/switchForfait/},  
	{
		initialize : function(elm) {
			var _self = this;
			this.current = null;
			
			FW.$(elm).getElements({nodeName:'li'}).each(function(li) {
				var _this = li;
				FW.$(li).addEvent('click', function(e){
					var label = FW.$(_this).getElement({ nodeName : "label" });
					if(_self.current)
					{
						FW.$(_self.current).removeClass('active');
					}
					FW.$(_this).addClass('active');
					_self.current = _this;
				});
			});	
		}
	}
);


/* switchForfaitCheckbox */
FW.Module(
	'switchForfaitCheckbox', 
	{nodeName:'div', className:/listForfaits/},  
	{
		initialize : function(elm) {
			var _self = this;
			this.current = null;
			
			FW.$(elm).getElements({nodeName:'input', className : /checkbox/}).each(function(input) {
				var _this = input;
				FW.$(input).addEvent('click', function(e){
					if(_self.current)
					{
						FW.$(_self.current).removeClass('active');
					}
					FW.$(input).addClass('active');
					_self.current = _this;
				});
			});	
			
			FW.$(elm).getElements({nodeName:'input', className : /submit/}).each(function(input) {
				var _this = input;
				
				FW.$(input).addEvent('click', function(e){
					if(e.preventDefault) e.preventDefault();
					else event.returnValue = false;
					if(_self.current)
					{
						location.href = _self.current.value;
					}
				});
			});
		}
	}
);







/***************
* Objects used
*****************/
var ActionInput = function(input, blockAction) {
	var _self = this;
	this.block = blockAction;
	this.actionInput = input;
	FW.$(this.actionInput).addEvent('click', function(e){
		_self.checkState()	
	});
	
	this.checkState = function(){
	    if (this.actionInput.type != "hidden") {
		    this.actionInput.checked ? FW.$(this.block).getElement({className:'field'}).removeClass('disable') : FW.$(this.block).getElement({className:'field'}).addClass('disable')
		    this.toggleInputState(this.actionInput.checked);
		}
	};
	
	this.toggleInputState = function(state){
		var disabled = state ? "" : "disabled";
		var formNodenames = ["input","textarea","select"];
		for (var i=0; i<formNodenames.length; i++) {
			var nodeList = this.block.getElementsByTagName(formNodenames[i]);
			for (var j=0 ; j<nodeList.length;j++){
				var elm = nodeList[j];
				if (elm != this.actionInput){
                    elm.disabled = disabled;
				}
			}
		}
	}
}


var $layer = {
	options : {
		id : 'insidePopup',
		templateHTML : [
			'<span class="layerTopCorners"><span></span></span>',
				'<div class="insidePopupContent">',
					'<a href="#" class="close popupCloseButton">__CLOSINGWORDING__</a>',
					'<div>',
						'__CONTENT__',
					'</div>',
				'</div>',
			'<span class="layerBottomCorners"><span></span></span>'
		].join(''),
		styles : {
			width: '700px'
		},
		position: 'center', // pour l'instant il ne prend que center et sera developpé plus tard pour prendre les valeurs left/right/center et top/bottom/center avec les combo 'left top', 'right top' etc, etc 
		mask : false, //mask sous le  layer
		maskPosition : null, // element HTML sur lequel le mask s'appliquera, si null, le parent le plus haut sera pris (<body>)
		maskClickClose : true, // click sur le mask ferme le layer
		content : '', //code HTML pour remplir le layer,
		contentFrom : null, //element contenant du code HTML pour l'afficher dedans
		parent : null, //le parent du layer, par defaut c'est document.body
		fixLayerOnParent : false, // si on veut placer le layer au dessus d'un élément, on peut spécifier si on met le position:relative ou pas
		className : "", //une classe CSS posée sur la popup afin de customiser la popup si nécessaire
		timerInterval : 100,
		offsetTop : 10,
		offsetLeft : 10,
		closingWording : ''
		
	},
	currentOptions : {},
	resetOptions : function() {this.currentOptions = {}; $extend(this.currentOptions, this.options);},	
	lastPositions : {},
	open : function(options) {
		var _self = this;
		this.close();
		this.resetOptions();
		if (options.styles && options.styles.opacity!=null) options.styles.filter = 'alpha(opacity='+options.styles.opacity*100+')'; // compatible IE
		if (options.contentFrom!=null) {
			options.contentFrom = FW.$(options.contentFrom).el;
			options.content = options.contentFrom.innerHTML
		}
		
		for (var i in options) {
			if (i!='styles') this.currentOptions[i] = options[i];
		}
		if (options.styles)
			for (var i in options.styles) {
				this.currentOptions.styles[i] = options.styles[i];
			}
		
		this.options.lastScrollTop = this.options.offsetTop;
		this.options.lastScrollLeft = this.options.offsetLeft;
		
		if (!FW.$(this.currentOptions.id).el)  this.createLayer();
		if (this.currentOptions.mask)  this.createMask();
		this.layer.innerHTML = this.layer.innerHTML.replace(/__CONTENT__/g, this.currentOptions.content).replace(/__CLOSINGWORDING__/, this.currentOptions.closingWording);
		this.correctIE(this.layer);
		this.initActionsButtonsOnLayer();
		
		this.layer.style.width = this.layer.clientWidth - FW.$(this.layer).getHStyle() + 'px';
		this.setSize();
		this.setPosition();
		this.timerRefresh = setInterval(function() {
			_self.refreshSizeAndPosition()
		},this.options.timerInterval)
		this.lastPositions = {
			scrollLeft : document.documentElement.scrollLeft,
			scrollTop : document.documentElement.scrollTop
		}
		this.refreshSizeAndPosition();
		this.layer.style.visibility = 'visible';
		
		
	},
	close : function() {
		if (this.timerRefresh) clearInterval(this.timerRefresh);
		var elmW = FW.$(this.currentOptions.id);
		if (elmW.el) {
			elmW.el.parentNode.removeChild(elmW.el);
		}
		if (this.currentOptions.parent) 
			this.currentOptions.parent.style.height  = '';
		if (this.mask){
			if (this.mask.$layerIframe) 
				this.mask.$layerIframe.parentNode.removeChild(this.mask.$layerIframe);
			this.mask.parentNode.removeChild(this.mask);
		}
		try {
			delete this.layer;
			delete this.content;
			delete this.mask;
		} catch(e) {}
		if (typeof window.CollectGarbage == 'function') {
		  CollectGarbage();
		}
	},
	createLayer : function() { 
		var layer = document.createElement('div');
		layer.className += ' '+this.currentOptions.className || "";
		layer.id = this.currentOptions.id;
		$extend(layer.style, this.currentOptions.styles);
		$extend(layer.style, {left:0, top:0, display:'block', visibility:'hidden'});
		layer.innerHTML = this.currentOptions.templateHTML;
		if (this.currentOptions.over) {
			this.currentOptions.parent.appendChild(layer);
			if (this.currentOptions.fixLayerOnParent) {
				this.currentOptions.parent.style.position = 'relative';
			} else 
				this.currentOptions.position = 'byElement';
		} else 
			document.body.appendChild(layer);
		this.layer = layer;
		FW.$(this.layer).addEvent('click', function(e) {FW.event.stop(e);});
		this.layerContent = FW.$(layer).getElement({nodeName:'div', className:'insidePopupContent'}).el;
		return this.layer;
	},
	createMask : function() {
		var mask  = document.createElement('div');
		this.mask = mask;
		mask.id = 'insidePopupMask';
		this.correctIE(mask);
		
		document.body.appendChild(mask);
		if (this.options.maskClickClose) {
			FW.$(mask).addEvent('click', function(e) {
				FW.event.stop(e);
				$layer.close();
			})
		}
	},
	setPosition : function() {
		var styles = {};
		var currStyles = this.currentOptions.styles;
		switch(this.currentOptions.position) {
			case 'center' : 
				var isWebkit = /webkit/i.test(navigator.userAgent);
				if (isWebkit) {
					this.layer.style.position = 'fixed';
				}
				var parentToUse = window.opera ? document.body : document.documentElement;
				var top = (parentToUse.clientHeight-this.layer.offsetHeight)/2+document.documentElement.scrollTop;
				var left = (parentToUse.clientWidth-this.layer.offsetWidth)/2+document.documentElement.scrollLeft;
				
				if (this.layer.offsetHeight>parentToUse.clientHeight) {
					if (isWebkit) {
						this.layer.style.position = 'absolute';
						top = document.body.scrollTop + this.options.offsetTop;
					}else {
						top = (this.lastPositions.scrollTop || 0) + this.options.offsetTop;
					}
				}
				else 
					this.lastPositions.scrollTop = document.documentElement.scrollTop;
				if (this.layer.offsetWidth>parentToUse.clientWidth)
					left = (this.lastPositions.scrollLeft || 0) + this.options.offsetLeft;
				else 
					this.lastPositions.scrollLeft = document.documentElement.scrollLeft
				styles = {
					left : left+'px',
					top : top+'px'
				};
				break;
			case 'user' :
				styles = {
					left : currStyles.left,
					top : currStyles.top
				}
				break;
			case 'byElement' : 	
				styles = {
					left : this.currentOptions.over.offsetLeft+'px',
					top : this.currentOptions.over.offsetTop+'px'
				};
				break;
			default : 
				break;
		}
		$extend(this.layer.style, styles);
	},
	setSize : function() {
		if (!isNaN(parseInt(this.currentOptions.styles.height))) {
			this.layer.style.height = 'auto';
			var inside = FW.$(this.layer).getElement({nodeName:'div', className:'insidePopupContent'}).el;
			if (this.currentOptions.parent && inside && FW.$(inside).getStyle('position')!='absolute' && inside.offsetHeight > this.currentOptions.parent.offsetHeight) {
				this.currentOptions.parent.style.height = this.layer.offsetHeight+'px';
			} 
			if (this.layer.offsetHeight<parseInt(this.currentOptions.styles.height))
				this.layer.style.height = parseInt(this.currentOptions.styles.height)-FW.$(this.layer).getVStyle(this.layer)+'px';
		}
	},
	refreshSizeAndPosition : function() {
		var parentToUse = window.opera ? document.body : document.documentElement;
		if (
			(this.mask && this.mask.offsetHeight<this.layer.offsetHeight) ||
			this.lastPositions.layerHeight != this.layer.offsetHeight || 
			this.lastPositions.width != parentToUse.clientWidth ||  
			this.lastPositions.height != parentToUse.clientHeight || 
			this.lastPositions.scrollLeft != document.documentElement.scrollLeft || 
			this.lastPositions.scrollTop != document.documentElement.scrollTop
		) {
			this.setPosition();
			if (this.mask && (this.lastPositions.width != document.documentElement.clientWidth || this.lastPositions.height != document.documentElement.clientHeight)) {
				var height =(document.body.clientHeight < document.documentElement.clientHeight ? 
								document.documentElement.clientHeight : 
									(document.body.scrollHeight>document.documentElement.scrollHeight ? 
										document.body.scrollHeight : document.documentElement.scrollHeight
									)
							)
				if(!height) height = document.documentElement.scrollHeight;
				$extend(this.mask.style, {
					height : height+'px',
					width : document.documentElement.scrollWidth > document.documentElement.clientWidth ? document.documentElement.scrollWidth+'px' : "100%"
				});
			}	
			this.lastPositions.layerHeight = this.layer.offsetHeight;
			this.lastPositions.width = parentToUse.clientWidth;
			this.lastPositions.height = parentToUse.clientHeight;
			
			this.correctIE(this.layer);
			this.correctIE(this.mask);
			
		}
	},
	initActionsButtonsOnLayer : function() {
		var closeButtons = FW.$(this.layer).getElements({className:'(close|insidePopupCloseButton)'});
		closeButtons.each(function(btn) {
			btn.onclick = function() {
				$layer.close();
				return false;
			}
		})
	},
	correctIE : function(element) {
		if(!element) return;
		if (!element.$layerIframe && FW.browser.ie6) {
			var ifr = document.createElement('<iframe style="filter:alpha(opacity=0);width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1;">');
			element.$layerIframe = (this.options.maskClickClose && element==this.mask ? document.body : element).appendChild(ifr);
			if (element==this.mask)
				element.$layerIframe.style.zIndex = 1;
		}
		if (element.$layerIframe)
			element.$layerIframe.style.height = element.offsetHeight+'px';
	

	}
}



/**********************
 decorations declarations
**********************/
FW.decoration('corners', 
	{nodeName:'div', className:'blockSimple,blockPhone,blockPromo'},
	'<span class="topCorners"><span class="tl"></span><span class="tr"></span></span>',
	'<span class="bottomCorners"><span class="bl"></span><span class="br"></span></span>'
);
FW.decoration('sides', 
	{nodeName:'div', className:'blockGlobalPrice'},
	'<span class="sideL"></span><span class="sideR"></span><span class="sideT"><span class="cornerRight"></span></span>',
	'<span class="sideB"><span class="cornerRight"></span></span>'
);


FW.$(window).addEvent('domready', function() {
	FW.initializer.launch();
})



/***************
custom functions
***************/
function selectLegend(select){
	for (var i=0; i<select.options.length;i++){
		var el = select.options[i].value;
		if (FW.$(el).el) FW.$(el).el.style.display = 'none';
	}
	var selected = select.options[select.selectedIndex].value;
	if (FW.$(selected).el) FW.$(selected).el.style.display = 'block';
}


function openFlashTVCamp() {
	$layer.open({
		content : '<div id="flashContainerLayer"></div>',
		mask : true
	});
/*	var so = new SWFObject('flashurl', 'flahsId', width, height, "8");
	so.write('flashContainerLayer');
*/

/* pour les tests */
	document.getElementById('flashContainerLayer').innerHTML = 'Ceci est le contenu du layer qui sera remplac&eacute; par le flash, attention le code de ceci doit etre supprim&eacute; <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />';
}





function pngFix(elm, noOverflow) {
	elm.style.filter = ' ';
	if (!(document.all && window.print && /MSIE [56]/.test(navigator.userAgent))) return;
	var exec = (function(elm, noOverflow, scale) {
		return function() {
			
		
			var options = { noOverflow:noOverflow};
			var repeat = elm.currentStyle.backgroundRepeat.toLowerCase()=='repeat';
			elm.style.filter = ' ';
				// si l'élément est un tag img, on va en faire creer une balise qui encadrera cette image et ensuite traiter la balise comme si c'etait un élément qui avait une image de fond
				if (elm.nodeName.match(/^(IMG|INPUT)$/)) {
					if (!elm.src.match(/.*\.png$/)) return;
					
					elm.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='image', src='"+ elm.src + "')";
					
					elm.width = elm.offsetWidth;
					elm.height = elm.offsetHeight;
					
					/* recuperation de l'url du pixel transparent */
					var url = elm.currentStyle.backgroundImage.match(/^url\(["'](.*\.gif)["']\)$/); //seulement les .png
					elm.src = url[1];
					elm.className = elm.className.replace(/pngFix/g,'');
					
				}
				else {
					if (elm.currentStyle.backgroundImage == "" || elm.currentStyle.backgroundImage == "url()") return;
					var url = elm.currentStyle.backgroundImage.match(/^url\(["'](.*\.png)["']\)$/); //seulement les .png
					if (!url || url.length<2) return;
					var pngLayer = document.createElement('i'); // on genere un <i> en position:absolute (layer), qui viendra se placer sous le contenu du div  qui avait besoin du style.
					with(pngLayer.style) {
						if (options.noOverflow) {
							width = elm.offsetWidth + 'px';
							height = elm.offsetHeight + 'px';
						} else {
						 	width = '32000px';
							height = '32000px'; 
						}
						position = 'absolute';
						zIndex = -1;
						fontSize = '1%';
						filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod='" + (options.noOverflow ? 'crop' : 'image') + "', src='"+url[1]+"')";
						background = 'none'; //forcing car parfois il peut arriver qu'on ai une CSS qui vienne rajouter des images / couleurs de fond
						/* positionnement de l'image en fonction du background-position sur l'element */
						if (!repeat) {
							switch((elm.currentStyle.backgroundPositionX+'').toLowerCase()) {
								case 'left' : left=0; break; 
								case 'right' : right = 0; break;
								case 'center' : 
									left='50%'; 
									setTimeout(function(pngLayer) {
										return function() {
											pngLayer.style.marginLeft = -(pngLayer.offsetWidth/2)+'px'; 
										}
									}(pngLayer), 50);
									break;
								default : 
									left = elm.currentStyle.backgroundPositionX; 
							}

							switch((elm.currentStyle.backgroundPositionY+'').toLowerCase()) {
								case 'top' : top = 0; break;
								case 'bottom' : bottom = 0; break;
								case 'center' : 
									top='50%'; 
									setTimeout(function(pngLayer) {
										return function() {
											pngLayer.style.marginTop=-(pngLayer.offsetHeight/2)+'px'; 
										}
									}(pngLayer), 100);
									break;
								default : 
									top = elm.currentStyle.backgroundPositionY || 0; 
							}
						} else {
							left = 0; //elm.currentStyle.backgroundPositionX +'';
							top = 0; //elm.currentStyle.backgroundPositionY +'';
						}
					} 
					
						/* gestion automatique du sizingMethod='scale' ou sizingMethod='image', ne pouvant pas tester le backgroundRepeat correctement, on passe par une methode un peu plus tricky */
						setTimeout(function(elmN, pngLayerN, repeatN) {
							return function() {
								if (!elmN || elmN.parentNode || !pngLayerN || !pngLayerN.parentNode) return;
								if (pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod=='image') {
									if (pngLayerN.offsetWidth<elmN.offsetWidth && repeatN) {
										pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='scale';
									} else if (pngLayerN.offsetWidth>elmN.offsetWidth && elm.currentStyle.backgroundPositionX.match(/^(left|0%|0px|0)$/) || elm.currentStyle.backgroundPositionY.match(/^(top|0%|0px|0)$/)){
										pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='crop';
									}
								} else {
									pngLayerN.sizingMethod = 'image';
								}
								if (elm.currentStyle.width.match(/^(0|[12](%|px)?)$/)) {
									pngLayerN.filters['DXImageTransform.Microsoft.AlphaImageLoader'].sizingMethod='image';
								}
								if (pngLayerN.style.right != 'auto' && pngLayerN.style.right !='')
									setTimeout(function() {
										pngLayerN.style.right = parseInt(pngLayerN.style.right) - (elm.offsetWidth%2 ? 1 : 0) + 'px';
									}, 50)
							}
						}(elm, pngLayer, repeat), 200);
					
					with (elm.style) {
						position = elm.currentStyle.position=="static" || elm.currentStyle.position=="" ? 'relative' : position;
						if (elm.currentStyle.overflow!='auto' && elm.currentStyle.overflow!='hidden') overflow = options.noOverflow ? 'visible' : (elm.currentStyle.width.match(/^(0|[12](%|px)?)$/) ? 'visible' : 'hidden');
						backgroundImage = 'none';
					}
					elm.appendChild(pngLayer);
			
			}
		}
	})(elm, noOverflow);
	try{
		pngFixLoader.useOnload ? pngFixLoader.addFunc(exec) : exec();
	} catch(e) {};
}



/* pngFixLoader 
	@unction 		:	objet pour permet le lancement des modifications des png via pngFix en décalé sur le onload de la page.
							cela permet de contourner un bug d'internet explorer qui affiche un message d'erreur si le DOM est modifié pendant le chargement de la page.
*/
var pngFixLoader = {
	useOnload : true, // true : active l'execution du fixPng sur le load, et false, execute le fixPng dès qu'il est appelé par la CSS
	functions : [], // toutes les fonctions à éxécuter sur le onload de la page
	addFunc : function(func) {
		pngFixLoader.functions.push(func);
	},
	launch : function() {
			pngFixLoader.useOnload = false; //une fois la page chargée, il faut laisser s'executer automatiquement la fonction pour d'autres actions (ex : ouverture layer)
			var counter = 1;
			while(pngFixLoader.functions.length>0) {
				//setTimeout(pngFixLoader.functions.pop(), 20*counter);
				pngFixLoader.functions.pop()();
				counter++;
			}
	},
	init : function() {
		if (pngFixLoader.useOnload && window.attachEvent && document.all) {
			window.attachEvent('onload', function() {
				setTimeout(pngFixLoader.launch, 100);
			});
		}
	}
}
pngFixLoader.init();




function openFicheMobile(idMobile) {
	// ici le code qui ouvrira soit un layer contenant une iframe avec l'url de la page
	// soit une popup
	
	
	/*
		
	*/
}



//SIMULATOR
function openSimDiv(opening) {
	setTimeout('openInterval('+opening+')',opening ? 1 : 1000 );
}

function openInterval(opening) {
	var SimFlashDiv = document.getElementById('flashSim');
	SimFlashDiv.style.height = opening ? "560px" : "200px" ;
	SimFlashDiv.style.zoom = opening ? 1 : 0 ;
	/*var SIMULATOR = document.getElementById('SIMULATOR');
	SIMULATOR.style.height = opening ? "560px" : "200px";*/
}


		//Fermeture Flash transparent => valable pour la Hp

function close_flash_hp(params) {
	
    document.getElementById('flashAllPage').style.display = 'none';
}




