/**
 * Espace de nom pour stocker les différents méthodes pour ne pas poluer window
 */
Utile = {
	
	/**
	 * Renvoi un UID aléatoire et unique
	 * @return string
	 */
	randomUID: function() {
		 return (Math.random()*Math.pow(10, 16)).toString().replace(/^([\.])+.*$/, '$1')+'_'+(new Date().valueOf());
	},
	
	/**
	 * Décode et renvoi un objet contenant les paramètres JS stockées dans la balise params d'un noeud
	 * @param Element element Le noeud Element d'où extraire les paramètres
	 * @param Object toExtend Un eventuel objet a étendre
	 * @return Object
	 */
	getParams: function(_element, toExtend) {
		if (!_element['nodeName'] && _element['0']) {
			var element = _element[0];
		} else {
			var element = _element;
		}
		var paramString  = element.getAttribute('params');
		var returnObject = toExtend || {};
		if (paramString == null) return returnObject;
		
		try { eval('var params = {'+paramString+'}'); }
		catch (e) { var params = {}; }

		return jQuery.extend(returnObject, params);
	},
	
	/**
	 * Converti une date jj/mm/aaaa vers sont format ISO.
	 */
	frDateToISODate: function(string, asDate) {
		var ISODateText = string.slice(3, 5)+'/'+string.slice(0, 2)+'/'+string.slice(6);
		return asDate ? new Date(Date.parse(ISODateText)) : ISODateText;
	},
	
	/**
	 * Fonction date comme ne php. 
	 * @param format
	 * @param timestamp
	 * @return string
	 * From PHPJS
	 */
	date: function(format, timestamp) {
	    var that = this;
	    var jsdate=((typeof(timestamp) == 'undefined') ? new Date() : (typeof(timestamp) == 'number') ? new Date(timestamp*1000) : new Date(timestamp));
	    var pad = function (n, c){if ( (n = n + "").length < c )return new Array(++c - n.length).join("0") + n;else return n;};
	    var _dst = function (t) {var dst=0;var jan1 = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0);var june1 = new Date(t.getFullYear(), 6, 1, 0, 0, 0, 0);var temp = jan1.toUTCString();var jan2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));temp = june1.toUTCString();var june2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);if (std_time_offset === daylight_time_offset) dst = 0;else {var hemisphere = std_time_offset - daylight_time_offset;if (hemisphere >= 0) std_time_offset = daylight_time_offset;dst = 1;};return dst;};
	    var ret = '';
	    var txt_weekdays = ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"];
	    var txt_ordin = {1:"er",2:"me",3:"me",21:"",22:"",23:"",31:""};
	    var txt_months =  ["", "Janvier", "Fevrier", "Mars", "Avril","Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre","Decembre"];
	    var f = {d: function (){return pad(f.j(), 2);},D: function (){var t = f.l();return t.substr(0,3);},j: function (){return jsdate.getDate();},l: function (){return txt_weekdays[f.w()];},N: function (){return f.w() + 1;},S: function (){return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';},w: function (){return jsdate.getDay();},z: function (){return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;},W: function (){var a = f.z(), b = 364 + f.L() - a;var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;if (b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){return 1;}if (a <= 2 && nd >= 4 && a >= (6 - nd)){nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");return that.date("W", Math.round(nd2.getTime()/1000));};return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);},F: function (){return txt_months[f.n()];},m: function (){return pad(f.n(), 2);},M: function (){var t = f.F();return t.substr(0,3);},n: function (){return jsdate.getMonth() + 1;},t: function (){var n;if ( (n = jsdate.getMonth() + 1) == 2 ){return 28 + f.L();};if ( n & 1 && n < 8 || !(n & 1) && n > 7 ){return 31;};return 30;},L: function (){var y = f.Y();return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;},o: function (){if (f.n() === 12 && f.W() === 1) {return jsdate.getFullYear()+1;}if (f.n() === 1 && f.W() >= 52) {return jsdate.getFullYear()-1;};return jsdate.getFullYear();},Y: function (){return jsdate.getFullYear();},y: function (){return (jsdate.getFullYear() + "").slice(2);},a: function (){return jsdate.getHours() > 11 ? "pm" : "am";},A: function (){return f.a().toUpperCase();},B: function (){var off=(jsdate.getTimezoneOffset()+60)*60;var theSeconds=(jsdate.getHours()*3600)+(jsdate.getMinutes()*60)+jsdate.getSeconds()+off;var beat=Math.floor(theSeconds/86.4);if(beat>1000){beat-=1000;};if(beat<0){beat+=1000;};if((String(beat)).length==1){beat="00"+beat;};if((String(beat)).length==2){beat="0"+beat;};return beat;},g: function (){return jsdate.getHours() % 12 || 12;},G: function (){return jsdate.getHours();},h: function (){return pad(f.g(), 2);},H: function (){return pad(jsdate.getHours(), 2);},i: function (){return pad(jsdate.getMinutes(), 2);},s: function (){return pad(jsdate.getSeconds(), 2);},u: function (){return pad(jsdate.getMilliseconds()*1000, 6);},e: function () {return 'UTC';},I: function (){return _dst(jsdate);},O: function (){var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);t = (jsdate.getTimezoneOffset() > 0) ? "-"+t : "+"+t;return t;},P: function (){var O = f.O();return (O.substr(0, 3) + ":" + O.substr(3, 2));},T: function () {return 'UTC';},Z: function (){return -jsdate.getTimezoneOffset()*60;},c: function (){return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();},r: function (){return f.D()+', '+f.d()+' '+f.M()+' '+f.Y()+' '+f.H()+':'+f.i()+':'+f.s()+' '+f.O();},U: function (){return Math.round(jsdate.getTime()/1000);}};
	    return format.replace(/[\\]?([a-zA-Z])/g, function (t, s){
	        if ( t!=s ){ret = s;} else if (f[s]){ret = f[s]();} else {ret = s;}
	        return ret;
	    });
	},
	
	/**
	 * Gère le redimensionnement automatique des dialogues
	 */
	dialogResize: function(body) {
		
		var jBody 		= jQuery(body),
			jBodyChilds = jBody.children(),
			options     = body.options;
		
		if (options.autoWidth || options.autoHeight) {
			
			var width  = body.preCalculedWidth  || -1,
				height = body.preCalculedHeight || -1,
				windowInnerWidth  = window.innerWidth  || document.documentElement.clientWidth,
				windowInnerHeight = window.innerHeight || document.documentElement.clientHeight,
				windowScrollTop   = jQuery(window).scrollTop(),
				windowScrollLeft  = jQuery(window).scrollLeft();
			
			if (width == -1 | height == -1) {
				jBodyChilds.each(function() {
					var jThis = jQuery(this);
					var position = jThis.position();
					width  = Math.max(width,  jThis.width()  + position.left);
					height = Math.max(height, jThis.height() + position.top);
				});
				body.preCalculedWidth  = width;
				body.preCalculedHeight = height;
			}
			
			if (options['maxWidth'])
				width  = Math.min(width, options.maxWidth);
			if (options['maxHeight'])
				height = Math.min(height, options.maxHeight);
			
			if (options['minWidth'])
				width  = Math.max(width, options.minWidth);
			if (options['minHeight'])
				height = Math.max(height, options.minHeight);
			
			// Pas plus grand que la fenêtre elle même , moins 20 pixels autours (20 à gauche et 20 à droite => 40)
			width  = Math.min(windowInnerWidth  - 40, width);
			height = Math.min(windowInnerHeight - 40, height);
			
			var left = (windowInnerWidth  - width)  / 2;
			var top  = (windowInnerHeight - height) / 2;
			if (width)  {
				body.parentNode.style.width  = width+'px';
				body.parentNode.style.left   =  (left + windowScrollLeft)+'px';
				if (jBodyChilds.length == 1) {
					jBodyChilds.get(0).style.width  = width+'px';
				}
			}
			
			if (height) {
				body.parentNode.style.height = height+'px';
				body.parentNode.style.top    = (top + windowScrollTop)+'px';
				if (jBodyChilds.length == 1) {
					jBodyChilds.get(0).style.height     = height+'px';
					jBodyChilds.get(0).dialogAutoHeight = true;
				}
			}
		}
	},
	
	getElementWidth: function(element, getInnerSize) {
		var width = Math.max(0,
				Math.max(element.scrollWidth, element.scrollWidth),
				Math.max(element.offsetWidth, element.offsetWidth),
				Math.max(element.clientWidth, element.clientWidth)
		);
		return width;
	},
	
	getElementHeight: function(element) {
	    return Math.max(0,
	        Math.max(element.scrollHeight, element.scrollHeight),
	        Math.max(element.offsetHeight, element.offsetHeight),
	        Math.max(element.clientHeight, element.clientHeight)
	    );
	},
	
	getDocumentHeight: function() {
	    return Utile.getElementHeight(document);
	},
	
	getDocumentWidth: function() {
	    return Utile.getElementWidth(document);
	},
	
	// Converti une url en objet
	deserialize: function(url) {
		
		var data = {};
		var chunks = String(url).split('&');
		for (var i = 0; i < chunks.length; i++) {
			var pair = chunks[i].split('=');
			data[pair[0]] = (pair.length == 2) ? pair[1] : null;
		}
		return data;
		
	},
	
	// Récupère la position du curseur dans un textarea
	// Affecte les propriétées du textarea pour qu'il soit compatible avec les méthodes W3C
	parseTextareaCaretPosition: function(oTextarea) {
		var docObj = oTextarea.ownerDocument;
		var result = {start:0, end:0, caret:0};
		
		if (navigator.appVersion.indexOf("MSIE")!=-1) {
			if (oTextarea.tagName.toLowerCase() == "textarea") {
				if (oTextarea.value.charCodeAt(oTextarea.value.length-1) < 14) {
					oTextarea.value=oTextarea.value.replace(/34/g,'')+String.fromCharCode(28);
				}
				var oRng = docObj.selection.createRange();
				var oRng2 = oRng.duplicate();
				oRng2.moveToElementText(oTextarea);
				oRng2.setEndPoint('StartToEnd', oRng);
				result.end = oTextarea.value.length-oRng2.text.length;
				oRng2.setEndPoint('StartToStart', oRng);
				result.start = oTextarea.value.length-oRng2.text.length; 
				result.caret = result.end;
				if (oTextarea.value.substr(oTextarea.value.length-1) == String.fromCharCode(28)) {
					oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length-1);
				}			
			} else {
				var range = docObj.selection.createRange();
				var r2 = range.duplicate();			
				result.start = 0 - r2.moveStart('character', -100000);
				result.end = result.start + range.text.length;	
				result.caret = result.end;
			}			
		} else {
			result.start = oTextarea.selectionStart;
	    	result.end   = oTextarea.selectionEnd;
			result.caret = result.end;
		}
		if (result.start < 0) {
			 result = {start:0, end:0, caret:0};
		}
		oTextarea.selectionStart = result.start;
		oTextarea.selectionEnd   = result.end;
		return result;
	},
	
	fullScreenModalAjax: function(display) {
		var modalDiv = document.getElementById('fullScreenModalAjax_div');
		if (!modalDiv) {
			modalDiv = document.createElement('DIV');
			modalDiv.id = 'fullScreenModalAjax_div';
			modalDiv.className = 'fullScreenModalAjax';
			modalDiv.display = 'none';
			modalDiv.style.position =  "absolute";
			modalDiv.style.top  = 0;
			modalDiv.style.left = 0;
			document.body.appendChild(modalDiv);
			jQuery(window).resize(function() {
				modalDiv.style.height  = Utile.getDocumentHeight()+"px";
				modalDiv.style.width   = Utile.getDocumentWidth()+"px";
			});
		}
		
		if (display) {
			modalDiv.style.zIndex  = 5000;
			modalDiv.style.display = '';
		}
		else {
			modalDiv.style.display = 'none';
		}
	},
	
	parseHTTPHeaders: function(string) {
		// Parse HTTP Headers as returned by the server
		var headerLines = string.replace(/\r/g,"").split("\n"),
			headers = {};
		for (var i = 0; i < headerLines.length; i++) {
			var name = String(headerLines[i]).replace(/^([^:]+):.*$/, '$1');
			if (name == '') continue;
			headers[name] = headerLines[i].replace(/^[^:]+: ?(.*)$/, '$1');
		}
		return headers;
	},
	
	// From PHPJS
	htmlEntitiesDecode: function (string, quote_style) {
		var hash_map = {}, symbol = '', tmp_str = '', entity = '', tmp_str = string.toString();
	    if (false === (hash_map = Utile.getHtmlTranslationTable('HTML_ENTITIES', quote_style))) return false;
	    for (symbol in hash_map) { entity = hash_map[symbol]; tmp_str = tmp_str.split(entity).join(symbol); }
	    tmp_str = tmp_str.split('&#039;').join("'");
	    return tmp_str;
	},
	
	// From PHPJS
	getHtmlTranslationTable: function(table, quote_style) {
		var entities={},hash_map={},decimal=0,symbol='',constMappingTable={},constMappingQuoteStyle={},useTable={},useQuoteStyle={};
		constMappingTable={0:'HTML_SPECIALCHARS',1:'HTML_ENTITIES'};
		constMappingQuoteStyle={0:'ENT_NOQUOTES',2:'ENT_COMPAT',3:'ENT_QUOTES'};
		useTable=!isNaN(table)?constMappingTable[table]:table?table.toUpperCase():'HTML_SPECIALCHARS';
		useQuoteStyle=!isNaN(quote_style)?constMappingQuoteStyle[quote_style]:quote_style?quote_style.toUpperCase():'ENT_COMPAT';
	    if(useTable!=='HTML_SPECIALCHARS'&&useTable!=='HTML_ENTITIES')throw new Error("Table: "+useTable+' not supported');
		if(useTable==='HTML_ENTITIES')entities={38:'&amp;',60:'&lt;',62:'&gt;',160:'&nbsp;',161:'&iexcl;',162:'&cent;',163:'&pound;',164:'&curren;',165:'&yen;',166:'&brvbar;',167:'&sect;',168:'&uml;',169:'&copy;',170:'&ordf;',171:'&laquo;',172:'&not;',173:'&shy;',174:'&reg;',175:'&macr;',176:'&deg;',177:'&plusmn;',178:'&sup2;',179:'&sup3;',180:'&acute;',181:'&micro;',182:'&para;',183:'&middot;',184:'&cedil;',185:'&sup1;',186:'&ordm;',187:'&raquo;',188:'&frac14;',189:'&frac12;',190:'&frac34;',191:'&iquest;',192:'&Agrave;',193:'&Aacute;',194:'&Acirc;',195:'&Atilde;',196:'&Auml;',197:'&Aring;',198:'&AElig;',199:'&Ccedil;',200:'&Egrave;',201:'&Eacute;',202:'&Ecirc;',203:'&Euml;',204:'&Igrave;',205:'&Iacute;',206:'&Icirc;',207:'&Iuml;',208:'&ETH;',209:'&Ntilde;',210:'&Ograve;',211:'&Oacute;',212:'&Ocirc;',213:'&Otilde;',214:'&Ouml;',215:'&times;',216:'&Oslash;',217:'&Ugrave;',218:'&Uacute;',219:'&Ucirc;',220:'&Uuml;',221:'&Yacute;',222:'&THORN;',223:'&szlig;',224:'&agrave;',225:'&aacute;',226:'&acirc;',227:'&atilde;',228:'&auml;',229:'&aring;',230:'&aelig;',231:'&ccedil;',232:'&egrave;',233:'&eacute;',234:'&ecirc;',235:'&euml;',236:'&igrave;',237:'&iacute;',238:'&icirc;',239:'&iuml;',240:'&eth;',241:'&ntilde;',242:'&ograve;',243:'&oacute;',244:'&ocirc;',245:'&otilde;',246:'&ouml;',247:'&divide;',248:'&oslash;',249:'&ugrave;',250:'&uacute;',251:'&ucirc;',252:'&uuml;',253:'&yacute;',254:'&thorn;',255:'&yuml;'}
	    if(useQuoteStyle!=='ENT_NOQUOTES')entities['34']='&quot;';
		if(useQuoteStyle==='ENT_QUOTES')entities['39']='&#39;';
		for(decimal in entities){symbol=String.fromCharCode(decimal);hash_map[symbol]=entities[decimal];}
		return hash_map;
	},
	
	// From PHPJS
	sprintf: function ( ) {var j=arguments,m=0,n=function(b,a,e,c){e||(e=" ");a=b.length>=a?"":Array(1+a-b.length>>>0).join(e);return c?b+a:a+b},o=function(b,a,e,c,f,d){var g=c-b.length;if(g>0)b=e||!f?n(b,c,d,e):b.slice(0,a.length)+n("",g,"0",true)+b.slice(a.length);return b},l=function(b,a,e,c,f,d,g){b=b>>>0;e=e&&b&&{"2":"0b","8":"0","16":"0x"}[a]||"";b=e+n(b.toString(a),d||0,"0",false);return o(b,e,c,f,g)},q=function(b,a,e,c,f,d){if(c!=null)b=b.slice(0,c);return o(b,"",a,e,f,d)};return j[m++].replace(/%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g, function(b,a,e,c,f,d,g){var h;if(b=="%%")return"%";f=false;h="";for(var i=false,k=false,r=" ",s=e.length,p=0;e&&p<s;p++)switch(e.charAt(p)){case " ":h=" ";break;case "+":h="+";break;case "-":f=true;break;case "'":r=e.charAt(p+1);break;case "0":i=true;break;case "#":k=true;break}c=c?c=="*"?+j[m++]:c.charAt(0)=="*"?+j[c.slice(1,-1)]:+c:0;if(c<0){c=-c;f=true}if(!isFinite(c))throw new Error("sprintf: (minimum-)width must be finite");d=d?d=="*"?+j[m++]:d.charAt(0)=="*"?+j[d.slice(1,-1)]:+d:"fFeE".indexOf(g)> -1?6:g=="d"?0:undefined;a=a?j[a.slice(0,-1)]:j[m++];switch(g){case "s":return q(String(a),f,c,d,i,r);case "c":return q(String.fromCharCode(+a),f,c,d,i);case "b":return l(a,2,k,f,c,d,i);case "o":return l(a,8,k,f,c,d,i);case "x":return l(a,16,k,f,c,d,i);case "X":return l(a,16,k,f,c,d,i).toUpperCase();case "u":return l(a,10,k,f,c,d,i);case "i":case "d":b=parseInt(+a,10);h=b<0?"-":h;a=h+n(String(Math.abs(b)),d,"0",false);return o(a,h,f,c,i);case "e":case "E":case "f":case "F":case "g":case "G":b=+a;h= b<0?"-":h;a=["toExponential","toFixed","toPrecision"]["efg".indexOf(g.toLowerCase())];g=["toString","toUpperCase"]["eEfFgG".indexOf(g)%2];a=h+Math.abs(b)[a](d);return o(a,h,f,c,i)[g]();default:return b}})},
	strptime: function(dateStr, format) {var c={tm_sec:0,tm_min:0,tm_hour:0,tm_mday:0,tm_mon:0,tm_year:0,tm_wday:0,tm_yday:0,unparsed:""},t=this,m=0,p=false,h=function(){return q(new Date(Date.UTC(c.tm_year+1900,c.tm_mon,c.tm_mday||1,c.tm_hour,c.tm_min,c.tm_sec)),c.tm_mday)},q=function(a,d){c.tm_sec=a.getUTCSeconds();c.tm_min=a.getUTCMinutes();c.tm_hour=a.getUTCHours();c.tm_mday=d===0?d:a.getUTCDate();c.tm_mon=a.getUTCMonth();c.tm_year=a.getUTCFullYear()-1900;c.tm_wday=d===0?a.getUTCDay()>0?a.getUTCDay()-1:6:a.getUTCDay(); d=new Date(Date.UTC(a.getUTCFullYear(),0,1));c.tm_yday=Math.ceil((a-d)/864E5)},u=/\S/,v=/\s/,w={c:"locale",D:"%m/%d/%y",F:"%y-%m-%d",r:"locale",R:"%H:%M",T:"%H:%M:%S",x:"locale",X:"locale"},r=function(a){return(a+"").replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g,"\\$1")};this.php_js=this.php_js||{};this.setlocale("LC_ALL",0);for(var i=this.php_js,n=i.locales[i.localeCategories.LC_TIME].LC_TIME;g.match(/%[cDFhnrRtTxX]/);)g=g.replace(/%([cDFhnrRtTxX])/g,function(a,d){a=w[d];return a==="locale"? n[d]:a});var e=function(a,d,o){if(typeof d==="string")d=new RegExp("^"+d,"i");var l=k.slice(a);d=d.exec(l);if((d?o.apply(null,d):null)===null)throw"No match in string";return a+d[0].length};i=function(a,d,o){return e(a,t.array_map(r,n[d]).join("|"),function(l){if(l=n[d].search(new RegExp("^"+r(l)+"$","i")))c[o]=l[0]})};for(var f=0,b=0;f<g.length;f++)if(g.charAt(f)==="%"){var s=["%","n","t"].indexOf(g.charAt(f+1));if(s!==-1){if(["%","\n","\t"].indexOf(k.charAt(b))===s){++f;++b;continue}return false}var j= g.charAt(f+1);try{switch(j){case "a":case "A":b=i(b,j,"tm_wday");break;case "h":case "b":b=i(b,"b","tm_mon");h();break;case "B":b=i(b,j,"tm_mon");h();break;case "C":b=e(b,/^\d?\d/,function(a){a=(parseInt(a,10)-19)*100;c.tm_year=a;h();if(!c.tm_yday)c.tm_yday=-1});break;case "d":case "e":b=e(b,j==="d"?/^(0[1-9]|[1-2]\d|3[0-1])/:/^([1-2]\d|3[0-1]|[1-9])/,function(a){a=parseInt(a,10);c.tm_mday=a;h()});break;case "g":break;case "G":break;case "H":b=e(b,/^([0-1]\d|2[0-3])/,function(a){a=parseInt(a,10); c.tm_hour=a});break;case "l":case "I":b=e(b,j==="l"?/^([1-9]|1[0-2])/:/^(0[1-9]|1[0-2])/,function(a){a=parseInt(a,10)-1+m;c.tm_hour=a;p=true});break;case "j":b=e(b,/^(00[1-9]|0[1-9]\d|[1-2]\d\d|3[0-6][0-6])/,function(a){a=parseInt(a,10)-1;c.tm_yday=a});break;case "m":b=e(b,/^(0[1-9]|1[0-2])/,function(a){a=parseInt(a,10)-1;c.tm_mon=a;h()});break;case "M":b=e(b,/^[0-5]\d/,function(a){a=parseInt(a,10);c.tm_min=a});break;case "P":return false;case "p":b=e(b,/^(am|pm)/i,function(a){m=/a/.test(a)?0:12; if(p)c.tm_hour+=m});break;case "s":b=e(b,/^\d+/,function(a){a=parseInt(a,10);a=new Date(Date.UTC(a*1E3));q(a)});break;case "S":b=e(b,/^[0-5]\d/,function(a){a=parseInt(a,10);c.tm_sec=a});break;case "u":case "w":b=e(b,/^\d/,function(a){c.tm_wday=a-(j==="u")});break;case "U":case "V":case "W":break;case "y":b=e(b,/^\d?\d/,function(a){a=parseInt(a,10);c.tm_year=a>=69?a:a+100;h();if(!c.tm_yday)c.tm_yday=-1});break;case "Y":b=e(b,/^\d{1,4}/,function(a){a=parseInt(a,10)-1900;c.tm_year=a;h();if(!c.tm_yday)c.tm_yday= -1});break;case "z":break;case "Z":break;default:throw"Unrecognized formatting character in strptime()";}}catch(x){if(x==="No match in string")return false}++f}else if(g.charAt(f)!==k.charAt(b))if(k.charAt(b).search(v)!==-1){b++;f--}else{if(g.charAt(f).search(u)!==-1)return false}else b++;c.unparsed=k.slice(b);return c},
	
	// Méthodes portées depuis la classe Utile
	stripURL: function(url, len, replacement) {
		len = len || 22;
		replacement = replacement || '-';
		url = Utile.htmlEntitiesDecode(url, 2);
		url = url.substring(0, len);
		url = Utile.stripAccents(url).replace(/([^a-z0-9]+)/ig, replacement);
		url = url.replace(eval('/'+replacement+'+/g'), replacement); // remove duplicate replacement chars
		url = url.replace(eval('/(^'+replacement+'|'+replacement+'$)/g'), ''); // remove leading dash
		return url.toLowerCase();
	},
	
	stripAccentsFrom: [/À/g,/Á/g,/Â/g,/Ã/g,/Ä/g,/Å/g,/Æ/g,/æ/g,/à/g,/á/g,/â/g,/ã/g,/ä/g,/å/g,/Ò/g,/Ó/g,/Ô/g,/Õ/g,/Ö/g,/Ø/g,/ò/g,/ó/g,/ô/g,/õ/g,/ö/g,/ø/g,/È/g,/É/g,/Ê/g,/Ë/g,/è/g,/é/g,/ê/g,/ë/g,/Ç/g,/ç/g,/Ì/g,/Í/g,/Î/g,/Ï/g,/ì/g,/í/g,/î/g,/ï/g,/Ù/g,/Ú/g,/Û/g,/Ü/g,/ù/g,/ú/g,/û/g,/ü/g,/ý/g,/ÿ/g,/Ÿ/g,/Ý/g,/Ñ/g,/ñ/g],
	stripAccentsTo:   ['A', 'A', 'A', 'A', 'A', 'A', 'AE','ae','a', 'a', 'a', 'a', 'a', 'a', 'O', 'O', 'O', 'O', 'O', 'O', 'o', 'o', 'o', 'o', 'o', 'o', 'E', 'E', 'E', 'E', 'e', 'e', 'e', 'e', 'C', 'c', 'I', 'I', 'I', 'I', 'i', 'i', 'i', 'i', 'U', 'U', 'U', 'U', 'u', 'u', 'u', 'u', 'y', 'y', 'Y', 'Y', 'N', 'n'], 
	stripAccents: function(str) {
		for (var i = 0, iMax = Utile.stripAccentsFrom.length; i < iMax; i++)
			str = str.replace(Utile.stripAccentsFrom[i], Utile.stripAccentsTo[i]);
		return str;
	},
	
	addClassName: function(className, DOMElement) {
		var classNameList = DOMElement.className.split(' ');
		for (var i = 0, iMax = classNameList.length; i < iMax; i++)
			if (classNameList[i] == className) return;
		classNameList[i] = className;
		DOMElement.className = classNameList.join(' ');
	},
	
	removeClassName: function(className, DOMElement) {
		var classNameList = DOMElement.className.split(' '),
			newClassNameList = [],
			j = 0;
		for (var i = 0, iMax = classNameList.length; i < iMax; i++)
			if (classNameList[i] != className) newClassNameList[j++] = classNameList[i];
		DOMElement.className = newClassNameList.join(' ');
	},
	
	/**
	 * @return true si la classe a été rajoutée
	 */
	toggleClassName: function(className, DOMElement) {
		var classNameList = DOMElement.className.split(' '),
			newClassNameList = [],
			addClassName = true,
			j = 0 ;
		for (var i = 0, iMax = classNameList.length; i < iMax; i++) {
			if (classNameList[i] == className) {
				addClassName = false;
			} else {
				newClassNameList[j++] = classNameList[i];
			}
		}
		if (addClassName) newClassNameList[j++] = className; 
		DOMElement.className = newClassNameList.join(' ');
		return addClassName;
	},
	
	/**
	 * Récupère la position d'un élément à l'intérieur du document.body
	 */
	getBodyOffset: function(element) {
		if (element == document.body) {
			var data = {
				top: 0,
				left: 0,
				height: Utile.getElementHeight(element),
				width: Utile.getElementWidth(element)
			}
		} else {
			var data = {
				top: element.offsetTop,
				left: element.offsetLeft,
				height: element.offsetHeight,
				width: element.offsetWidth
			}
		}
		// Correction pour les éléments contenant des css float
		if (!data.height) {
			for (var i = 0, iMax = element.childNodes.length; i < iMax; i++) {
				data.height += Utile.getElementHeight(element.childNodes.item(i));
			}
		}
		if (element['offsetParent']) {
			var offsetParent = element['offsetParent'];
			while (offsetParent && offsetParent != document.body) {
				data.top += offsetParent.offsetTop;
				data.left += offsetParent.offsetLeft;
				offsetParent = offsetParent.offsetParent;
			}
		}
		return data;
	}
	
}
window.App = window.App || {};
App.Messages = App.Messages || {};

