var DEBUG=true;

$j(document).ready(function($){

  $.datepicker.regional['fr'] = {
	  closeText: 'Fermer',
	  prevText: '&#x3c;Préc',
	  nextText: 'Suiv&#x3e;',
	  currentText: 'Courant',
	  monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin',
	  'Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
	  monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
	  'Jul','Aoû','Sep','Oct','Nov','Déc'],
	  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};
  $.datepicker.setDefaults($.datepicker.regional['fr']);

  $.datepicker.setDefaults($.extend({
       showButtonPanel: true
      ,beforeShow: function(input) {
        $("#ui-datepicker-div").css('z-index','1003');
      }

    }, $.datepicker.regional['fr']));


  $('a.jouteur').live('click',function(e){
    if(e.button!=0){ return false };

    var $this = $(this);
	var id = this.href.split('#')[1];

	$this.addClass('jouteur-loading');
	showJouteurProp(id,function(){$this.removeClass('jouteur-loading');});
	return false;

  });

  $('a.equipe').live('click',function(e){
    
    if(e.button!=0){ return false };

	var $this = $(this);
	var id = this.href.split('#')[1];

	$this.addClass('equipe-loading');
	showTeamProp(id,function(){$this.removeClass('equipe-loading');});
	return false;

  });

});

/**
 *  @description Identify elements by giving them a unique ID for the current document
 *  @author Jp Siffert
 *  @email plugin hostedAt chezouam.fr
 *  @version 1.0
 *  @param object optional object of options, see $.fn.identify.defaults
 *  @link
 *  @return the jQuery object for chaining
 *
 *  @example $('SPAN').identify();
 */
(function($){

    $.fn.identify = function(options) {
        var opts = $.extend(true,{}, $.fn.identify.defaults, options);

        return this.each(function() {
                $this = $(this);
                var o = ($.metadata ? $.extend(true,{},opts,$this.metadata()) : opts);

                var id=$this.attr('id');

                if(id){
                    if(o.unique == false || $('[id='+id+']').length<=1){
                        return;
                    }
                }

                do {
                    id = o.prefix + o.separator + o.guid(o.guidSeparator);
                } while($('#' + id).length > 0);

                $this.attr('id', id);
            });
    };

    /**
     *  @description Object of identify plugin options
     **/
    $.fn.identify.defaults = {
         prefix : 'id'  // prefix used for the generated id
        /**
         * @description inspired from the exelent article http://note19.com/2007/05/27/javascript-guid-generator/
         * @param string sep, the separator use to return de generated guid (default = "-")
         */
        ,guid : function(sep){
              /**
               * @description Internal function that returns a hexadecimal number
               * @return an random hexa dÃ©cimal value between 0000 and FFFF
               */
              function S4() {
               return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
            }

            if(typeof sep == "undefined") sep ="-"

            return (S4()+S4()+sep+S4()+sep+S4()+sep+S4()+sep+S4()+S4()+S4());
        }
        ,unique : false             // If an id is found, test if it's unique or assign a new one
        ,separator : '_'            // Separator used between prefix and guid
        ,guidSeparator : '-'        // Separator unsed between guid's elements'

    }
})(jQuery);


/************************************************
* Retourne true si le type de l'objet est objet
* sinon retourne false
************************************************/
function isObj(obj){
	return (typeof(obj)=='object' && obj!=null);
}

/************************************************
* Retourne true si le type de l'objet est string
* sinon retourne false
************************************************/
function isStr(obj){
	return (typeof(obj)=='string');
}

/************************************************
* Retourne true si le type de l'objet est un tableau
* sinon retourne false
************************************************/
function isArray(obj){
	if(isObj)	// Un tableau est un Objet
		return (obj.push && obj.pop)
	else
		return false;
}


/************************************************
* Retourne true si le type de l'objet est function
* sinon retourne false
************************************************/
function isFunc(obj){
	return (typeof(obj)=='function');
}


