/**
 * 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)
 *
 */



/* 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 (typeof aQueryData[svar] == 'object') {
        aQueryData[svar] = objToUrl(aQueryData[svar]);

      } else if (typeof aQueryData[svar] == 'array') {
        aQueryData[svar] = objToUrl(aQueryData[svar]);
      }

      if (first) {
          first = false;
      } else {
          query += '&';
      }
      query += svar + '=' + encodeURI(aQueryData[svar]); // escape

    }

    return query;
} // end function buildQueryVars()
*/


/**
 * objToUrl
 */
/*function objToUrl(obj)
 {
    var str = '';
    for (var i in obj) {

    }
 } // end of "objToUrl()"
*/


    /**
     * Construit la liste des variables de l'url
     *
     * @param
     *
     * @return
     */
    function buildQueryVars(vars_array)
    {
        var var_list = [];

        // Parcours une variable de type tableau et créé le code de l'url
        buildUrlValue = function (path, vars_array)
          {
              for (var i in vars_array) {
                  if (typeof vars_array[i] == 'array' || typeof vars_array[i] == 'object') {
                      buildUrlValue(path + '[' + encodeURIComponent(i) + ']', vars_array[i]);
                  } else {
                      var_list.push(path + '[' + encodeURIComponent(i) + ']=' + encodeURIComponent(vars_array[i]));
                  }
              }
          }; // end of "buildUrlValue()"


        for (var i in vars_array)
        {
            if (typeof vars_array[i] == 'array' || typeof vars_array[i] == 'object') {
                buildUrlValue(i, vars_array[i]);
            } else {
                var_list.push(encodeURIComponent(i) + '=' + encodeURIComponent(vars_array[i]));
            }
        }

        /*var sign = '';
        if (var_list.length > 0) {
            sign = '?';
        }
        sign +
        */

        return var_list.join('&');

    } // end of the "buildQueryVars()" function




/**
 * htmlSpecialChars
 *
 * Conversion des entités html
 * (trouvée sur le web, il en manque quelques unes
 * que j'ai enlevé à cause de problème d'encodage de ce fichier)
 *
 */
 function htmlSpecialChars(sText)
 {
    /*if (typeof sText == 'string') {
      return sText.replace(/&/m,'&amp;').replace(/</m,'&lt;').replace(/>/m,'&gt;').replace('\'','&apos;').replace('"','&quot;');
    } else {
      return false;
    }*/

  sText = sText.replace(eval('/&/g'), '&amp;');
  fromTo = new
  Array('&AElig;','Æ','&Aacute;','Á','&Acirc;','Â','&Agrave;','À','&Aring;','Å',
  '&Atilde;', 'Ã','&Auml;','Ä','&Ccedil;','Ç','&ETH;','Ð','&Eacute;','É','&Ecirc;',
  'Ê','&Egrave;','È ','&Euml;','Ë','&Iacute;','Í','&Icirc;','Î','&Igrave;','Ì',
  '&Iuml;','Ï','&Ntilde;','Ñ', '&Oacute;','Ó','&Ocirc;','Ô','&Ograve;','Ò',
  '&Oslash;','Ø','&Otilde;','Õ','&Ouml;','Ö','&THORN; ','Þ','&Uacute;','Ú',
  '&Ucirc;','Û','&Ugrave;','Ù','&Uuml;','Ü','&Yacute;','Ý','&aacute;', 'á',
  '&acirc;','â','&aelig;','æ','&agrave;','à','&aring;','å','&atilde;','ã',
  '&auml;','ä ','&brvbar;','¦','&ccedil;','ç','&cent;','¢','&copy;','©',
  '&deg;','°','&eacute;','é', '&ecirc;','ê','&egrave;','è','&eth;','ð',
  '&euml;','ë','&frac12;','½','&frac14;','¼','&frac34; ','¾','&gt;','>',
  '&gt','>','&iacute;','í','&icirc;','î','&iexcl;','¡','&igrave;','ì',
  '&iquest;','¿','&iuml;','ï', '&laquo;','«','&lt;','<','&lt','<',
  '&mdash;','_','&micro;','µ','&middot;','·','&not;','¬',
  '&ntilde;','ñ', '&oacute;','ó','&ocirc;','ô','&ograve;','ò','&oslash;',
  'ø','&otilde;','õ','&ouml;','ö','&para;','¶','&plusmn;','±','&pound;',
  ' £','&quot;','\"','&raquo;','»','&reg;','®','&sect;','§', //'&shy;','\*',
  '&sup1;','¹','&sup2;','²', '&sup3;','³','&szlig;','ß','&thorn;','þ',
  '&uacute;','ú','&ucirc; ','û','&ugrave;','ù','&uuml;','ü',
  '&yacute;','ý','&yen;','¥','&yuml;','ÿ');

  for (i=0; i < fromTo.length; i=i+2)
  sText = sText.replace(eval('/' + fromTo[i+1] + '/g'), fromTo[i])
  return (sText);



 } // end of "htmlSpecialChars()"






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;
}



