/**
 * Fonction permettant d'unifier les accès aux objets
 * et propriétés.
 *
 * Permet un accès identique quelque soit le navigateur :
 * + aux événements : addListenner(obj, sEventType, func, bubbling);
 * + aux objets et à leur style : getObjById(sObjId, win);
 * + à l'objet "événement" : getEventObj(evt)
 *
 */

/**
 * Object xml http request
 */
//var XHR_request;


/* Event and Objects
------------------------------------------------------------------------*/


/**
 * Cherche la référence sur un objet dont on connait l'id
 *
 */
function getObjById(sObjId, win)
{
    var obj = false;
    if (!win || win == null) win = window;

    if (document.getElementById) {
      return win.document.getElementById(sObjId);

    } else if (document.all) {
      return win.document.all[sObjId];

    } else if (document.layers) {
      obj = win.document.layers[sObjId];
      obj.style = win.document.layers[sObjId];
    }

    return obj;
} // end of the "getEventObj()" function




/**
 * Standardise les propriétés d'un objet "événement" en créant celles qui manquent
 *
 * source : http://developer.apple.com/internet/webcontent/eventmodels.html
 */
  function getEventObj(evt) {

    // Merci apple (voir ci dessus)
    evt = (evt) ? evt : ((window.event) ? window.event : "");

    var newevt = new Object;
    newevt.type = evt.type;

    // Cible (url de destination pour un lien, par exemple)
    if (evt.target) { // NN4, Gecko, W3C/Safari
        if (evt.currentTarget && evt.nodeType != 3) {
            newevt.target = evt.currentTarget;
        } else {
            newevt.target = evt.target;
        }
    } else {
        if (evt.srcElement) { // IE 4+
            newevt.target = evt.srcElement;
        } else {
            newevt.target = 'undefined';
        }
    }

    // Coordonnées du clic
    if (evt.pageX) { // NN4, Gecko, W3C/Safari
            newevt.pageX = evt.pageX;
            newevt.pageY = evt.pageY;
    } else {
        if (evt.clientX) { // IE 4+
            newevt.pageX = evt.clientX + document.body.scrollLeft;
            newevt.pageY = evt.clientY + document.body.scrollTop;
        } else {
            newevt.pageX = 0;
            newevt.pageY = 0;
        }
    }

    // Bouton de la souris ayant servis au clic :
    // W3C, Gecko   : gauche 0, milieu 1, droite 2
    // IE 4+        : gauche 1, milieu 4, droite 2
    if (!newevt.button) { // IE 4+, Gecko, W3C/Safari
        if (evt.which) {
            newevt.button = evt.which; // NN4
        } else {
            newevt.button = "undefined";
        }
    }

    // code de la touche pressée (NN4 a=97; autres : a=65)
    if (!newevt.keyCode) { // IE 4+, Gecko, W3C/Safari
        if (evt.which) {
            newevt.keyCode = evt.which; // NN4
        } else {
            newevt.keyCode = "undefined";
        }
    }

    return newevt;
  } // end of the "getEventObj()" function





/**
 * Retourne les dimensions de la fenêtre
 */
function getWindowSize()
{
    var size = new Array;
    if (self.innerHeight) // all except Explorer
    {
        size.x = self.innerWidth;
        size.y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight)
        // Explorer 6 Strict Mode
    {
        size.x = document.documentElement.clientWidth;
        size.y = document.documentElement.clientHeight;
    }
    else if (document.body) // other Explorers
    {
        size.x = document.body.clientWidth;
        size.y = document.body.clientHeight;
    }

    return size;
} // end of the "getWindowSize()" function



/**
 * Retourne l'offset du scroll vertical et horizontal
 */
function getScrollOffset()
{
    var offset = new Array;
    if (self.pageYOffset) // all except Explorer
    {
        offset.x = self.pageXOffset;
        offset.y = self.pageYOffset;
    }
    else if (document.documentElement && document.documentElement.scrollTop)
        // Explorer 6 Strict
    {
        offset.x = document.documentElement.scrollLeft;
        offset.y = document.documentElement.scrollTop;
    }
    else if (document.body) // all other Explorers
    {
        offset.x = document.body.scrollLeft;
        offset.y = document.body.scrollTop;
    }

    return offset;
} // end of the "getScrollOffset()" function



/**
 * Retourne les coordonnées du curseur
 */
function getMousePosition(event)
{
    if (!event) event = window.event;
    var cursorPosition = {x:0, y:0};

    if (event.pageX) {
        cursorPosition.x = event.pageX;
        cursorPosition.y = event.pageY;

    } else if (event.clientX) {
        var scrollOffset  = getScrollOffset();
        cursorPosition.x = event.clientX + scrollOffset.x;
        cursorPosition.y = event.clientY + scrollOffset.y;
    }

    return cursorPosition;

} // end of the "getMousePosition()" function



/**
 * essaie de déterminer le meilleur endroit pour afficher une boite
 * autour d'un point central (en général la position du curseur) dans une zone
 *
 * Cette fonction détermine l'endroit (haut-bas, droite-gauche) où
 * on a le plus de place pour afficher un élément.
 */
function getBestDisplayPos(ref, blockSize, zoneSize, margin)
{
    var bestPos = [0, 0];
    var depassement = 0;

    bestPos[0] = getBestPos(ref[0], blockSize[0], zoneSize[0], margin[0]);
    bestPos[1] = getBestPos(ref[1], blockSize[1], zoneSize[1], margin[1]);



    return bestPos;
} // end of the "getBestDisplayPos()" function



/**
 * calcule une coordonnée pour le placement d'un élément
 */