/************************************************
* Retourne le x et le y du curseur de la souris
************************************************/
function sourisPos(e){
	if(!e)	
		e=window.event;

	var x=0;
	var y=0;
	
	if(e.clientX!=null){
		x=e.clientX;		
		y=e.clientY;
	}
	else if(e.pageX!=null){
		x=e.pageX;		
		y=e.pageY;
	}
	
	return {"x":x,"y":y}
}

/************************************************
* Fonctions du DOM 
************************************************/ 

/************************************************
* Enlève le noeud child du père parent
************************************************/
function removeChild(child,parent){
	if(!isObj(child)) return null;
	
	if(!isObj(parent))
		parent=parentNode(child);
	
	if(parent.removeChild)
		return parent.removeChild(child);
}


/************************************************
* Retourne le noeud avant l'objet obj (le grand-frère)
************************************************/
function previousSibling(obj){
	if(!isObj(obj)) return null;
	
	if(obj.previousSibling)
		return obj.previousSibling;
}

/************************************************
* Retourne le frère de tagName = tagName avant l'objet obj (le petit frère de tagName)
************************************************/
function previousSiblingByTagName(obj,tagName){
	if(!isObj(obj)) return null;
	
	if(!tagName && obj.previousSibling)
		return obj.previousSibling;
	
	var i=0;
	
	while(isObj(obj) && obj.tagName!=tagName){
		obj=previousSibling(obj);
		i++;
	};
	
	return obj;
}


/************************************************
* Retourne le dernier noeud au même niveau que l'objet obj
************************************************/
function lastSibling(obj){
	if(!isObj(obj)) return null;
	
	var last=obj;
	while((obj=nextSibling(obj))){
	}
		return last;
}

/************************************************
* Retourne le premier noeud au même niveau que l'objet obj
************************************************/
function firstSibling(obj){
	if(!isObj(obj)) return null;
	
	var prev=obj;
	
	while((obj=previousSibling(obj))){
		prev=obj;
	}
	
	return prev;
}


/************************************************
* Retourne le noeud aprés l'objet obj (le petit frère)
************************************************/
function nextSibling(obj){
	if(!isObj(obj)) return null;
	
	if(obj.nextSibling)
		return obj.nextSibling;
}

/************************************************
* Retourne le dernier noeud de l'objet obj
************************************************/
function lastChild(obj){
	if(!isObj(obj)) return null;
	
	if(obj.lastChild)
		return obj.lastChild;
	
	return null;
}

/************************************************
* Retourne le premier noeud de l'objet obj
************************************************/
function firstChild(obj){
	if(!isObj(obj)) return null;
	
	if(obj.firstChild)
		return obj.firstChild;
	
	return null;
}


/************************************************
* Insérer oNew juste avant obj (en fait un grd frère)
* dans l'ordre des noeuds
* Cette fonction est une sur fonction de insertBefore
* elle sert simplement a rajouter un frère a obj,
* pas de sa position potentielle, elle prend moins 
* d'argument que insertBefore tout court
************************************************/
function insertBeforeEl(obj,oNew){
	if(!(isObj(obj) && isObj(oNew))) return null;

	if(obj.insertBefore)
		return insertBefore(parentNode(obj),oNew,obj);
	
	return null;
}

/************************************************
* Insérer oNew juste aprés obj (en fait un pt frère)
* dans l'ordre des noeuds
* Cette fonction est une sur fonction de insertBefore
* elle sert simplement a rajouter un frère a obj,
* pas de sa position potentielle, elle prend moins 
* d'argument que insertBefore tout court
************************************************/
function insertAfterEl(obj,oNew){
	if(!(isObj(obj) && isObj(oNew))) return null;

	if(obj.insertBefore)
		return insertBefore(parentNode(obj),oNew,nextSibling(obj));
	
	return null;
}


/************************************************
* Insérer oNew juste avant parent ( ou avant si oChild!=null) 
* dans l'ordre des noeuds
************************************************/
function insertBefore(parent,oNew,oChild){
	if(!(isObj(parent) && isObj(oNew))) return null;

	if(parent.insertBefore)
		return parent.insertBefore(oNew,oChild);
	
	return null;
}