window.App.getText = function() {
	if (!arguments.length) return;
	var args = arguments;
	if (!App.Messages[App.lang]) return args[0];
	if (!App.Messages[App.lang][args[0]]) return args[0];
	args[0] = App.Messages[App.lang][args[0]];
	return Utile.sprintf.apply(this, args);
}
window.App.trad = window.App.getText;

jQuery.behaviors = (function() {
	var behaviors = [];
	return {
		register: function(behavior) { if (typeof behavior == 'function') behaviors.push(behavior); },
		apply:    function(node) {
			if (!node) node = document.body;
			for (var i = 0, iMax = behaviors.length; i < iMax; i++) behaviors[i](node);
		}
	}
})();

// pmercier: Prévoir l'utilisation de jQuery.live() après tests sosu IE6
jQuery.behaviors.register(function(node) {	

	jQuery('.jqOnglets', node).each(function() {
		jQuery(this).addClass('ui-tabs ui-widget ui-widget-content ui-corner-all')
					.children('ul').addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all')
					.children('li').addClass('ui-state-default ui-corner-top')
					.hover(
						function() {jQuery(this).addClass('ui-state-hover')},
						function() {jQuery(this).removeClass('ui-state-hover')}
					);
		
	}).click(function(event) {
		// On ignore les clics sur les onglets n'ayant pas de liens
		var ignoreHref = String(window.location.href).slice(-1) == "#" ? window.location.href : window.location.href + "#",
			target = event.target; 
		if (target.nodeName == "SPAN") {
			target = target.parentNode;
		}
		if (target.nodeName == 'A' && (target.href == "#" || target.href == ignoreHref)) {
				return true;
		}
		// Appel du gestionnaire onUnload si il existe
		if (window.App['onUnload'] && event.target.nodeName != "UL") {
			App.onUnload(event);
		}
	});
	
	jQuery('.jqConfirmOnClick', node).click(function (event) {
		var params = Utile.getParams(this);
		if (!params['confirmOnClickText']) return false;
		if (!window.confirm(params['confirmOnClickText'])) {
			event.stopPropagation();
			return false;
		}
	});
	
	jQuery('textarea.jqFCKEditor', node).each(function() {
		if (!this['id'] || this['id'] == '') return;
		var params = Utile.getParams(this, {fckEditorToolbarSet:'Basic'});
		var oFCKeditor = new FCKeditor(this.id) ;
		oFCKeditor.BasePath = window.App.root + "js/fckeditor/" ;
		oFCKeditor.ToolbarSet = params.fckEditorToolbarSet;
		oFCKeditor.Config = oFCKeditor['Config'] || {};
		if (params['fckEditorCounterId'])
			oFCKeditor.Config.CounterId = params['fckEditorCounterId'];
		if (params['fckEditorStylesXmlPath'])
			oFCKeditor.Config.StylesXmlPath = params['fckEditorStylesXmlPath'];
		if (params['fckEditorEditorAreaCSS'])
			oFCKeditor.Config.EditorAreaCSS = params['fckEditorEditorAreaCSS'];
		if (params['fckEditorHeight'])
			oFCKeditor.Height = params['fckEditorHeight'];
		oFCKeditor.ReplaceTextarea();
	});
	
	// Gestion des Fieldsets
	jQuery(":input", jQuery("form", node)).focus(function() {
		jQuery(this).parents(".jqFieldsetFocus").addClass('hasFocusedElement').addClass('cadreGrisFonce').removeClass('cadreGris');
	}).blur(function(){
		jQuery(this).parents(".jqFieldsetFocus").removeClass('hasFocusedElement').addClass('cadreGris').removeClass('cadreGrisFonce');
	})
	
	// Gestion des tips dans les champs de recherches
	jQuery("input.jqInputTip", node).each(function() {
		if (!this.id) this.id = Utile.randomUID();
		var params = Utile.getParams(this, {inputTextTip:''});
		jQuery(this).emptyonclick({defaultValue: params.inputTextTip, defaultClass: 'defaultValue'});
		if (this.value == '') this.value = params.inputTextTip;
	});
	
	// Mise en place des différents artefacts
	//Gère l'afficahge d'un calendrier date & heure+minute
	jQuery(".jqDateTimePicker", node).each(function(index, elem) {
		
		var jElem = jQuery(elem),
			lang  = elem.getAttribute('lang');
		if (lang == '') lang = 'fr';
		
		jElem.datetimepicker({
			ampm: false,
			timeText: '',
			hourText: 'Heure',
			minuteText: 'Minute'
		});
	});
	
	
	// Mise en place des différents artefacts
	jQuery(".jqDatePicker", node).each(function(index, elem) {
		
		var jElem = jQuery(elem),
			lang  = elem.getAttribute('lang');
		if (lang == '') lang = 'fr';
		
		var getDatePickerOptions = function(input, parseMinMax) {
			
			var options = {changeYear: true};
			var params = Utile.getParams(input, {datePickerMin:'',datePickerMax:''});
			var dateMin = new String(params.datePickerMin.constructor == Date ? Utile.date('d/m/Y', params.datePickerMin) : params.datePickerMin);
			var dateMax = new String(params.datePickerMax.constructor == Date ? Utile.date('d/m/Y', params.datePickerMax) : params.datePickerMax);
			
			if (dateMin.charAt(0) == '#') { // Utilisation de la valeur du champs input
				if (dateMin.slice(1) != input.id || parseMinMax) {
					var inputMin = document.getElementById(dateMin.slice(1));
					if (inputMin && /^(?:\d{2}(\/|-)){2}\d{4}$/.test(inputMin.value))
						options.minDate = Utile.frDateToISODate(inputMin.value, true);
				}
			}
			else {
				options.minDate = dateMin != '' ? Utile.frDateToISODate(dateMin, true) : null;
			}
			
			if (dateMax.charAt(0) == '#') { // Utilisation de la valeur du champs input
				if (dateMax.slice(1) != input.id || parseMinMax) {
					var inputMax = document.getElementById(dateMax.slice(1));
					if (inputMax && /^(?:\d{2}(\/|-)){2}\d{4}$/.test(inputMax.value))
						options.maxDate = Utile.frDateToISODate(inputMax.value, true);
				}
			}
			else {
				options.maxDate = dateMax != '' ? Utile.frDateToISODate(dateMax, true) : null;
			}
			
			// Gestion de l'heure
			options.showTime = params['datePickerShowTime'] || false;
			options.stepHours = params['datePickerStepHours'] || 1;
			options.stepMinutes = params['datePickerStepMinutes'] || 5;
			options.time24h = params['datePickertime24h'] || true;
			
			options.zIndex = params['datePickerZIndex'] || false;
			
			return options;
		}
		
		var checkDateRange = function(elem) {
			if (elem['nodeName'] != 'INPUT') return false;
			var options = getDatePickerOptions(elem, true);
			
			// On vérifie juste que la date supérieur l'est bien
			if (options['maxDate'] && options['minDate']) {
				return !(options.maxDate < options.minDate);
			}
			
			return true;
		}
		
		// Sélecteur de dates
		jElem.datepicker(jQuery.extend({
			beforeShow: function(input, inst) {
				var options = getDatePickerOptions(input);
				if (options.zIndex) inst.dpDiv[0].style.zIndex = options.zIndex;
				return options;
			}
		}, jQuery.datepicker.regional[lang]));
		
		// On lie la vérification de la plage de date au formulaire
		if (elem.form && elem.form['nodeName'] == "FORM") {
			
			var options = Utile.getParams(elem, {datePickerMin: '', datePickerMax: ''});
			
			// Si le range 
			var doBind = (options['datePickerMin'][0] != '#' && options['datePickerMax'][0] != '#');
			// Cas d'un range composé de seulement un input
			doBind |= (options['datePickerMin'][0] != '#' ^ options['datePickerMax'][0] != '#');
			// Cas d'un dateRange composé de deux inputs: on ne lie que sur l'un des deux
			doBind |= (options['datePickerMin'][0] == '#' && options['datePickerMax'][0] == '#' && elem.id == options['datePickerMin'].slice(1));
			
			if (doBind) {
				jQuery(elem.form).submit(function() {
					var options = getDatePickerOptions(elem, true);
					
					// On vérifie juste que la date supérieur l'est bien
					if (options['maxDate'] && options['minDate']) {
						return !(options.maxDate < options.minDate);
					}
					return true;
				});
			}
		}
	});

	// Gestion des focus pour les input
	jQuery(":input", node).focus(function() {
		jQuery(this).addClass('hasFocus');
	}).blur(function() {
		jQuery(this).removeClass('hasFocus');
	})
	
	// Gestion des popup depuis un lien
	jQuery("a.jqPopup", node).click(function(event) {
		jqPopup(event.currentTarget);
		event.stopPropagation();
		return false;
	});
	
	// Permet a un élément interne de provoquer le rechargement
	jQuery('.jqPopupReplace', node).each(function() {
		var jThis = jQuery(this);
		if (this.nodeName == 'FORM') {
			jThis.submit(jqPopupReplace);
		}
		else if (this.nodeName == 'A') {
			jThis.click(jqPopupReplace);
		}
	});

	
	jQuery(".jqSubmitOnClick", node).click(function(event) {
		var form = this['form'] || jQuery(this).closest('form').get(0);
		if (form['submit']) jQuery(form).trigger('submit', {originalEvent: event});
	});
	
	
	jQuery(".jqSubmitOnChange", node).change(function(event) {
		var form = this['form'] || jQuery(this).closest('form').get(0);
		if (form['submit']) jQuery(form).trigger('submit', {originalEvent: event});
	});
	
	jQuery(".jqToggleCheckbox", node).click(function(event) {
		
		// Empèche le toggle de se faire si l'utilisateur a cliqué sur un lien
		if (jQuery(event.target).closest('a').get(0)) {
			return true;
		}
		// Empèche le toggle de se faire si l'utilisateur a cliqué sur la checkbox
		if (jQuery(event.target).is('input') || jQuery(event.target).is('label')) {
			return true;
		}
		var params = Utile.getParams(this);
		if (!params['toggleCheckboxId']) return false;
		var checkbox = document.getElementById(params['toggleCheckboxId']);
		if (!checkbox) return false;
		if (checkbox.disabled) return false;
		if (checkbox.type == 'checkbox') checkbox.checked =! checkbox.checked;
		
	});
	
	// Limite la taille d'un champs textarea
	jQuery(".jqTextareaRestriction", node).keypress(function(event) {
		
		var textarea = event.target;
		Utile.parseTextareaCaretPosition(textarea);
		
		var	params = Utile.getParams(textarea, {
				textareaRestrictionMaxCol:0,
				textareaRestrictionMaxRow:0,
				textareaRestrictionMaxLength:0
			}),
			textareaValue = textarea.value.replace("\r", ''), // On ignore les retours chariots
			caretPosition = textarea.selectionStart,
			textLines = textareaValue.split("\n"),
			caretRow  = textareaValue.substr(0, caretPosition).split("\n").length - 1,
			caretCol  = (textareaValue.substr(0, caretPosition).split("\n").pop()).length,
			currentLine = textLines[caretRow];
		
		// Retour à la ligne ?
		if (params.textareaRestrictionMaxRow > 0 && event.keyCode == 13) {
			if (textLines.length >= params.textareaRestrictionMaxRow) {
				event.stopPropagation();
				return false;
			}
		}
		
		// Pas trop de caractères sur la même ligne ?
		if (params.textareaRestrictionMaxRow > 0 && event.which >= 30) {
			if (currentLine.length >= params.textareaRestrictionMaxCol - 1) {
				event.stopPropagation();
				return false;
			}
		}
		
		// Pas trop de caractères dans le textarea ?
		if (params.textareaRestrictionMaxLength > 0 && event.which >= 30) {
			if (textareaValue.length >= params.textareaRestrictionMaxLength - 1) {
				event.stopPropagation();
				return false;
			}
		}
		
		return true;
	});

	jQuery(".jqRangeSlider", node).each(function() {
		var minInput	= document.getElementById(this.id+'_min'),
			maxInput	= document.getElementById(this.id+'_max'),
			valueInput	= document.getElementById(this.id+'_value');
		var params = Utile.getParams(this);
		var options = {
				min:	params.sliderMin || 0,
				max:	params.sliderMax || 500,
				range:	params.sliderRange || true
		}
		jQuery(this).slider({
			range: options.range,
			min: options.min,
			max: options.max,
			values: [parseInt(minInput.value), parseInt(maxInput.value)],
			slide: function(event, ui) {
				var parent		= event.target,
					minHandle	= parent.childNodes[1] || null,
					maxHandle	= parent.childNodes[2] || null,
					valueHandle	= parent.childNodes[1] || null;
				
				if (minInput && maxInput) {
					if (ui.handle == minHandle)
						minInput.value = ui.value;
					else if (ui.handle == maxHandle)
						maxInput.value = ui.value;
				}
				else if (valueInput)
					valueInput.value = ui.value;
			},
			stop: function(event, ui) {
				document.forms.form_filtre.submit();
			}
		});
	});
	
	
	// accordéon
	
	jQuery('.jqAccordion', node).each(function() {
		var jThis = jQuery(this),
			params = Utile.getParams(this);
		if (params['accordionActive'] === undefined)
			params['accordionActive'] = 0;
		jThis.accordion({
			collapsible: true,
			animated: false,
			autoHeight: false,
			active: params['accordionActive']
		});
	});
	
	jQuery('.jqUITabs', node).tabs();
	
	// onglets	
	jQuery('.jqTabs', node).each(function() {
		var parentThis = this;
		jQuery('.jqPanel:not(.on)', this).hide();
		jQuery('.jqOnglets > li', this).click(function () {
			jQuery('.jqOnglets > li', parentThis).removeClass('on');
			jQuery(this).addClass('on');
			
			var tabId = jQuery(this).children('a').attr('href');			
			jQuery('.jqPanel', parentThis).hide();
			jQuery(tabId, parentThis).show();
			return false;
		});
	});
	
	var jTooltips = jQuery('*[title].jqTooltip', node);
	if (jTooltips.length) {
		// Si la div du tooltip n'est pas présent on le rajoute avant d'appliquer le tooltip
		var tooltipDiv = document.getElementById('__tooltipDiv');
		if (!tooltipDiv) {
			tooltipDiv = document.createElement('DIV');
			tooltipDiv.id = '__tooltipDiv';
			tooltipDiv.innerHTML = '&nbsp;';
			document.body.appendChild(tooltipDiv);
		}
		jTooltips.tooltip('#__tooltipDiv');
	}
	
	jQuery('.jqAutoFocus', node).each(function(){this.focus()});
	
	jQuery('table.ui-widget-content tbody tr', node).hover(
		function() {
			$(this).addClass("ui-state-hover ui-state-highlight");
		},
		function() {
			$(this).removeClass("ui-state-hover ui-state-highlight");
	}).click(function(event) {
		
		// Si c'est un lien, on gère le lien
		if (event.target.nodeName == 'A') return true;
		
		// Sinon si le premier enfant est un noeud A avec un display block, on le considère comme cliqué
		var jLinks = jQuery("a", event.target),
			jNodes = jQuery(":not(a)", event.target);
		// FIXME
		/*if (jLinks.length == 1 && !jNodes.length) {
			var newHref = jLinks.trigger('click');
			App.Dialog.alert(newHref);
			//.get(0).href;
			//if (newHref !== false) window.location = newHref;
			event.stopPropagation();
			return false;
		}*/
		// Sinon, si la première collone contient une case à cocher ...
		if (event.target.nodeName == 'INPUT' && event.target.type == "checkbox") {
			var jCheckBox = jQuery(event.target);
			jCheckBox.get(0).checked = !jCheckBox.get(0).checked;
		} else {
			var jCheckBox = jQuery('td:first-child :checkbox', this);
		}
		
		if (jCheckBox.length) {
			var checkBox = jCheckBox.get(0);
			checkBox.checked = !checkBox.checked;
			jQuery(this).toggleClass('checkedLine');
		}
	});
	
	
	jQuery('.jqCount', node).each(function () {
		var jThis = jQuery(this),
			params = Utile.getParams(this);
		params['countDisplay'] = params['countDisplay'] || this.id + "_count";
		var countDisplayElement = typeof(params.countDisplay) == "object" ? params.countDisplay : document.getElementById(params.countDisplay);
		
		jqCount(this, countDisplayElement);
		jThis.keyup(function() {
			jqCount(this, countDisplayElement);
		}).change(function() {
			jqCount(this, countDisplayElement);
		});
		
	})
	
	if (jQuery.fn.mask) {
		jQuery('.jqMask', node).each(function() {
			var params = Utile.getParams(this);
			if (!params['inputMask']) return false;
			jQuery(this).mask(params['inputMask']);
		});
	}
//	
//	if (window.App['onUnload']) {
//		jQuery('form', node).submit(window.App.onUnload);
//	}
	
	// Uniquement pour IE >= 5.5 && < 7.0
	if (jQuery.browser.msie) {
		var version = parseFloat(jQuery.browser.version.replace(/^(\d(?:\.\d)?).*$/, '$1'));
		if (version >= 5.5 && version < 7.0) {
			jQuery('.jqPNG24', node).each(function() {
      	         var imgName = this.src.toUpperCase()
      	         if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
      	         {
      	            var imgID 	 = (this.id) 		? "id='" + this.id + "' " 			: "",
      	            	imgClass = (this.className)	? "class='" + this.className + "' " : "",
      	            	imgTitle = (this.title)		? "title='" + this.title + "' " 	: "title='" + this.alt + "' ",
      	            	imgStyle = "display:inline-block;" + this.style.cssText;
      	            
      	            if (this.align == "left")    imgStyle = "float:left;"  + imgStyle;
      	            if (this.align == "right")   imgStyle = "float:right;" + imgStyle;
      	            if (this.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
      	            
      	            var strNewHTML = "<span " + imgID + imgClass + imgTitle
      	            	+ " style=\"" + "width:" + this.width + "px; height:" + this.height + "px;" + imgStyle + ";"
      	            	+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
      	            	+ "(src=\'" + this.src + "\', sizingMethod='scale');\"></span>";
      	          this.outerHTML = strNewHTML;
      	         }
			});
		}
	}
	
});

/**
* @return DOMElement Le conteneur des donnée
*/
jqPopup = function(elem, url, data, callback, options) {
	
	// Création de la div en utilisant DOM car un lag existe dans la synchro
	var body  = document.createElement("div"),
		jBody = jQuery(body);
	
	
	// Traitement des options
	if (!options) options = {};
	var jqThis = jQuery(elem),
		params = Utile.getParams(elem, {popupFrame: false, popupReloadOnClose: false});
	jQuery.extend(params, options);
	if (params['popupAutoResize']) {
		params.popupAutoHeight = true;
		params.popupAutoWidth  = true;
	}
	var options = {
		draggable:   params['popupDraggable']   !== undefined ? params.popupDraggable   : false,
		modal:       params['popupModal']       !== undefined ? params.popupModal       : true,
		resizable:   params['popupResizable']   !== undefined ? params.popupResizable   : true,
		autoOpen:    params['popupAutoOpen']    !== undefined ? params.popupAutoOpen    : true,
		position:    params['popupPosition']    !== undefined ? params.popupPosition    : 'center',
		autoHeight:  params['popupAutoHeight']  !== undefined ? params.popupAutoHeight  : false,
		autoWidth:   params['popupAutoWidth']   !== undefined ? params.popupAutoWidth   : false,
		dialogClass: params['popupDialogClass'] !== undefined ? params.popupDialogClass : 'jqDialogSimple',
		title:		 params['popupTitle']       !== undefined ? params.popupTitle       : '',
		close: function(event, ui) {
			jQuery(elem).dialog("destroy");
			var parentNode = body.parentNode;
			parentNode.removeChild(body);
			parentNode.parentNode.removeChild(parentNode);
		},
		open: function(dialogEvent) {
			jQuery(".ui-widget-overlay").click(function() {
				jQuery(dialogEvent.target).dialog("close");
				if (params.popupReloadOnClose) window.location = window.location;
			});
		}
	};
	
	if (params['popupWidth'])  options.width  = params.popupWidth;
	if (params['popupHeight']) options.height = params.popupHeight;
	if (!callback && params['popupCallback']) {
		callback = window[params['popupCallback']];
	}
	
	body.options = options;
	
	var tmpDivId = (elem.id || Utile.randomUID()) + '_popup',
		tmpDivFrameId = tmpDivId + '_ifrm';
	
	body.id = '#'+tmpDivId;
	
	if (!url && elem.nodeName == 'A') {
		url = elem.href.replace('#', ' #');
	}
	
	if (!data) data = null;

	if (params.popupFrame) {
		// Impossible de charger par POST. On envoi les données par GET
		if (data) {
			var serializedData = jQuery.param(data);
			url += url.search(/\?/) === false ? '?' : '&';
			url += serializedData;
		}
		
		jBody.append('<iframe src="'+url+'" style="width:100%;height:100%;border:0;frameborder:0;padding:0;margin:0" id="'+tmpDivFrameId+'"></iframe>');
		document.body.appendChild(body);
		jBody.dialog(options);
		if (jQuery.isFunction(callback)) {
			var popupIFrame = document.getElementById(tmpDivFrameId),
				popupWindow = popupIFrame.contentWindow,
				popupDocument = popupIFrame.contentDoocument;
			jQuery(popupIFrame).load(callback);
		}
	}
	else {
		if (!data) data = {};
		data.fromJs = true;
		
		if (!jQuery.isFunction(callback)) callback = function(responseText, textStatus, XMLHttpRequest) {
			if (Utile) Utile.dialogResize(body);
			if (jQuery.behaviors) jQuery.behaviors.apply(body);
		}
		jBody.append('<div style="height:100%;background: white url(\'' + window.App.root + 'images/green-ajax-loader.gif\') no-repeat center center">&nbsp;</div>');
		jBody.dialog(options).load(url, data, callback);
	}
	
	// Dans le cas d'un redimensionnement de fenêtre
	jQuery(window).resize(function() {
		Utile.dialogResize(body);
	});
	
	return body;
	
}

jqPopupReplace = function(event) {
	
	var target	= event.target,
		data	= null,
		url		= null,
		method  = 'GET';
	
	// On recherche la div qui contient les données
	var jBody = jQuery(target).parents('.ui-dialog-content.ui-widget-content');
	var body  = jBody.get(0);
	if (!jBody) return true;
	
	if (target.nodeName == 'FORM') {
		var form  = target,
			jForm = jQuery(target),
			formMethod = form.method.toUpperCase();
		
		data  = jForm.serialize();
		data += (data == '' ? '' : '&')+'fromJs=1';
		url   = form.action;
		if (formMethod == 'POST') {
			data = Utile.deserialize(data);
		}
		else {
			url += (/\?/.test(url) ? '&' : '?') + data;
		}
	}
	else if (target.nodeName == 'A') {
		url = target.href;
	}
	
	jBody.load(url, data, function() {
		if (Utile) Utile.dialogResize(body);
		if (jQuery.behaviors) jQuery.behaviors.apply(body);
	});
	
	event.stopPropagation();
	return false; 
	
}

jqCount = function(countElement, countDisplayElement) {
	var count = 0;
	if (countElement['value'] !== undefined)
		count = countElement.value.length;
	else if (countElement['childNodes'] !== undefined)
		count = countElement.childNodes.length
	
	if (countDisplayElement['value'] !== undefined)
		countDisplayElement.value = count;
	else if (countDisplayElement['innerHTML'] !== undefined)
		countDisplayElement.innerHTML = count;
}

/**
 * jQuery emptyonclick plugin
 * Created by Andreas Creten (andreas@madewithlove.be) on 2008-06-06.
 * Copyright (c) 2008 madewithlove. All rights reserved.
 * Version: 1.2
 */
jQuery.fn.extend({
   emptyonclick: function(options) {
       return this.each(function() {
           new jQuery.EmptyOnClick(this, options);
       });
   }
});

jQuery.EmptyOnClick = function(element, options) {
   var defaultValue = options.defaultValue,
   	   defaultClass = options.defaultClass || 'defaultValue';
   // Bind event handlers to the element
   jQuery(element)
   // On Focus: Store the default value if it's not set, empty the field
   .bind("focus", function(e) {
       if(defaultValue == jQuery(this).val())
    	   jQuery(this).val('').removeClass(defaultClass);
    })
   // On Blur: if the field is empty, reset the default value
   .bind("blur", function(e) {
       if(!jQuery(this).val()) {
    	   jQuery(this).val(defaultValue).addClass(defaultClass);
       }
   }).each(function(e) {
       if(!jQuery(this).val()) {
    	   jQuery(this).val(defaultValue).addClass(defaultClass);
       }
   });
    // Search for the form which has the element
   jQuery("form:has(#"+element.id+")")
   // If the form gets resetted, set the default value back
   .bind('reset', function(e) {
	   jQuery(element).val(defaultValue).addClass(defaultClass);
       jQuery(element).removeClass(options.changeClass);
   }) 
   // If the form gets submitted empty, remove the default values
   .bind('submit', function(e) {
       if(jQuery(element).val() == defaultValue)
    	   jQuery(element).val('').addClass(defaultClass);
   });
};

jQuery(function() {

	window.store = {};
	window.App   = window['App'] || {};
	
	// IE ?
	if (jQuery.browser.msie) {
		App.browserType = "ie";
	}
	else if (jQuery.browser.safari) {
		App.browserType = "safari";
	}
	else if (jQuery.browser.mozilla) {
		App.browserType = "mozilla";
	}
	else if (jQuery.browser.opera) {
		App.browserType = "opera";
	}
	document.body.className = App.browserType + " " + document.body.className;
	
	// Définition de la langue d'après les prérequis de Bedouk
	window.App.tld = String(window.location).replace(/^.+:\/\/(.*?\.)+(\w+)\/.*$/, '$2');
	window.App.lang = 'fr';
	
	// Configurations
	jQuery.datepicker.regional['fr'] = {closeText:"Ok",prevText:"Prec",nextText:"Suiv",currentText:"Aujourd'hui",monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fev","Mar","Avr","Mai","Jun","Jul","Aout","Sep","Oct","Nov","Dec"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],dayNamesMin:["Di","Lu","Ma","Me","Je","Ve","Sa"],dateFormat:"dd/mm/yy",firstDay:1,isRTL:false};
	jQuery.datepicker.regional['en'] = {closeText:"Ok",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};
	
	jQuery.datepicker.setDefaults(jQuery.extend({
		showMonthAfterYear: false,
		buttonImage: window.App.root + 'images/datepicker.gif',
		showOn: 'button'
	}, jQuery.datepicker.regional[window.App.lang]));

	jQuery.behaviors.apply();
	
	//all hover and click logic for buttons
	$(".fg-button:not(.ui-state-disabled)").hover(
		function(){
			$(this).addClass("ui-state-hover");
		},
		function(){
			$(this).removeClass("ui-state-hover");
		}
	).mousedown(function(){
		$(this).parents('.fg-buttonset-single:first').find(".fg-button.ui-state-active").removeClass("ui-state-active");
		if( $(this).is('.ui-state-active.fg-button-toggleable, .fg-buttonset-multi .ui-state-active') ){ $(this).removeClass("ui-state-active"); }
		else { $(this).addClass("ui-state-active"); }
		return true;
	}).mouseup(function() {
		if(! $(this).is('.fg-button-toggleable, .fg-buttonset-single .fg-button, .fg-buttonset-multi .fg-button') ){
			$(this).removeClass("ui-state-active");
		}
		return true;
	});

});

