

(function(){//on encapusle nos donné grace a une fonction anonyme , pour eviter tros de vriables globale ou de faire un namespace
   
   //definit les versions du navigateur, peux etre mit en globale
   var ua=navigator.userAgent.toLowerCase(),
       isIE=/msie/.test(ua),
       isIE6=/msie 6/.test(ua),
       isIE7=/msie 7/.test(ua),
       isIE8=/msie 8/.test(ua);
   
   
   var getStyle = function(/*DOMObject*/element, /*string*/rule){//peux etre definit en globale car très utilise, aucune dépendance...
   
       var camelRule=rule.replace(/\-(\w)/g, function (strMatch, p1){return p1.toUpperCase();}),//supprime les tiré et met en majuscule la lettre suivante  
           value = element.style[camelRule];
           
       if (!value){ 
           if(document.defaultView && document.defaultView.getComputedStyle){
		       value = document.defaultView.getComputedStyle(element, "").getPropertyValue(/*fait l inverse de camelRule*/rule.replace(/[A-Z]/g, function(match){return '-'+match.charAt(0).toLowerCase();})); 
	       }else{//specifique ie
		       value = element.currentStyle[camelRule] ;
           }
       }
       
       return value == 'auto' ? undefined : value;
   }; 
   
   
   
   var getOffset = function(/*DOMObject*/element,  /*bool*/byPosition,  /*bool*/lessScroll,  /*string*/from, /*bool*/force){
   
       var of=[0,0],//tableau de coor à retourné
           from = from || 'border',
           ep; //ep -> elementPosition
       
       if(force)// force les elements parents non affiché a l étre
          var dp=displayParent(element);
           
       ep=getStyle(element,'position');
       if(ep!='relative' &&  ep!='absolute')//passe en relatif , surtout pour ie6 et 7  , et evite ainsi la boucle sur offsetParent  
          element.style.position='relative';
       
       of[0] += element.offsetLeft;
       of[1] += element.offsetTop;
      
       element.style.position=ep;//remet la position d 'origine
           
       if(byPosition){//rectifie les valeurs suivant la version d'ie
          if(isIE){
             var t=getOffsetParent(element),
                 op=t[0],//offsetParent
                 pp=t[1];//pp-> parentPosition 
             if(isIE7 || isIE8){
                 of[0] -= toNum(op,'border-left-width');   
                 of[1] -= toNum(op,'border-top-width');
             }else if(pp && pp=='relative'){
                 do{//eneleve toute les marges,bordure et paddings de droite des parents, du 1er parent definnissant une position non static et relative
                    of[0] -= toNum(op,'margin-left')+toNum(op,'padding-left')+toNum(op,'border-left-width'); 
                 }while((op=op.parentNode) && op!=document.body); 
             }
          }
       }
       
       if(lessScroll ^ isIE6)//ie6 calcule la position sans les scroll, ( ^ -> test conditionnelle exslisif , soit l un , soit l autre, mais pas les deux en, meme temp)
           manageScroll(element, of, isIE6);
       
       manageBox(element, of, from);//rectifie les valeur en focntion de depart de la mesure
       
       if(force)//si force rectifie les dispalye des parents 
           unDisplayParent(dp);
       
       return of;
   };
   
   var getSize = function(/*DOMObject*/element,  /*string*/from, /*bool*/force){
       var dim=[0,0],//tableau de coor à retourné
           from = from || 'border';
       
       if(force)
          var dp=displayParent(element);
          
       dim[0] += element.offsetWidth;
       dim[1] += element.offsetHeight;  
       
       manageBox(element, dim, from);
       
       if(force)
           unDisplayParent(dp);
       
       return dim; 
   };
   
   var displayParent = function(el){//recuepre les parents pas affiché et affiche les, (pas en absolue , car les valeurs sont erronné, a corriger plus tard, mais aucun sintillement ne se fait, l'execution de getOffset met moin de temp que le taux de rafraichissement de l écran, ~= 20millisecondes)
        var p=[];
        while((el=el.parentNode) && el!=document.documentElement){
           var d=getStyle(el,'display');
           if(d=='none'){
               p.push(el);
               el.__visibility__=getStyle(el,'visibility');
               el.style.visibility='hidden';
               el.style.display='';
           }
       }  
       return p;
   };
   
   var unDisplayParent = function(p){//recache les parents
        for(var i=0,el;(el=p[i]);i++){
            el.style.visibility=el.__visibility__;
            el.style.display='none';
        }
   };
   
   var getOffsetParent = function(element){//retourn le parent non static et sa position 
       while((element=element.parentNode) && element!=document.body){
           var p=getStyle(element,'position');
           if(p!='static')
               return [element,p];
       } 
       return [element,'static'];  
   };
   
   var toNum = function(el,rule){// convertie un valeur avec des px
       return parseInt(getStyle(el,rule) ,10) || 0;
   };
   
   var modBox = ['content','padding','border','margin'];//pour boucler dessus (traiement générique)
   
   var manageBox = function(element, of, from){
       for(i=0,co=false;i<4;i++){
          if(co){
              of[0]-=toNum(element,modBox[i]+'-left'+(modBox[i]=='border'?'-width':''));
              of[1]-=toNum(element,modBox[i]+'-top'+(modBox[i]=='border'?'-width':''));
          }
          if(modBox[i]==from)co=true;
       }
   };
   
   var manageScroll = function(el, of, op, _with){
       while ((el = el.parentNode) && el != document.body){
           of[0] =of[0]-el.scrollLeft || 0;
           of[1] = _with?of[1]+el.scrollTop || 0:of[1]-el.scrollTop || 0;
       };
   };
   
   //raccourcit 
   
   window.getOffset=function(element,lessScroll,form,force){
      return getOffset(element,false,lessScroll,form,force);//getOffset est accessible car, W.getOffset est déclaré dans la meme fonction 
   };
   
   window.getPositionnedOffset=function(element,lessScroll,form,force){
      return getOffset(element,true,lessScroll,form,force);
   };
   
   window.getSize=function(element,form,force){
      return getSize(element,form,force);
   }; 
})()