/************************************************
* Retourne le noeud de tagName = tagName avant l'objet obj (l'ancètre)
************************************************/
function parentNodeByTagName(obj,tagName){
	if(!isObj(obj)) return null;
	
	if(!tagName)
		return parentNode(obj);
	
	var i=0;
	
	while(isObj(obj) && obj.tagName!=tagName){
		obj=parentNode(obj);
	};
	
	return obj;
}


/************************************************
*	Retourne le noeud parent de obj
************************************************/

function parentNode(obj){
	return obj.parentNode;
}

/************************************************
* La fonction copy l'objet, et le retourne
************************************************/
function cloneNode(obj,deep){
	if(deep==null)
		deep=true;
		
	return obj.cloneNode(deep);
}

/************************************************
*	La fonction remplace le node oldChild 
*	par le node newChild dans parent
************************************************/
function replaceChild(newChild,oldChild,parent){
	if(!parent)
		parent=parentNode(oldChild);

	if(parent)
		return parent.replaceChild(newChild,oldChild);
	else
		return false;
}

/************************************************
*	La fonction retourne le parent de obj
************************************************/
function parentNode(obj){
	if(obj.parentNode)
		return obj.parentNode;
}

/************************************************
*	La fonction retourne l'ancètre parent de obj ayant comme tagName tagNamz
************************************************/
function parentNodeByTagName(obj,tagName){
	while((obj=obj.parentNode) && obj)
		if(obj.tagName && obj.tagName.toUpperCase()==tagName.toUpperCase())
			break;
		
	return obj;
}


/************************************************
* appendChild(obj,child)
* 
* Ajout un enfant child à obj retourne 
* l'enfant
************************************************/
function appendChild(obj,child){
	obj.appendChild(child);
	return child;
}

/************************************************
* createElement(type)
* Créer un élement de type type et le retourne
************************************************/
function createElement(type){
	return document.createElement(type.toUpperCase());
}

// JavaScript Document
function getId(obj){
	if(obj=$(obj)){
	    if(!obj.id){
	        var tmp=0;
	        do
	            tmp='id'+parseInt(Math.random()*1000000,10);
	        while($(tmp));
	        obj.id=tmp;
		}
		return obj.id;
	}
	return null;
}

/************************************************
*   getId(obj)
*
*   retourne l'objet d'id = id ou de nom = id
************************************************

function getId(obj){
	obj=getObj(obj);

	if(!isObj(obj))
		return;

	var i=0;
	while(getObj(obj.id)!=obj && ++i<100){
		obj.id='randid'+parseInt(Math.random(10)*100000000);
	};
}

*/

/************************************************
*   getObj(id,parent)
*
*   retourne l'objet d'id = id ou de nom = id
************************************************/  
function getObj(id,parent){

	if(isObj(id))
		return id;

	if(parent==null)
		parent=document;

    if(parent.getElementById)
        return parent.getElementById(id);
    
    if(parent.getElementsByName)
        return parent.getElementsByName(id)[0];
    
   return null; 
}

/************************************************
*   getObjByTagName(id)
*
*   retourne les objets de tage = name
************************************************/  
function getObjByTagName(name,parent){

	if(parent==null)
		parent=document;
	
	if(isArray(name)){
		var ret = new Array();
		for(arg in name){
			var coll = parent.getElementsByTagName(name[arg]);
			for(var i=0;i<=coll.length-1;i++){
				ret.push(coll[i]);
			}
		}
		
		return ret;
	}
	else{
		return parent.getElementsByTagName(name);
	}
   
   return null; 
}

/************************************************
 * La fonction fait clignoter obj avec le style
 * "style", pour un nombre "cnt " de fois avec 
 *  un interval de "time"
 *     
 ***********************************************/
function blinkObj(obj,style,cnt,time){

	if(cnt==null)
		cnt=6;
	if(time==null)
		time=100;
	
	if(time==0)
		return;
	
	if(style=='' || style==null)
		style='blink';
	
	var intervalId=setInterval(function(){
		
		if(cnt % 2 !=0)
			addClassName(obj,style);
		else
			remClassName(obj,style);
		
		cnt--;
		
		if(cnt==0)
			clearInterval(intervalId);
	},time);

}

