/****
 Global vars
*******/
var IS_IE = document.all && window.print && !window.opera && ( !document.compatMode || /MSIE 6/.test(navigator.userAgent) || (document.compatMode && document.compatMode=="BackCompat"));
var IE_NG = document.all && window.print && !window.opera && /MSIE [7-9]/.test(navigator.userAgent) && document.compatMode && document.compatMode!="BackCompat"; //variable pour IE7 et + si besoin.
var IS_quirks = IS_IE && document.compatMode && document.compatMode=="BackCompat"; // variable qui declare le quirksmode seulement utile pour IE
var heightPropertyToUse = IS_IE ? "height" : "minHeight"; //variable utilisee pour l'alignement en hauteur des elements.
var IS_Webkit = /Konqueror|Safari|KHTML/.test(navigator.userAgent); 


//ajoute la classe hasJS si le JS est active sur le navigateur
document.documentElement.className+=" hasJS";

if (IS_IE) {
    document.documentElement.className += " IS_IE";
}


/*******
* Framework : 
* Fonctions necessaires au fonctionnement general. Elles apportent une aide supplementaire pour le developpement d'autres fonctions. Ces fonction sont utilisees par toutes les autres.
*********/

/* domReadyAddFuncs */
var beforeDomReadyFuncs = [];
function addBeforeDomReady(fn) { beforeDomReadyFuncs.push(fn); }
window.addEvent('domready', function() {
	beforeDomReadyFuncs.each(function(fn) {fn();});
});
var beforeLoadFuncs = [];
function addBeforeLoad(fn) { beforeLoadFuncs.push(fn); }

function getElementsByClassName(oElm, sTagName, sClassName){
	var aElements = (sTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(sTagName);
	var aReturnElements = new Array();
	sClassName = sClassName.replace(/\-/g, "\\-");
	var oRegExp = new RegExp("(^|\\s)" + sClassName + "(\\s|$)");
	var oElement;
	for(var i=0; i < aElements.length; i++){
		oElement = aElements[i];
		if(oRegExp.test(oElement.className)) {
            aReturnElements.push(oElement);
        }
	}
	return aReturnElements;
}

// getStyle : retourne la valeur d'une propriete CSS appliquee a un element
function getStyle(oElm, strCssRule){
	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;
}

/*retourne la valeur entiere d'un style*/
function intStyle(oElm, strCSSRule) {
	var val = parseInt(getStyle(oElm, strCSSRule));
	if (isNaN(val)) {
        val = 0;
    }
	return val;
}

/* retourne la somme de tous les styles verticaux appliques (border-width+padding) */ 
function getVStyles(elm) {
	return IS_quirks ? 0 : intStyle(elm, "border-top-width")+intStyle(elm, "border-bottom-width")+intStyle(elm, "padding-top")+intStyle(elm, "padding-bottom");
}
function getVMargins(elm) {
	return intStyle(elm, "margin-top")+intStyle(elm, "margin-bottom");
}
function getHStyles(elm) {
	return IS_quirks ? 0 : intStyle(elm, "border-left-width")+intStyle(elm, "border-right-width")+intStyle(elm, "padding-left")+intStyle(elm, "padding-right");
}
//removeClass
function removeClass(element, className) {
	element.className = element.className.replace(new RegExp("\\b"+className+"\\b","g"),"");
};

//addClass
function addClass(element, className) {
	element.className += " " + className;
};

//toggleClass
function toggleClass(element, className, classNameReplace) {
	element.className = element.className.replace(new RegExp("\\b"+className+"\\b","g"), classNameReplace);
};

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft;
		curtop = obj.offsetTop;
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return [curleft,curtop];
}

/* openclose */
function openclose(elm) {
    var par = getParent(elm, {className:"content(show|hide)"});
    if (par.className.match(/contenthide/)) {
        toggleClass(par, "contenthide", "contentshow");
    } else {
        toggleClass(par, "contentshow", "contenthide");
    }
    fixColumns();
}

