function CrossBrowserClass(){
    this.n = navigator.userAgent.toLowerCase();
    this.db = null;
    this.op = !!(window.opera && document.getElementById);
    this.op6 = !!(this.op && (xUA.indexOf('opera 6')!=-1 || xUA.indexOf('opera/6')!=-1 || xUA.indexOf('opera 7')!=-1 || xUA.indexOf('opera/7')!=-1));
    if (this.op && !this.op6) document.onmousedown = new Function('e',
        'if (((e = e || window.event).target || e.srcElement).tagName == "IMAGE") return false;');
    this.ie = !!(this.n.indexOf("msie") >= 0 && document.all && !this.op);
    this.iemac = !!(this.ie && this.n.indexOf("mac") >= 0);
    this.ie4 = !!(this.ie && !document.getElementById);
    this.ie6 = !!(this.ie && this.n.indexOf("msie 6") >= 0);
    this.n4 = !!(document.layers && typeof document.classes != "undefined");
    this.n6 = !!(typeof window.getComputedStyle != "undefined" && typeof document.createRange != "undefined");
    this.w3c = !!(!this.op && !this.ie && !this.n6 && document.getElementById);
    this.ce = !!(document.captureEvents && document.releaseEvents);
    this.px = (this.n4 || this.op6)? '' : 'px';
    this.tiv = this.w3c? 40 : 10;
    this.ff2 = !!(this.n.indexOf("firefox/2") >= 0);

    this.getDB = function(){
        if (this.db==null){
            this.db = (document.compatMode && document.compatMode.toLowerCase() != "backcompat")?
            document.documentElement
            : (document.body || null);
        }
        return this.db;
    }

  // Valeur enti?re
    this.Int = function(d_x, d_y){
        return isNaN(d_y = parseInt(d_x,10))? 0 : d_y;
    }

  // Retourne un curseur valide
    this.getCursor = function(c_name){
        if ( (c_name == 'hand') || (c_name=='pointer')) {
           return (!this.ie || this.iemac) ? 'pointer' : 'hand';
        } else {
            return c_name;
        }
    }

  // Positionne le curseur de la div
    this.setDivCursor = function(divName, c_name){
        var div = this.getDiv(divName);
        if (div.style) {
            div.style.cursor = this.getCursor(c_name);
        }
    }

  // Positionne le cusreur de l'image
    this.setImgCursor = function(imgName, c_name){
        var img = this.getImg(imgName);
        if ( (img.style) && (img.style.cursor)) {
            img.style.cursor = this.getCursor(c_name);
        }
    }

  // Position X de la div par rapport ? la fen?tre (ou frame).
    this.getPageX = function(p_div){
        var result = 0;
        while (p_div){
            result += this.Int(p_div.offsetLeft);
            p_div = p_div.offsetParent || null;
        }
        return result;
    }

    // Position Y de la div par rapport ? la fen?tre (ou frame).
    this.getPageY = function(p_div){
        var result = 0;
        while (p_div){
            result += this.Int(p_div.offsetTop);
            p_div = p_div.offsetParent || null;
        }
        return result;
    }

  // Largeur de la fen?tre
    this.getWndW = function() {
        return this.Int(
            (this.getDB() && !this.op && !this.w3c && this.getDB().clientWidth && !this.n6)? this.getDB().clientWidth : (window.innerWidth || 770)
        );
    }

  // Hauteur de la fen?tre
    this.getWndH = function() {
        return this.Int(
            (this.getDB() && !this.op && !this.w3c  && this.getDB().clientHeight && !this.n6)? this.getDB().clientHeight : (window.innerHeight || 500)
        );
    }

  // Scroll courant en X
    this.getScrollX = function() {
        return this.Int(window.pageXOffset || (this.getDB()? this.getDB().scrollLeft : 0));
    }

  // Scroll courant en Y
    this.getScrollY = function(){
        return this.Int(window.pageYOffset || (this.getDB()? this.getDB().scrollTop : 0));
    }

  // Largeur de l'image
    this.getImgW = function(p_img){
        return p_img ? this.Int(p_img.width) : 0;
    }

  // Hauteur de l'image
    this.getImgH = function(p_img){
        return p_img ? this.Int(p_img.height) : 0;
    }

  // Cherche l'image
    this.getImg = function(imgName, aDoc){
        aDoc = aDoc || document;
        var img = aDoc.images[imgName];
        return (img.name == imgName ) ? img : null;
    }

  // Position en X de l'image
    this.getImgX = function(img){
        if (img ){
            if (this.n4) {
                return img.x;
            } else {
                return this.getPageX(img);
            }
        }
        return 0;
    }

    // Position en Y de l'image
    this.getImgY = function(img){
        if (img ){
            if (this.n4) {
                return img.y;
            } else {
                return this.getPageY(img);
            }
        }
        return 0;
    }

    // Largeur de la div
    this.getDivW = function(d_o){
        return this.Int(
            this.n4? (d_o? d_o.clip.width : 0)
            : d_o? (d_o.offsetWidth || d_o.style.pixelWidth || d_o.style.width || 0)
            : 0
        )
    }

    this.getDivWByDivName = function(divName) {
    	var div = this.getDiv(divName);
    	if(div) return this.getDivW(div);
    }

    /**
     * Set the div width
     * @param {String} divName id of the div
     * @param {int} width value
     */
    this.setDivW = function(divName, value) {
        var div = this.getDiv(divName);
        if(div) {
        	if (this.n4) div.clip.width = value;
        	else {
        		if(div.style.pixelWidth) div.style.pixelWidth = value;
        		if(div.style.width) div.style.width = value;
        	}
        }
    }

    // Hauteur de la div
    this.getDivH = function(d_o){
        return this.Int(
            this.n4? (d_o? d_o.clip.height : 0)
            : d_o? (d_o.offsetHeight || d_o.style.pixelHeight || d_o.style.height || 0)
            : 0
        );
    }

    this.getDivHByDivName = function(divName) {
    	var div = this.getDiv(divName);
    	if(div) return this.getDivH(div);
    }

    /**
     * Set the div height
     * @param {String} divName id of the div
     * @param {int} height value
     */
    this.setDivH = function(divName, value) {
    	var div = this.getDiv(divName);
        if(div) {
        	if (this.n4) div.clip.height = value;
        	else {
        		if(div.style.pixelHeight) div.style.pixelHeight = value;
        		if(div.style.height) div.style.height = value;
        	}
        }
    }

    // Position en X de la div
    this.getDivX = function(div){
        return this.Int(div.offsetLeft);
    }

    // Position en Y de la div
    this.getDivY = function(div){
        return this.Int(div.offsetTop);
    }

  // Div de nom demand?
    this.getDiv = function(divName, d_d){
        d_d = d_d || document;
        if (this.n4){            if (d_d.layers[divName]) return d_d.layers[divName];
            for (var d_i = d_d.layers.length; d_i--;)
            {
                var d_y = this.getDiv(divName, d_d.layers[d_i].document);
                if (d_y) return d_y;
            }
        }
        if (this.ie) return d_d.all[divName] || null;
        if (d_d.getElementById) return d_d.getElementById(divName) || null;
        return null;
    }

  // Positionne la div visible ou non
    this.setDivVisible = function(divName, state,d_d) {

        if(this.getDiv(divName,d_d)) this.getDiv(divName,d_d).style.visibility = (state) ? "visible" : "hidden";
    }

  // Positionne la div relative (absolue si faux)
    this.setDivPosition = function(divName, state,d_d) {

        if(this.getDiv(divName,d_d)) this.getDiv(divName,d_d).style.position = (state) ? "static" : "absolute";
    }

    // Positionne la propri?t? display ? block ou none
    this.setDivBlockDisplay = function(divName, state,d_d){
        if(this.getDiv(divName,d_d)) this.getDiv(divName,d_d).style.display = (state) ? "block" : "none";
    }

  // Indique si la div est visible
    this.isDivVisible = function(divName,d_d){
        return this.getDiv(divName,d_d).style.visibility == "visible";
    }

  // Indique si la div parent est visible
    this.isParentDivVisible = function(divName, d_d){
        return this.getDiv(divName, d_d).parentNode.style.visibility == "visible";
    }

  // Propri?t? completed des images autoris?e ?
    this.isImageCompleteDefined = function(){
        return !this.kq;
    }

    //Indique si la transparence du png est suppor?
    this.applyFilterForTransparentPngSupport = function() {
    		var arVersion = navigator.appVersion.split("MSIE");
        var version = parseFloat(arVersion[1]);
        return this.ie && ((version >= 5.5) && (version < 7) && (document.body.filters));
    }

    // Cherche l'?lement
    this.findElement = function(elementId, aDocument){
        if (!aDocument) aDocument = document;
        return aDocument.all ? aDocument.all(elementId) : aDocument.getElementById(elementId) || aDocument.getElementsByName(elementId)[0];
    }
    // Cherche l'?lement
    this.findSubElement = function(elementId, aDocument){
        return aDocument.all ? aDocument.all(elementId) : aDocument.getElementById(elementId);
    }

  // Remplace le code de la Div
    this.write = function(divName, d_x, d_d){
        var aDiv = CROSS_BROWSER.getDiv(divName, d_d);
	    if(aDiv) {
	        if (CROSS_BROWSER.n4) {
	            var d_o = aDiv.document;
	            d_o.open();
	            d_o.write(d_x);
	            d_o.close();
	            //dd.getWH(this);
	        } else if (!CROSS_BROWSER.op6) {
	            if (aDiv.style) {
	                aDiv.style.height = 'auto';
	            }
	            aDiv.innerHTML = d_x;
	        }
        }
    }


    // Ajoute du code ? la div
    this.append = function(divName, d_x, d_d){
        var aDiv = this.getDiv(divName, d_d);
        if (this.n4) {
            var d_o = aDiv.document;
            d_o.write(d_x);
        } else if (!this.op6) {
            if (aDiv.style) {
                aDiv.style.height = 'auto';
            }
            aDiv.innerHTML += d_x;
        }
    }

    // La Div contient le point ?
    this.contains = function(divName,x,y,d_d){
        var div = this.getDiv(divName,d_d);
        var w = this.getDivW(div);
        var h = this.getDivH(div);
        var divX = this.getDivX(div);
        var divY = this.getDivY(div);

        return ( (x>=divX) && (x<=(divX+w)) && (y>=divY) && (y<=(divY+h)));
    }

    this.distance = function(x1, y1, x2, y2){
        return Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
    }

    // D?place la div en relatif
    this.moveBy = function(divName, aX, aY, d_d){
        var aDiv = this.getDiv(divName, d_d);
        if(aDiv) {
        	aDiv.style.left = this.Int(aDiv.style.left) + this.Int(aX);
        	aDiv.style.top  = this.Int(aDiv.style.top) + this.Int(aY);
        }
    }

    // D?place la div en absolu
    this.moveTo = function(divName, aX, aY, d_d){
        var aDiv = this.getDiv(divName, d_d);
        if(aDiv) {
	        aDiv.style.left = this.Int(aX);
	        aDiv.style.top = this.Int(aY);
        }
    }

    // D?place la div en la recentrant par rapport ? la taille de la div
    this.centerDivAndMoveTo = function(divName, aX, aY, d_d) {
      var aDiv = this.getDiv(divName, d_d);
      var divW = this.getDivW(aDiv);
      var divH = this.getDivH(aDiv);
      var newX = aX-divW/2;
      var newY = aY-divH/2;
      this.moveTo(divName, newX, newY, d_d);
    }

    // Glisse la div en la recentrant par rapport ? la taille de la div
    this.centerDivAndSlideTo = function(divName, targetX, targetY, duration, d_d) {
      var aDiv = this.getDiv(divName, d_d);
      var divW = this.getDivW(aDiv);
      var divH = this.getDivH(aDiv);
      var newX = targetX-divW/2;
      var newY = targetY-divH/2;
      this.slideTo(divName, newX, newY, duration, d_d);
    }

    //Glisse la div en ligne droite en une dur?e exprim?e en millisecondes avec
    this.slideTo = function(divName, targetX, targetY, duration, isLinearSlide, d_d) {
        if(isLinearSlide==null) isLinearSlide = true;
        var aDiv = this.getDiv(divName, d_d);

        //Fixe le taux d'images par seconde
        if(!aDiv.fps) aDiv.fps = 25;
        //Fixe les coordonn?es cibles
        aDiv.targetX = this.Int(targetX);
        aDiv.targetY = this.Int(targetY);

        //Fixe la dur?e du glissement
        aDiv.slideDuration = duration;
        //R?initialise l'?tat de la div
        aDiv.stop = false;
        //Evalue la distance en pixels ? parcourir
        aDiv.deltaX = aDiv.targetX - this.Int(aDiv.style.left);
        aDiv.deltaY = aDiv.targetY - this.Int(aDiv.style.top);

        //Fixe la p?riode
         aDiv.period = 1/duration;

        //Fixe la position initiale
        aDiv.startX = this.Int(aDiv.style.left);
        aDiv.startY = this.Int(aDiv.style.top);

        aDiv.startTime = new Date().getTime();
        if (!aDiv.moving) this._slideTo(divName, isLinearSlide, d_d);
    }

    this._slideTo = function(divName, isLinearSlide, d_d) {
      var aDiv = this.getDiv(divName, d_d);

      if(!aDiv) return;

      var now, s, deltaT, newY, newX;
      now = new Date();
      deltaT = now.getTime() - aDiv.startTime;

      var T = (isLinearSlide) ? 1 : Math.PI/2;
      var rate = (deltaT/aDiv.slideDuration)*T;
      if(!isLinearSlide) rate = Math.sin(rate);

      if (aDiv.stop) {
        aDiv.moving = false;
      }
      else if (deltaT < aDiv.slideDuration) {
        setTimeout("CROSS_BROWSER._slideTo('"+divName+"',"+isLinearSlide+","+d_d+")", Math.round(1000/aDiv.fps));
        newX = aDiv.startX + Math.round(aDiv.deltaX * rate);
        newY = aDiv.startY + Math.round(aDiv.deltaY * rate);

        this.moveTo(divName, newX, newY, d_d);
        aDiv.moving = true;
      }
      else {
        this.moveTo(divName, aDiv.targetX, aDiv.targetY, d_d);
        aDiv.moving = false;
        if (aDiv.slidePerformed) {
          aDiv.slidePerformed();
        }
      }
    }

    // Positionne la div via l'?venement souri
    this.moveToEvent = function(divName, ev, align, valign, xOffset, yOffset){
        var crossEvent = new CrossBrowserEvent();
        crossEvent.set(ev);
        this.moveToObj(
            divName,
            crossEvent.x, crossEvent.y,
            0, 0,
            align, valign,
            xOffset, yOffset);
    }

    // Positionne la div via la position de l'image
    this.moveToImage = function(divName, imageName, align, valign, xOffset, yOffset){
        var img = CROSS_BROWSER.getImg(imageName);
        this.moveToObj(
            divName,
            CROSS_BROWSER.getImgX(img), CROSS_BROWSER.getImgY(img),
            CROSS_BROWSER.getImgW(img), CROSS_BROWSER.getImgH(img),
        align, valign,
        xOffset, yOffset
        );
    }

    // Positionne la div via la position de la div
    this.moveToDiv = function(divName, ownerDivName, align, valign, xOffset, yOffset){
        var div = CROSS_BROWSER.getDiv(ownerDivName);
        this.moveToObj(
            divName,
            CROSS_BROWSER.getPageX(div), CROSS_BROWSER.getPageY(div),
            CROSS_BROWSER.getDivW(div), CROSS_BROWSER.getDivH(div),
        align, valign,
        xOffset, yOffset
        );
    }

    // Positionne une div sous une autre
    this.moveUnder = function( underDivName, divName ){
    	var div = this.getDiv(divName);
    	var selectedDivHeight = this.getDivH(div);
    	var selectedDivOffsetY = this.getPageY(div);
    	this.getDiv(underDivName).style.left = 0;
    	this.getDiv(underDivName).style.top = selectedDivHeight + selectedDivOffsetY + 20;
  		this.setDivVisible(underDivName, true);
    	this.setDivBlockDisplay(underDivName, true);
    }

    // Positionne la div
    this.moveToObj = function(divName, xOwner, yOwner, wOwner, hOwner, align, valign, xOffset, yOffset){

        // Default value
        if (!wOwner) wOwner = 0;
        if (!hOwner) hOwner = 0;
        if (!align)  align = "inRight";
        if (!valign) valign = "inTop";
        if (!xOffset) xOffset = 0;
        if (!yOffset) yOffset = 0;
        xOwner  = CROSS_BROWSER.Int(xOwner);
        yOwner  = CROSS_BROWSER.Int(yOwner);
        hOwner  = CROSS_BROWSER.Int(hOwner);
        wOwner  = CROSS_BROWSER.Int(wOwner);
        xOffset = CROSS_BROWSER.Int(xOffset);
        yOffset = CROSS_BROWSER.Int(yOffset);

        // Compute div location
        var elt  = CROSS_BROWSER.getDiv(divName);
        var wElt = CROSS_BROWSER.getDivW(elt);
        var hElt = CROSS_BROWSER.getDivH(elt);
        var x     = 0;
        var y     = 0;
        switch (align){
            case "right"   : x=xOwner+wOwner; break;
            case "center"  : x=xOwner+((wOwner-wElt)/2); break;
            case "left"    : x=xOwner-wElt; break;
            case "inRight" : x=xOwner; break;
            case "inLeft"  : x=xOwner+wOwner-wElt; break;
            default        : x=xOwner; break;
        }
        switch (valign){
            case "top"      : y=yOwner-hElt; break;
            case "middle"   : y=yOwner+((hOwner-hElt)/2); break;
            case "bottom"   : y=yOwner+hOwner; break;
            case "inTop"    : y=yOwner; break;
            case "inBottom" : y=yOwner+hOwner-hElt; break;
            default         : y=yOwner; break;
        }

        x+=xOffset;
        y+=yOffset;

        if (x<0) x=0;
        if (y<0) y=0;

        // move
        CROSS_BROWSER.moveTo(divName, x,y);
    }

    // Change la transparence de la div
    this.setDivOpacity = function(divName, value){
        var div = this.getDiv(divName);
        if (this.n6) div.style.MozOpacity = value;
        else if (this.ie && !this.iemac && typeof div.filters != "undefined") {
          //if (div.filters.length==0){
               div.style.filter = "Alpha(opacity="+parseInt(100*value,10)+")";
            /*} else {
              div.style.filters[0].opacity = parseInt(100*value);
            }*/
        }
    }

    this.createHttpObject = function(){
    var xmlhttp = null;
    /*@cc_on
    @if (@_jscript_version >= 5)
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
        xmlhttp = false;
        }
      }
    @else
    xmlhttp = false;
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
      try {
        xmlhttp = new XMLHttpRequest();
      } catch (e) {
        xmlhttp = false;
      }
    }
    return xmlhttp;
  }
}

var CROSS_BROWSER = new CrossBrowserClass();


// Evenement g?n?rique
function CrossBrowserEvent(){
    this.x = -1;
    this.y = -1;
    this.MOUSE_BUTTON_LEFT = 1;
    this.MOUSE_BUTTON_MIDDLE = 2;
    this.MOUSE_BUTTON_RIGHT = 3;
    this.which = -1; // MOUSE BUTTON : 1 = LEFT, 2 = CENTER, 3 = RIGHT
    this.type = -1;
    this.src = null;
    this.e = null;
    this.enterKey = false;
    this.shiftKey = false;
    this.ctrlKey = false;

  // positionne les propri?t?s de l'?venement g?n?rique ? partir de l'?v?nement sp?cifique ? IE, Mozilla ou autre
    this.set = function(ev, aWindow){
        if (!ev) var ev = (aWindow || window).event;
        this.e = ev;

        this.x = CROSS_BROWSER.Int(ev.pageX || ev.clientX || 0);
        this.y = CROSS_BROWSER.Int(ev.pageY || ev.clientY || 0);
        if (CROSS_BROWSER.ie || CROSS_BROWSER.kq) {
            this.x += CROSS_BROWSER.getScrollX() - ((CROSS_BROWSER.ie && !CROSS_BROWSER.iemac)? 1 : 0);
            this.y += CROSS_BROWSER.getScrollY() - ((CROSS_BROWSER.ie && !CROSS_BROWSER.iemac)? 1 : 0);
        }

        if (ev.which){
            this.which = ev.which;
        } else { // IE
            switch (ev.button){
                case 1 : this.which = 1; break;
                case 4 : this.which = 2; break;
                case 2 : this.which = 3; break;
            }
        }
        this.type = this.e.type;
        this.src = this.e.target || this.e.srcElement || null;
        this.src.tag = (this.src.tagName || this.src).toString().toLowerCase();
        this.shiftKey = ev.modifiers? (ev.modifiers & Event.SHIFT_MASK)   : (ev.shiftKey || false);
        this.ctrlKey  = ev.modifiers? (ev.modifiers & Event.CONTROL_MASK) : (ev.ctrlKey  || false);
        var characterCode;  //literal character code will be stored in this variable

        if(ev && ev.which){ //if which property of event object is supported (NN4)
            ev = ev;
            characterCode = ev.which; //character code is contained in NN4's which property
        }
        else {
            characterCode = ev.keyCode; //character code is contained in IE's keyCode property
        }
        if(characterCode == 13){ //if generated character code is equal to ascii 13 (if enter key)
            this.enterKey = true;
        }
        else {
            this.enterKey = false;
        }
    }

    // Stop la propagation de l'?venement
    this.stopPropagation = function(){
        if (this.e){
            this.e.cancelBubble = true;
            if (this.e.stopPropagation) this.e.stopPropagation();
        }
   }

   // Retourne l'?l?ment from
   this.getFromElement = function(){
      if (this.e){
        if (this.e.relatedTarget) return this.e.relatedTarget;
        else if (this.e.fromElement) return this.e.fromElement;
      }
      return null;
  }

  // Retourne l'?l?ment to
  this.getToElement = function(){
      if (this.e){
        if (this.e.relatedTarget) return this.e.relatedTarget;
        else if (this.e.fromElement) return this.e.toElement;
      }
      return null;
  }
}

// Ajax caller
function AjaxEngine(isSynchronous){
    this.isAsynchronous = true;
    this.obj = null;
    this.divId = null;
    this.functionToCallName = null;
    this.periodAutoRefresh = null;
    this.callback = null;
    this.doc = null;

    var ajaxEngine = this;

    this.makeSynchronousCall = function(url) {
    	this.url = url;
    	this.obj = CROSS_BROWSER.createHttpObject();
        this.obj.open("GET", url, false);
        this.obj.send(null);
        if(this.obj.status == 200){
       		return this.obj.responseText;
   		}
    };

    this.makeCall = function(url, divId, functionToCallName, periodAutoRefresh) {
        this.url = url;
        this.divId = divId;
        this.functionToCallName = functionToCallName;
        this.periodAutoRefresh = periodAutoRefresh;
        this.obj = CROSS_BROWSER.createHttpObject();
        this.obj.open("GET", url, this.isAsynchronous);
        this.obj.onreadystatechange = onReadyStateChange;
        this.obj.send(null);
    };

    this.makeCall2 = function(url, divId, callback, doc) {
        this.url = url;
        this.divId = divId;
        this.callback = callback;
        this.doc = doc;
        this.obj = CROSS_BROWSER.createHttpObject();
        this.obj.open("GET", url, this.isAsynchronous);
        this.obj.onreadystatechange = onReadyStateChange2;
        this.obj.send(null);
    };

    function onReadyStateChange() {
        if ( ajaxEngine.obj.readyState == 4 || ajaxEngine.obj.readyState == "complete" )
        {
          CROSS_BROWSER.write(ajaxEngine.divId, ajaxEngine.obj.responseText);
          if(ajaxEngine.functionToCallName && ajaxEngine.periodAutoRefresh) {
          	setTimeout(ajaxEngine.functionToCallName+"()",ajaxEngine.periodAutoRefresh);
          }
        }
    };

    function onReadyStateChange2() {
        if ( ajaxEngine.obj.readyState == 4 || ajaxEngine.obj.readyState == "complete" )
        {
          CROSS_BROWSER.write(ajaxEngine.divId, ajaxEngine.obj.responseText, ajaxEngine.doc);
          if(ajaxEngine.callback) {
          	ajaxEngine.callback();
          }
        }
    };
}