/************************************************
* setDisplay(id,d1)
* 
* CHnage le display de l'objet id, pour d1
************************************************/
function setDisplay(id,d1){
	var conv='';
	
	if(d1==='' || d1===true)	d1='block';
	if(d1===0 || d1===false)	d1='none';
	
	if(isStr(id))
		conv= getObj(id);
	else if(isObj(id))
		conv=id;
		
	if(conv)
		conv.style.display=d1;
}


/************************************************
* swapDisplay_r(id,d1,d2)
* 
* Echange le display des objets de l'array id, entre d1 et d2
************************************************/
function swapDisplay_r(id,d1,d2){
	var conv='';
	
	for(i in id){
		swapDisplay(id[i],d1,d2);
	}
	delete(i);
		
	return true;
}

/************************************************
* setDisplay_r(id,d1)
* 
* Change le display des objets de l'array id, pour d1
************************************************/
function setDisplay_r(id,d1){
	var conv='';
	
	for(i in id){
		setDisplay(id[i],d1);
	}
	delete(i);
		
	return true;
}


/************************************************
* swapDisplay(id,d1,d2)
* 
* Echange le display de l'objet id, entre d1 et d2
************************************************/
function swapDisplay(id,d1,d2){
	var conv='';
	
	if(isStr(id))
		conv= getObj(id);
	else if(isObj(id))
		conv=id;
		
	if(conv)
		conv.style.display=(conv.style.display=='' || conv.style.display==d1 ? d2:d1);
}


/************************************************
* swapClassName(id,c1,c2)
* 
* Echange la class de l'objet id, de c1 pour c2
************************************************/
function swapClassName(id,c1,c2){
	var conv=null;

	if(isObj(id)) // Si on passe l'objet lui même
		conv=id;
	else
		conv=getObj(id);
		
	var _reg=eval('/\\b'+c1+'\\b/gi');
	
	if(conv.className.match(_reg))
		conv.className=conv.className.replace(_reg,c2);
	else
		addClassName(id,c2);
}

/************************************************
* setClassName(id,c1)
* 
* Définis la class c1 à l'objet id
************************************************/
function setClassName(id,c1){
	var conv=null;

	if(isObj(id)) // Si on passe l'objet lui même
		conv=id;
	else
		conv=getObj(id);

	if(conv && conv.className.search(eval('/\\b'+c1+'\\b/gi'))==-1)
		conv.className=c1;
}

/************************************************
* addClassName(id,c1)
* 
* Ajoute la class c1 à l'objet id
************************************************/
function addClassName(id,c1){
	var conv=null;

	if(isObj(id)) // Si on passe l'objet lui même
		conv=id;
	else
		conv=getObj(id);
	
	if(conv && conv.className.search(eval('/\\b'+c1+'\\b/gi'))==-1)
		conv.className+=" "+c1;
}

/************************************************
* remClassName(id,c1)
* 
* enlève la class c1 à l'objet id
************************************************/
function remClassName(id,c1){
	var conv=null;

	if(isObj(id)) // Si on passe l'objet lui même
		conv=id;
	else
		conv=getObj(id);
	
	if(conv)
		conv.className=conv.className.replace(eval('/\\b'+c1+'\\b/gi'),'');
}

/************************************************
*	Retourne num sans px derrière
************************************************/
function parsePx(num){
	return(String(num).replace(/px/,''));
}

/************************************************
*	Retourne un objet "boîte" comportant
*	x -> position x de l'objet obj
*	y -> position y de l'objet obj
*	width -> largeur de l'objet obj
*	height -> hauteur de l'objet obj
************************************************/
function getBox(obj){
	var x=0;
	var y=0;
	var width=0;
	var height=0;

	if(!obj)
		return null;
		
	x=obj.offsetLeft;
	y=obj.offsetTop;
	width=obj.offsetWidth;
	height=obj.offsetHeight;
	
	if(obj.offsetParent!=null){
		var tmp = getBox(obj.offsetParent);
		x+=tmp.x;
		y+=tmp.y;
	}
	
	return {"x":x,"y":y,"width":width,"height":height}
}