/**********
* $n : objet de parcours du DOM, facile. Les fonctions ne font que les nodes HTML
***********/
var $nodes = {
    /* 	hasAttributes : 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 (hasAttributes(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) {
        var re, at;
        if (n.nodeType != 1) {
            return false;
        }
        function check(attr) {
            for (var i in attr) {
                at = (typeof n[i]) != "undefined" ? n[i] : n.getAttribute(i);
                re = attr[i] instanceof RegExp ? re : new RegExp("\\b" + attr[i] + "\\b", "i");
                if (!at || !re.test(at)) {
                    return false;
                }
            }
            return true;
        }
        ;
        if (not && check(not))    {
            return false;
        }
        if (check(a)) {
            return true;
        }
        return false;
    },
    /* 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("*")) : n.getElementsByTagName(tag);
    },
    /* fonction qui retourne le premier element correspondant aux attributs donnes */
    node : function(n, a, not) {
        return $nodes.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 caract&egrave;res passee en param&egrave;tre, cela signifie qu'on ne veut que recuperer des tags
        if (a.nodeName && a.nodeName == "*") {
            delete a.nodeName;
        }
        var elms = arrElms || $nodes.getByTagName(n, (a.nodeName || "*"));
        for (var i = 0; i < elms.length; i++) {
            var x = elms[i];
            if ($nodes.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 $nodes.nodes(n, a, not, false, n.childNodes);
    },
    firstChild : function(n, a, not) {
        return $nodes.nodes(n, a, not, true, n.childNodes);
    },
    lastChild : function(n, a, not) {
        var node = $nodes.nodes(n, a, not, false, n.childNodes);
        return node[node.length - 1];
    },
    move : function(n, a, not, action) {
        do {
            n = n[action];
            if (n && $nodes.hasAttr(n, a, not)) {
                return n;
            }
        } while (n);
        return null;
    },
    after : function(n, a, not) {
        return $nodes.move(n, a, not, "nextSibling");
    },
    before : function(n, a, not) {
        return $nodes.move(n, a, not, "previousSibling");
    },
    parent : function(n, a, not) {
        return $nodes.move(n, a, not, "parentNode");
    }
};
/* fonctions raccourcis */
var getNode = $nodes.node,
	getNodes = $nodes.nodes,
	getChildNodes = $nodes.childs,
	getNextSibling = $nodes.after,
	getPreviousSibling = $nodes.before,
	getParent = $nodes.parent,
	hasAttributes = $nodes.hasAttr,
	getElementsByTagName = $nodes.getByTagName;

/*  ifrlayer : 
	Cette fonction corrige un probleme sous IE6 lorsqu'un layer passe par dessus un select, le select sera toujours au dessus. Pour corriger ce probl&egrave;me.
	ex : 	
		- afficher un bloc : 
			myBlock.style.display='block';
			ifrlayer.make(myBlock); //genere ou affiche l'iframe
		- cacher un bloc :
			myBlock.style.display='none';
			ifrlayer.hide(myBlock); //cache l'iframe associee au bloc
		-deplacer un bloc : 
			myBlock.style.left = "100px";
			ifrlayer.move(myBlock); // deplace l'iframe associee au bloc
*/
var ifrlayer = {
    make:function(obj) {
        if (!obj) {
            return;
        }
        obj = (typeof(obj) == "string") ? document.getElementById(obj) : obj;
        if (!obj) {
            return;
        }
        if (document.all && window.print && document.getElementById && !obj.iframelayer) {
            if (obj.parentNode && !obj.iframelayer) {
                var ifr = obj.parentNode.insertBefore(document.createElement("iframe"), obj);
            }
            ifr.src = "javascript:false";
            if (obj.currentStyle.zIndex != "" && parseInt(obj.currentStyle.zIndex) > 1) {
                ifr.style.zIndex = parseInt(obj.currentStyle.zIndex) - 1;
            }
            with (ifr.style) {
                filter = "mask()";
                position = "absolute";
            }
            obj.iframelayer = ifr;
        }
        if (obj.iframelayer) {
            obj.iframelayer.style.visibility = "visible";
            ifrlayer.move(obj, true);
        }
    },
    hide:function(obj) {
        if (!obj) {
            return;
        }
        obj = typeof(obj) == "string" ? document.getElementById(obj) : obj;
        if (!obj) {
            return;
        }
        if (obj.iframelayer) {
            obj.iframelayer.style.visibility = "hidden";
        }
    },
    kill:function(obj) {
        if (!obj) {
            return;
        }
        obj = typeof(obj) == "string" ? document.getElementById(obj) : obj;
        if (obj) {
        } else return;
        if (obj.iframelayer) {
            obj.iframelayer.parentNode.removeChild(obj.iframelayer);
        }
    },
    move:function(obj, size) {
        if (obj && obj.iframelayer) {
            with (obj.iframelayer.style) {
                top = obj.offsetTop + "px";
                left = obj.offsetLeft + "px";
                if (size) {
                    width = obj.offsetWidth + "px";
                    height = obj.offsetHeight + "px";
                }
            }
        }
    }
};

/*  addHover : */
function addHover(elm, className, iframeTag) {
	className = className || "hover";
	elm.style.behavior = " "; //reecriture du style behavior
	elm.hoverClassName = className;
	
	if (iframeTag) {
		elm.iframeElm = getNode(elm, iframeTag);
	}
	elm=$(elm);
	elm.addEvent('mouseenter', function() {
        elm.className += ' ' + elm.hoverClassName;
        if (elm.iframeElm) {
            ifrlayer.make(elm.iframeElm);
        }
    });
	elm.addEvent('mouseleave', function() {
        elm.className = elm.className.replace(new RegExp("\\b" + elm.hoverClassName + "\\b", "g"), "");
        if (elm.iframeElm) {
            ifrlayer.hide(elm.iframeElm);
        }
    });
	
}

/*************
* Fonctions pour fixer les coins sous IE
* Une fonctions est prevue aussi pour Safari 2.0, Opera 8.5 et FF 1.0 pour certains cas
**************/
var CSSBottomCorners=[]; //array pouvant contenir les coins absolu positionnes en bottom
var CSSHeightCorners=[]; //array pouvant contenir les listes des blocks dont les coins font 100% de la hauteur
var currentBlockToFixCorners=null; //variable gloable utilisee lorsqu'on veux fixer les coins sur un seul bloc

function cssRight(elm) {
	if (elm.currentStyle.right!="auto") {
		elm.style.right = (parseInt(elm.currentStyle.right)-(elm.parentNode.offsetWidth%2))+"px";
	} else {
		elm.style.right = "auto";
	}
}

function cssBottom(elm, pushElement) {
	if (pushElement && !elm.CSSBottomAlreadyCSS) {
		CSSBottomCorners.push(elm);
		elm.CSSBottomAlreadyCSS=true;
	}
	if (elm.currentStyle.bottom!="auto") {
		elm.style.bottom = (parseInt(elm.currentStyle.bottom)-(elm.parentNode.offsetHeight%2))+"px";
	} else {
		elm.style.bottom = "auto";
	}
}

function fixCorners(block) {
	if (IS_IE) {
		for (var i=CSSBottomCorners.length-1; i>-1; --i) {
			CSSBottomCorners[i].style.bottom="";
		}
	} else {
		if (IS_Webkit || /Gecko\/200[56]|Opera 8.5/i.test(navigator.userAgent)) {
            fixCornersOnBlocks(block);
        }
	}
}

function fixCornersOnBlocks(block) {
	currentBlockToFixCorners = block || document.body;
	currentBlockToFixCorners.className+=" hidecorners";
	setTimeout(fixCornersOnBlocksShowCorners,5);
}

function fixCornersOnBlocksShowCorners() {
	if (currentBlockToFixCorners) {
        currentBlockToFixCorners.className = currentBlockToFixCorners.className.replace(/\bhidecorners\b/g, "");
    }
	currentBlockToFixCorners=null;
}
/* height Corners : coins qui font tout le tour d'un bloc */
function cssHeight(elm, pushElement) {
	if (pushElement && !elm.CSSHeightAlreadyCSS) {
		CSSHeightCorners.push(elm);
		elm.CSSHeightAlreadyCSS=true;
	}
	elm.style.height = elm.parentNode.offsetHeight+"px";
}

function fixHeights(block) {
	if (IS_IE) {
		var array = block ? getNodes(block, {nodeName:"b", className:"tr|bl"}) : CSSHeightCorners;
		array.eachInv(function() {
			this.style.height="";
		});
	}
}

/****************
* Suppression du texte dans les input
******************/
function inputValue(elm, state) { 
	elm.oldValue=elm.getAttribute('value'); 
	elm.onfocus = function() {
        if (!this.isChecking && this.value == this.oldValue) {
            this.value = '';
        }
    };
	elm.onblur = function() {
        if (this.value == '') {
            this.value = this.oldValue;
        }
    };
	if (!elm.isChecking) {
        elm.onfocus();
    }
}
/* ********************************* Fin Lib + Mootools ************************************* */

function forceCheck(elm, linkedInput) {
	linkedInput = typeof linkedInput=="string" ? document.getElementById(linkedInput) : linkedInput;
	linkedInput.checked = elm.checked;
}

/* generates corners and others elements if needed */
function generateElements(parent, stringClasses) {
	var i, x;
	parent = (typeof parent == "string") ? document.getElementById(parent) : parent;
	var content = parent || document.body;
	var div = content.getElementsByTagName("div");
	
	//recupere un node avec la class blockInsideParDefaut
	function getIsd(node, className) { return getNode(node, {className: (className || "blockInside")});};
	
	// fonction de creation d'un coin (b avec className) 
	function nc(clN) {var b = document.createElement("b");b.className=clN;return b;};
	
	//ajoute un element ou une liste d'elements (c) sur l'element x
	function add(x, c) {
        var i=0;
        if (!x) {
            return;
        }
        if (c.length) {
            for (i = 0; i < c.length; i++) {
                x.appendChild(c[i].cloneNode(true));
            }
        } else {
            x.appendChild(c.cloneNode(true));
        }
    };
	
	//-- creation des elements qui seronts clones --
	var corners = [nc("tl"), nc("tr"), nc("bl"), nc("br")]; //corners 
	var shadow = nc("specialShadow"); add(shadow, [nc("lt"), nc("rt"), nc("trame")]); // specialShadow
	var overtl = nc("overtl"); // overtl : coin arrodis supplementaire pour les blocks avec des bordures speciales
	
	// -- creation des coins ou autres elements -- 
	// parcours des divs pour leur rajouter les corners
	for (i=div.length-1; i>=0; i--) {
		x=div[i];
		if (!x.alreadyProcessed) {
			if(x.className.match(/\bblock\b/)){
				add(getIsd(x), corners);
			}
			if (x.className.match(/\bblockToggle|blockShadowSimple\b/)) { //blocks avec coins absolus sur tous les cotes.
				add(getIsd(x), overtl);
			}
			x.alreadyProcessed = true;	
			initOtherBlocks(x); // fonction d'initialisation d'autres blocks
		}
	}
	//fixColumns();
}
/* initOtherBlocks() : fonction rajoute d'autres fonctionnalites sur differents blocks  (toggle, onglets),
   Cette fonction est forcement lancee depuis generateElements, et cela evite de faire une deuxieme passe sur les divs de la page
 */
function initOtherBlocks(x) {
	// block a onglets
    if (x.className.match(/\bblockTabs(Sub)?\b/)) {//block d'ongl ets en general (gere tous types d'onglets).
        tabs.init(x);
    }
    if (x.className.indexOf("scrollH")!=-1) {  //block de scroll horizontal
        scroll.init(x);
    }
    if (x.className.match(/\bline\b/)) { //si ligne de block, on la stocke dans un tableau
        linesOfBlocks.push(x);
    }
}


/**************
* sizeBlocks : alignement des blocks en hauteurs
**************/
var linesOfBlocks=[];
function sizeBlocks(parentBlock) {
	function size(block, size){
		if (block){
			var body = block.className.match(/\bblock\b/) ? getNode(block, {nodeName:"div", className:"body"}) : block; //si on a une line ou bien un block
			if (body) {
                body.style[heightPropertyToUse] = body.offsetHeight + size - getVStyles(body) + "px";
            }
		}
	};
	linesOfBlocks.eachInv(function (line) { //les lignes fournies sont
		var units = getChildNodes(line, {className:"unit"});
		units.each(function(unit) {
			var blocks = getChildNodes(unit, {className:"(block|line)"}, {className:"noresize"});
			var sizeToApply = line.offsetHeight-unit.offsetHeight;
			var sizePerBlock = parseInt(sizeToApply/blocks.length);
			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(blocks.getLast(), line.offsetHeight - unit.offsetHeight);
            }
		});
	});
}

/***************
* fixColumns()
****************/
function fixColumns() {
	function fix() {
		var colonnes = ['main','rightColumn'],
			colonnesInside = ["", ""];
		var hMax=0, i, b, minMax=0, sum=0; hToU = heightPropertyToUse;
		
		function each(f) { //fonction d'iteration
			for (i=0; i<colonnes.length; i++){
				b = $(colonnes[i]);
				f();
			}
		}
		
		each(function() {
			sum=0;
			if (b) {
				getChildNodes(b, {}).each(function(node) { sum += node.offsetHeight; });
				if (sum>minMax) {
                    minMax = sum;
                }
			}
		});
		// on remet la hauteur par defaut a toutes les colonnes (hauteur minimum)
		each(function() {
			var bToSize = $(colonnesInside[i]) || b;
			if (bToSize) {
                bToSize.style[hToU] = minMax + "px";
            }
		});
		// on recupere la hauteur la plus grande
		each(function() {
			if (b){
				if (b.offsetHeight + intStyle(b, "margin-top") >= hMax) {
					hMax = b.offsetHeight - intStyle(b, "margin-top");
				}
			}
		});
		// on applique la nouvelle hauteur sur les colonnes
		each(function() {
			var bIsd = $(colonnesInside[i]);
			if (b && bIsd) {
				var diff = (hMax - b.offsetHeight) + bIsd.clientHeight - getVStyles(bIsd);
				bIsd.style[hToU] = diff + 'px';
			} else if (b) {
				getVStyles(b);
				b.style[hToU] = hMax  - getVStyles(b) - intStyle(b, "margin-top") + 'px';
			}
			
		});
	};
	setTimeout(fix,1);
}


function showAndHide(field) {
	var allFields = getNodes(field.form, {name:field.name}, null, false, field.form.elements);
	allFields.each(function(field) {
		var elm = document.getElementById(field.value);
		elm.style.display = this.checked ? "block" : "none";
	});
	fixHeights(field);
}

function fixWidth(elm) {
	elm.style.width = elm.offsetWidth>118 ? '118px' : '';
}


/***********
* Init
************/
//fonction lancee une fois toute la page chargee
window.addEvent('load', function () {
    generateElements();
    fixCorners();
});