function getBestPos(pos, size, range, margin) {

    var best = 0;

    // Deuxième moitié
    if (pos > (range/2)) {

        // on essaie de placer la boîte avant le milieu
        if (pos - size - margin > 0) {
            best = pos - size - margin;

        } else {
            best = margin; // si on ne peut placer la boite avant le curseur, on garde une marge avec le début
        }


    // Première moitié
    } else {
        if ((pos + size + margin) <= range) {
            best = pos + margin;

        } else {
            best = range - margin - size;
        }
    }

    if (best < 0) {
        best = margin;
    }

    return best;
} // end of the "getBestPos()" function





/**
 * Attache un évènement à un objet et unifie l'objet "événement"
 *
 * Source : http://simon.incutio.com/archive/2004/05/26/addLoadEvent
 */
function addListenner(obj, sEventType, func, bubbling)
{
    //alert('addListenner : ' + sEventType + ', ' + obj.nodeName);
    var sOnEventType = "on" + sEventType;
    var newFunc = function(evt) {
                                    // retrieve event objet with standard properties
                                    evt = getEventObj(evt);

                                    // Manage event bubbling for IE
                                    if (window.event) window.event.cancelBubble=!bubbling;

                                    // Run event handler
                                    return func(evt);
                                };

    if (sEventType == "mousemove" && document.captureEvents && Event) {
        document.captureEvents(Event.MOUSEMOVE);

    } else if (sEventType == "click" && document.captureEvents && Event) {
        document.captureEvents(Event.MOUSEMOVE);

    } else if (sEventType == "mouseup" && document.captureEvents && Event) {
        document.captureEvents(Event.MOUSEUP);

    } else if (sEventType == "mousedown" && document.captureEvents && Event) {
        document.captureEvents(Event.MOUSEDOWN);
    }


    // DOM way of managing events
    if (document.addEventListener) {
        obj.addEventListener(sEventType, func, bubbling);

    // Microsoft (attention ! Chez microsoft, les événements sont lancés dans l'ordre inverse d'arrivée)
    } else if (document.attachEvent) {
        obj.attachEvent(sOnEventType, newFunc);

    // Classic old way + http://simon.incutio.com/archive/2004/05/26/addLoadEvent
    } else {
        var oldEvent = obj[sOnEventType];
        if (typeof obj[sOnEventType] != "function") {
            obj[sOnEventType] = newFunc;
        } else {
            obj[sOnEventType] = function(evt) { var test = oldEvent(evt); return newFunc(evt) && test; };
        }
    }

    return true;
} // end function addListenner()




/* Misc
------------------------------------------------------------------------*/



/**
 * Créé la partie après le point d'interrogation d'une url
 * à partir d'un tableau de variables
 *
 */
function buildQueryVars(aQueryData)
{
    var query = '';
    var first = true;
    for (var svar in aQueryData) {
        if (first) {
            first = false;
        } else {
            query += '&';
        }
        query += svar + '=' + encodeURI(aQueryData[svar]); // escape
    }

    return query;
} // end function buildQueryVars()




var DBG;
/**
 * Si la console de débuggage existe, affiche un message
 */
function DBG_msg(msg, type)
{
    if (DBG != null && DBG.dbgMsg) {
        DBG.dbgMsg(msg, type);
    }
    return true;
}




/**
 * Lance la procédure d'impression, en ouvrant d'abord le popup
 *
 */
function printDoc(targetId)
{
    // Le popup récupère la feuille de style de la page appelante
    styles = document.getElementsByTagName('link');
    for (var i=0; i<styles.length; i++) {
        if (styles[i].rel && styles[i].rel == 'stylesheet') {
            stylesheet = styles[i].href;
        }
    }

    // Ecriture du contenu du popup, et préparation
    this.console  = window.open('','name','height=500,width=700,resizable=yes,scrollbars=yes');
    this.console.document.write(getPrintWindow(stylesheet, targetId));
    this.console.document.close();

    return this;
} // end of "printDoc" function





/**
 * Ouvre un popup pour imprimer une partie de la page
 *
 */
function getPrintWindow(stylesheet, targetId)
{
    var targetnode = document.getElementById(targetId);
    var popupContent = '';
    popupContent += '<html>\r\n';
    popupContent += '    <head>\r\n';
    popupContent += '        <title>Impression de votre document</title>\r\n';
    popupContent += '        <link rel="stylesheet" type="text/css" href="' + stylesheet + '">\r\n';
    popupContent += '    </head>\r\n';
    popupContent += '    <body style="background : #ffffff;">\r\n';
    popupContent += '        <div id="print-zone">\r\n';
    popupContent += '        	<' + targetnode.nodeName + ' id="' + targetId + '">\r\n';
    popupContent += targetnode.innerHTML;
    popupContent += '        	</' + targetnode.nodeName + '>\r\n';
    popupContent += '        </div>\r\n';
    popupContent += '    <SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">\r\n';
    popupContent += '    <!--\r\n';
    popupContent += '    window.print();\r\n';
    popupContent += '    window.close();\r\n';
    popupContent += '    // -->\r\n';
    popupContent += '    </SCRIPT>\r\n';
    popupContent += '    </body>\r\n';
    popupContent += '</html>\r\n';

    return popupContent;
} // end of "getPrintWindow()" function




/**
 * Outils supplémentaires de base
 */

// Removes leading whitespaces
function LTrim(value) {
    var re = /\s*((\S+\s*)*)/;

    return value.replace(re, "$1");
} // end function LTrim()

// Removes ending whitespaces
function RTrim(value) {
    var re = /((\s*\S+)*)\s*/;

    return value.replace(re, "$1");
} // end function RTrim()

// Removes leading and ending whitespaces
function trim(value) {
    return LTrim(RTrim(value));
} // end function trim()