/************************************************
*	Affecte les valeurs de box à l'objet obj
************************************************/
function setBox(obj,box){
	var x=0;
	var y=0;
	var width=0;
	var height=0;

	if(!obj || !box)
		return null;

	if(box.x)
		setLeft(obj,box.x);
	if(box.y)
		setTop(obj,box.y);
	if(box.width)
		setWidth(obj,box.width);
	if(box.height)
		setHeight(obj,box.height);
	
	return obj;
}

/************************************************
*	Affecte left à l'objet obj, 
*	exprimée en unit
************************************************/
function setLeft(obj,left,unit){
	if(!unit)
		unit='px';
	
	obj.style.left=left+unit;
}

/************************************************
*	Affecte top à l'objet obj, 
*	exprimée en unit
************************************************/
function setTop(obj,top,unit){
	if(!unit)
		unit='px';
	
	obj.style.top=top+unit;
}

/************************************************
*	Affecte la largeur width à l'objet obj, 
*	exprimée en unit
************************************************/
function setWidth(obj,width,unit){
	if(!unit)
		unit='px';
	
	obj.style.width=width+unit;
}

/************************************************
*	Affecte la hauteur height à l'objet obj, 
*	exprimée en unit
************************************************/
function setHeight(obj,height,unit){
	if(!unit)
		unit='px';
	
	obj.style.height=height+unit;
}


/************************************************
*	Retourne l'attribut att de l'objet obj
************************************************/ 
function getAttribute(obj,att){

	if(isStr(obj))
		obj=getObj(obj);
		
	if(!obj)
		return false;
		
	if(obj.getAttribute){
		var attr= obj.getAttribute(att);
		
/*		if(att=='style'&&document.all)
			return attr.value;
	*/	
		return attr;
	}
}

/************************************************
*	Ajoute/Modifie l'attribut att de l'objet obj
*	avec la valeur val
************************************************/ 
function setAttribute(obj,att,val){

	if(isStr(obj))
		obj=getObj(obj);
		
	if(!obj)
		return false;
		
	if(obj.setAttribute)
		return obj.setAttribute(att,val);
}

/************************************************
*	Test si l'attribut att existe dans l'objet obj
************************************************/ 
function hasAttribute(obj,att){

	if(isStr(obj))
		obj=getObj(obj);
		
	if(!obj)
		return false;
		
	if(obj.hasAttribute)
		return obj.hasAttribute(att);
	else
		return false;
}

/************************************************
*	Echange l'attribut att1 avec att2 
*	si les attributs existent
************************************************/ 
function swapAttribute(obj,att1,att2,createIfNot){
	
	var val1="";
	var val2="";
	
	if(createIfNot==null)
		createIfNot=false;
	
	if(isStr(obj))
		obj=getObj(obj);
		
	if(!obj)
		return false;
	
	if((hasAttribute(obj,att1) && hasAttribute(obj,att2)) || createIfNot==true){
		val1=getAttribute(obj,att1);
		val2=getAttribute(obj,att2);
		setAttribute(obj,att1,val2);
		setAttribute(obj,att2,val1);
	}
		return;
}


/************************************************
*	Additionne a et b et renvoi le résultat
************************************************/ 
function add(a,b){
	a=	a*1;
	b= 	b*1;
	
	return (a+b);
}

/************************************************
*	Soustrait a et b et renvoi le résultat
************************************************/ 
function sous(a,b){
	a=	a*1;
	b= 	b*1;
	
	return (a-b);
}

/************************************************
*	Encode un chaîne pour la passer en URL
************************************************/
function encoderURI(a){
	return encodeURI(a);
}

/************************************************
*	Décode un chaîne pour la passer en URL
************************************************/
function decoderURI(a){
	return decodeURI(a);
}

/************************************************
*	Attache la fonction _function sur evt, 
*	a l'objet obj
************************************************/ 
function addEvent(obj,evt,_function,event){

	if(isStr(obj))
		obj=getObj(obj);
		
	if(!isObj(obj))
		return false;

	if(isStr(_function))
		var ptrFunc = new Function(_function);
	else if(isFunc(_function))
		var ptrFunc = _function;
	else
		return false;
	
	if(obj.addEventListener)
		obj.addEventListener(evt,ptrFunc,false);
	
	if(obj.attachEvent){
		evt='on'+evt;
		obj.attachEvent(evt,ptrFunc);
	}
	
	delete(ptrFunc);
}