/**
 * addClass
 */
 function addClass()
 {
   if (arguments.length >= 2) {
     var obj = arguments[0];
     if (!obj) return false;
     if (!obj.className) obj.className = '';

     for (var i = 1; i < arguments.length; i++) {
       if (obj.className.indexOf(arguments[i]) == -1) {
        obj.className += (obj.className ? ' ' : '') + arguments[i];
       }
     }

     obj.className = trim(obj.className);

   }
 } // end of "addClass()"


/**
 * removeClass
 */
 function removeClass()
 {
   if (arguments.length >= 2) {
     obj = arguments[0];
     if (!obj) return false;
     for (var i = 1; i < arguments.length; i++) {
       if (obj.className) {
        obj.className = obj.className.replace(arguments[i], '');
       }
     }
     obj.className = trim(obj.className);
   }
 } // end of "removeClass()"


/**
 * createRandomName
 */
 function createRandomName()
 {
    var str = '';
    var letters = range('a', 'z');
    letters = letters.concat(range('0', '9'));
    for(var i = 0; i < 7; i++) {
        str += letters[getRandomInt(0, 34)];
    }
    return str;

 } // end of "createRandomName()"


function getRandomInt(min, max) {
  return Math.round(Math.random() * (max - min + 1) + min);
}



/**
 * range
 */
 function range(start, end)
 {
    var tab = [];
    for (var chr = start.charCodeAt(0); chr <= end.charCodeAt(0); chr++) {
       tab.push(String.fromCharCode(chr));
    }

    return tab;

 } // end of "range()"




/**
 * 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,menubar=yes,status=no');
    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()





/**
 * Lit les valeurs saisies dans les champs d'un formulaire
 * (type input et select)
 *
 * @param object  form  objet contenant les données à lire
 *
 * @return array  tableau associatif des données lues
 */
 function readForm(form) {

    var aQueryData = {};

    // Lecture des champs textes, des cases à cocher, des boutons radios
    var textareaList = form.getElementsByTagName('textarea');
    var inputList = form.getElementsByTagName('input');
    for (var k = 0; k < inputList.length; k++) {
        if (inputList[k].type == 'checkbox') { // inputList[k].type &&
            aQueryData[inputList[k].name] = 0;
            if (inputList[k].checked) {
                aQueryData[inputList[k].name] = inputList[k].value;
            }

        } else {
        aQueryData[inputList[k].name] = inputList[k].value;
        }
    } // end for

    for (var k = 0; k < textareaList.length; k++) {
        aQueryData[textareaList[k].name] = textareaList[k].value;
    } // end for


    // Lecture des listes déroulantes
    var selectList = form.getElementsByTagName('select');
    for (var k = 0; k < selectList.length; k++) {
      if (typeof selectList[k].selectedIndex == 'number' && typeof selectList[k].name == 'string') {
        aQueryData[selectList[k].name] = selectList[k].options[selectList[k].selectedIndex].value;
      } else {
        alert('probleme avec ' + selectList[k].id + ', name=' + selectList[k].name + ', selectList[k].selectedIndex=' + selectList[k].selectedIndex);
      }
    }

    return aQueryData;

} // end of "readForm()"







/**
 * Positionnement des champs du formulaire
 *
 * @param array postvalues valeurs des champs du formulaire
 */
 function setForm(postvalues)
 {
    for (var key in postvalues) {
        var inputValue = postvalues[key];
        var input = document.getElementById(key);

        if (input) {
            if (input.type == 'checkbox' || input.type == 'radio') {
                if (parseInt(inputValue) == 1) {
                    input.checked = 'checked';
                } else {
                    input.checked = null;
                }

            } else if (input.nodeName == 'SELECT') {
                for (var a = 0; a < input.options.length; a++) {
                    if (input.options[a].value == parseInt(inputValue) || input.options[a].value == inputValue) {
                        input.options[a].selected = 'selected';
                    } else {
                        input.options[a].selected = null;
                    }
                }
            } else {
              input.value = inputValue;
            }
        }
    } // end for
 } // end of "setForm()"




/**
 * getEventTarget
 *
 * http://www.quirksmode.org pour le code original
 */
 function getEventTarget(e)
 {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;

    return targ;

 } // end of "getEventTarget()"



/**
 * createNode
 */
 function createNode(sNodeName, oOptions)
 {
      oNode = document.createElement(sNodeName);

      for (attribute in oOptions) {
        if (attribute == 'innerHTML') {
          oNode.innerHTML = oOptions[attribute];

        } else if (attribute == 'class' || attribute == 'className') {
          oNode.className = oOptions[attribute];

        } else {
          oNode.setAttribute(attribute, oOptions[attribute]);
        }
      }

      return oNode;

 } // end of "createNode()"