/************************************************
*	Charge la page avec l'url en paramètre
*************************************************/

function goURL(url){
	goUrl(url);
}

function goUrl(url){
	if(url=='')
		if(window.location.reload)
			document.location.reload();

	if(window.location.assign)
		document.location.assign(url);	
	else
		document.location.href=url;
}


/************************************************
*	Renvoi l'url de base du site
*************************************************/
function getUrl(url){
	var _reg=/([\w]+:\/\/[^\/]*)/;
	var res='';
	// On a passé une URL on retourne cette URL
	if(_reg.test(url))
		return url;
	
	//Sinon on se base sur l'URL en cours
	res=_reg.exec(window.location.href);
	
	return res[1];
}

/************************************************
*	AJAX
************************************************/ 
var ajaxObj=null;

/************************************************
*	Crée un objet AJAX
************************************************/ 
function createAjax(){
	var oAjax=null;
		if(window.ActiveXObject){
				try{
					oAjax=new ActiveXObject("Microsoft.XMLHTTP")
					}catch(e){
						alert("Vous devez activer la fonctionnalité Active Scripting et les contrôles ActiveX.")
					}
		}
		else if(window.XMLHttpRequest){
			oAjax=new XMLHttpRequest();
			
			if(!oAjax){
				alert("XMLHttpRequest non pris en charge dans ce navigateur.")
			}
		}
	return oAjax;
}

function defaultAjaxReadyStateChange(ajaxObj){
	if(ajaxObj.readyState==4 && ajaxObj.status==200)
		eval(ajaxObj.responseText);
	}

/************************************************
*	Envoi une requete AJAX en POST
************************************************/
function postAjax(data,url,ajaxObj,_funct){
	
	if(!isStr(url)) url='./ajax.php';
	
	if(!isObj(ajaxObj))
		if(!isObj(ajaxObj=createAjax()))
			return
	
	if(!isFunc(_funct)) // On veux le comportement par défaut =  eval(ajaxObj.responseText)
		_funct=function(){defaultAjaxReadyStateChange(ajaxObj)};
	
	ajaxObj.onreadystatechange=_funct;
	ajaxObj.open("POST",url,true);
	ajaxObj.setRequestHeader('Content-Type','application/x-www-form-urlencoded;');
	//ajaxObj.setRequestHeader('Content-Type','charset=iso-8859-1;');
	sendAjax(ajaxObj,data);
}

/************************************************
*	Envoi une requete AJAX en GET
************************************************/
function getAjax(url,ajaxObj,_funct){
	if(!isObj(ajaxObj))
		if(!isObj(ajaxObj=createAjax()))
			return

	if(!isFunc(_funct)) // On veux le comportement par défaut =  eval(ajaxObj.responseText)
		_funct=function(){defaultAjaxReadyStateChange(ajaxObj)};

	alert(_funct)

	ajaxObj.onreadystatechange=_funct;
	ajaxObj.open("GET",url,true);
	ajaxObj.setRequestHeader('Content-Type','text/html; charset=iso-8859-1');
	sendAjax(ajaxObj,null)
}

/************************************************
*	Envoi la requete AJAX
*************************************************/
function sendAjax(ajaxObj,data){
	try{
		ajaxObj.send(data);
	}
	catch(e){
		if(e.number==-2146697208){
			alert("Vérifiez que le paramètre &apos;Langues...&apos; dans Internet Explorer est bien associé à une valeur.")
		}
	}
}

/************************************************
*	Gestion des erreurs
************************************************/
/************************************************
*	Trace une erreur JS
************************************************/
function traceError(err,cpl){
	// Affiche le contenu de la pile des erreurs
	function afficherPile(a){
		/* Retourne le nom de la fonction a */	
		function getFunctionName(a){
	/*	function Sy(a){
			for(var b in window){
				try{
					var c=window[b];
					if(c){
						var d=c.prototype;
						if(d){
							for(var e in d){
								if(d[e]==a){
									return b+"."+e
								}
							}
						}
					}
				}
				catch(f){}
			}
			return""
		}
	*/
			var _reg=/function (\w+)/;
			var b=_reg.exec(String(a));
			if(b){
				return b[1]
			}
			else{
				//return Sy(a)
			}
			return""
		}

		try{
			var b="";
			if(Error().stack){
				b=Error().stack+"\n\n"
			}
			if(a){
				var b="- "+getFunctionName(a)+"(";
				
				for(var c=0;c<a.arguments.length;c++){
					if(c>0)
						b+=", ";
					var d=String(a.arguments[c]);
					if(d.length>40){
						d=d.substr(0,40)+"..."
					}
					b+=d
				}
				b+=")\n";
				b+=afficherPile(a.caller)
			}
			return b
		}catch(e){
			return"[Cannot get stack trace]: "+e+"\n"
		}
	}
	
	var errTxt="Erreur Javascript: "+(cpl?cpl:"")+" "+err;
	if(document.all){
		errTxt+=" "+err.name+": "+err.message+" ("+err.number+")\n";
	}
	var detail="";
	if(isStr(err)){
		detail=err+"\n"
	}
	else{
		for(var e in err){
			try{
				detail+=e+": "+err[e]+"\n"
			}
			catch(f){
			}
		}
	}
	detail+=afficherPile(err.caller);
	logError(errTxt,detail)
}


/************************************************
*	Renvoi l'heure côté client
************************************************/
function getTime(){
	return new Date().getTime();
}

/************************************************
*	Envoi une erreur JS au serveur
************************************************/
var lastErrorTime=0;
var errorRepeat=0;
function logError(errTxt,detail){
	try{
		var temps=getTime();
		
		if(sous(temps,lastErrorTime)<60000){
			errorRepeat++;
			return false;
		}
		lastErrorTime=temps;
		
		detail+=(errorRepeat>0 ? 'Encore des erreurs':'');
		errorRepeat=0;
		
		var oAjax=createAjax();	
		detail='action=jsError&detail='+encodeURI(errTxt+'\n'+detail);
		postAjax(oAjax,getUrl()+'/impact/ajax.php',detail,function(){if(oAjax.readyState==4 && DEBUG) alert('Javascript Debug :\n'+oAjax.responseText)});
	}
	catch(e){}
}









/************************************************
* Gestion des cookies
************************************************/
/*****************************************************
Writes a cookie using the following sentens, nom=valeur
*****************************************************/
function writeCookie(nom, valeur){
	var argv=writeCookie.arguments;
	var argc=writeCookie.arguments.length;
	var expires=(argc > 2 && argv[2]!="") ? argv[2] : new Date(2015,12,31);
	var path=(argc > 3 && argv[3]!="") ? argv[3] : null;
	var domain=(argc > 4  && argv[4]!="") ? argv[4] : null;
	var secure=(argc > 5  && argv[5]!="") ? argv[5] : false;
	document.cookie=nom+"="+escape(valeur)+
		((expires==null) ? "" : ("; expires="+expires.toGMTString()))+
		((path==null) ? "" : ("; path="+path))+
		((domain==null) ? "" : ("; domain="+domain))+
		((secure==true) ? "; secure" : "");
}

/*****************************************************
Sub function of readcookie
*****************************************************/
function getCookieVal(offset,defaultValue){
	var endstr=document.cookie.indexOf (";", offset);
	if (endstr==-1) endstr=document.cookie.length;
	return unescape(document.cookie.substring(offset, endstr));
}

/*****************************************************
Function Read cookie
*****************************************************/

function readCookie(nom,defaultValue){
	var arg=nom+"=";
	var alen=arg.length;
	var clen=document.cookie.length;
	var i=0;
	
	while (i<clen){
		var j=i+alen;
		if (document.cookie.substring(i, j)==arg) return getCookieVal(j);
		i=document.cookie.indexOf(" ",i)+1;
		if (i==0) break;
	}
	
	return defaultValue;
}

