/**
* Affiche un div tableau, en dessous du champ texte, contenant un calendrier.
* @author Morey Damien
* @copyright Scasi.com - 2006
*/

/**
* Liste des mois
*/
var moisDC = new Array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
"Juillet", "Août", "Septembre", "Octobre", "Novembre",
"Décembre");

/**
* Nombre de jours pour chaque mois
*/
var nbJoursDC = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

/**
* Les jours de la semaine
*/
var joursSemaineDC = new Array("Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di");

/**
* Tableau contenant les jours affichés dans le calendrier
*/
var joursDC = new Array();

/**
* Le mois qui est affiché dans le calendrier
*/
var moisCourantDC = null;

/**
* L'année qui est affichée dans le calendrier
*/
var anneeCouranteDC = null;

/**
* La date qui est déjà présente dans le champs texte (si elle y est)
*/
var jourChoisiDC = null;

/**
* Le champs texte dans lequel doit être affiché le calendrier
*/
var champsTexteDC = null;

/**
* La div contenant le calendrier
*/
var dateChooserDiv = null;

/**
* Le timer utilisé dans onmouseover et onmouseout du dateChooserDiv
*/
var timerDC = null;

/**
 * Element HTML dans lequel doit apparaitre le dateChooser et qui sera mis en
 * position relative
 */
var parent = null;

/**
* Initialisation sur les champs dateDebut et dateFin
*/
function initChampsDate(champs, cible) {
   if (cible != null) {
      parent = cible;
   }
   for (var i = 0; i < champs.length; i++) {
      var c = document.getElementById(champs[i]);
      c.onfocus = dateOnFocus;
      c.onmouseover = dateOnMouseOver;
      c.onmouseout = dateOnMouseOut;
   }
}

var dateOnMouseOver = function () {
   this.className += ' champsTexteOver';
   clearTimeout(timerDC);
}
var dateOnMouseOut = function () {
   timerDC = setTimeout('hideDateChooserDiv()', 1000);
   if (!dateChooserDiv || this != champsTexteDC || dateChooserDiv.style.visibility == 'hidden') {
      this.className = 'champsTexte';
   }
}
var dateOnFocus = function () {
   initDateChooser(this);
   this.select();
};

/**
* Initialisation du calendrier
*
* C'est cette fonction qui doit être appelée dans le champs texte
* @param {Object} champ L'objet du champs texte
*/
function initDateChooser(champ) {
   hideDateChooserDiv();
   jourChoisiDC = null;
   champsTexteDC = champ;
   var date = verifDate(champsTexteDC.value);
   if (champsTexteDC.value != "" && date !== false) {
      var j = date[0];
      if (j[0] == "0") {
         j = j[1];
      }
      var m = date[1];
      if (m[0] == "0") {
         m = m[1];
      }
      moisCourantDC = m - 1;
      anneeCouranteDC = date[2];
      jourChoisiDC = new Date();
      jourChoisiDC.setFullYear(anneeCouranteDC, moisCourantDC, j);
   }
   else {
      date = new Date();
      moisCourantDC = date.getMonth();
      anneeCouranteDC = date.getFullYear();
   }
   creerDateChooserDiv();
   setTableauMoisDC();
   afficheDateChooserTableEntiere();
   showDateChooserDiv();
}

/**
* Créée le div qui contiendra le calendrier
*/
function creerDateChooserDiv() {
   if (dateChooserDiv == null) {
      dateChooserDiv = document.createElement("div");
      dateChooserDiv.id = "dateChooserDiv";
      dateChooserDiv.onmouseover = function () {
         clearTimeout(timerDC);
      }
      dateChooserDiv.onmouseout = function () {
         timerDC = setTimeout('hideDateChooserDiv()', 1000);
      }
      if (parent != null) {
         parent.appendChild(dateChooserDiv);
         parent.style.position = "relative";
      }
      else {
         document.body.appendChild(dateChooserDiv);
      }
   }
}

/**
* Change le mois affiché dans le calendrier
* @param {Object} m le mois a afficher
* @param {Object} a l'année a afficher
*/
function changeMoisDC(m, a) {
   moisCourantDC = m;
   anneeCouranteDC = a;
   setTableauMoisDC();
   afficheDateChooserTable();
   setEmplacementDateChooser();
}

/**
* Construit le tableau contenant les jours à afficher et leurs positions
*/
function setTableauMoisDC() {
   var date = new Date();
   date.setFullYear(anneeCouranteDC, moisCourantDC, 1);
   var premierJour = date.getDay();
   // Si premierjour est dimanche (0), alors on le passe en chiffre 7
   // pour un affichage français (dernier jour de la semaine)
   if (premierJour == 0) { premierJour = 7; }

   var nbJoursMois = getNbJoursMoisDC(moisCourantDC, anneeCouranteDC);
   var cpt = 1; // jour courant
   joursDC = new Array();
   for (var ligne = 1; cpt <= nbJoursMois; ligne++) {
      joursDC[ligne] = new Array();
      for (var colonne = 1; colonne < 8; colonne++) {
         if (ligne == 1) {
            if (colonne < premierJour) {
               joursDC[ligne][colonne] = "";
            }
            else {
               joursDC[ligne][colonne] = cpt++;
            }
         }
         else {
            if (cpt > nbJoursMois) {
               joursDC[ligne][colonne] = "";
            }
            else {
               joursDC[ligne][colonne] = cpt++;
            }
         }
      }
   }
}

/**
* Affiche le calendrier
*/
function afficheDateChooserTableEntiere() {
   var html = '<div id="calMois"><div class="moisDC">' + moisDC[moisCourantDC] + " " +
   anneeCouranteDC + '</div>';
   html += '<table class="joursDC" cellpadding="0" cellspacing="0"><tr>';
   for (var i = 0; i < joursSemaineDC.length; i++) {
      html += '<th class="thJoursDC">' + joursSemaineDC[i] + '</th>';
   }
   html += '</tr>';
   html += afficheJoursDC();
   html += '</table></div>';
   dateChooserDiv.innerHTML = html;
   afficherLiensDC();
}
function afficheDateChooserTable() {
   var html = '<div class="moisDC">' + moisDC[moisCourantDC] + " " +
   anneeCouranteDC + '</div>';
   html += '<table class="joursDC" cellpadding="0" cellspacing="0"><tr>';
   for (var i = 0; i < joursSemaineDC.length; i++) {
      html += '<th class="thJoursDC">' + joursSemaineDC[i] + '</th>';
   }
   html += '</tr>';
   html += afficheJoursDC();
   html += '</table>';
   document.getElementById('calMois').innerHTML = html;
}

function afficherLiensDC() {
   var html = '<table class="liensDC"><tr>'
   + '<td><a href="javascript: void(0);" onclick="anneePrecDC(false)"  ondblclick="anneePrecDC(true)" class="aLiensDC"><b>&lt;&lt;</b></a></td>'
   + '<td><a href="javascript: void(0);" onclick="moisPrecDC(false)"  ondblclick="moisPrecDC(true)" class="aLiensDC"><b>&lt;</b></a></td>'
   + '<td><a href="javascript: void(0);" onclick="hideDateChooserDiv()" class="aLiensDC">Fermer</a></td>'
   + '<td><a href="javascript: void(0);" onclick="moisSuivDC(false)"  ondblclick="moisSuivDC(true)" class="aLiensDC"><b>&gt;</b></a></td>'
   + '<td><a href="javascript: void(0);" onclick="anneeSuivDC(false)"  ondblclick="anneeSuivDC(true)"class="aLiensDC"><b>&gt;&gt;</b></a></td>'
   + '</tr></table>';
   dateChooserDiv.innerHTML += html;
}

var onLiensDCMouseOver = function () { this.className += ' divLiensDCOver'; };
var onLiensDCMouseOut = function () { this.className = 'divLiensDC'; };
var onLiensDCClick = function () {
   if (this.id == 'anneePrec') { anneePrecDC(false); }
   else if (this.id == 'moisPrec') { moisPrecDC(false); }
   else if (this.id == 'moisSuiv') { moisSuivDC(false); }
   else if (this.id == 'anneeSuiv') { anneeSuivDC(false); }
}
var onLiensDCDblClick = function () {
   if (this.id == 'anneePrec') { anneePrecDC(true); }
   else if (this.id == 'moisPrec') { moisPrecDC(true); }
   else if (this.id == 'moisSuiv') { moisSuivDC(true); }
   else if (this.id == 'anneeSuiv') { anneeSuivDC(true); }
}

/**
* Affiche les jours du mois et de l'année choisis en prenant le tableau
* construit par la fonction setTableauMoisDC
*/
function afficheJoursDC() {
   var html = "";
   var d = new Date();
   for (var ligne = 1; ligne < 7; ligne++) {
      html += '<tr>';
      for (var colonne = 1; colonne < 8; colonne++) {
         if (!joursDC[ligne] || !joursDC[ligne][colonne]) {
            var classe = "jourrienDC";
            var valeur = "&nbsp;";
            var over = false;
         }
         else if (   joursDC[ligne][colonne] == d.getDate()
         && moisCourantDC == d.getMonth()
         && anneeCouranteDC == d.getFullYear()) {
            var classe = "aujourdhuiDC";
            var over = true;
         }
         else if (jourChoisiDC && joursDC[ligne][colonne] == jourChoisiDC.getDate()
         && moisCourantDC == jourChoisiDC.getMonth()
         && anneeCouranteDC == jourChoisiDC.getFullYear()) {
            var classe = "jourchoisiDC";
            var over = true;
         }
         else {
            var classe = "jourautreDC";
            var over = true;
         }
         if (!joursDC[ligne] || !joursDC[ligne][colonne]) {
            var valeur = "&nbsp;";
         }
         else {
            var valeur = '<a class="aJourDC" href="javascript: void(0)" '
            + 'onclick="selectionnerJourDC(' + joursDC[ligne][colonne] + ')">' +
            + joursDC[ligne][colonne] + '</a>';
         }
         html += '<td class="' + classe + '"';
         if (over == true) {
            html += ' onmouseover="this.className=\'jouroverDC\';"'
            + ' onmouseout="this.className=\'' + classe + '\';"';
         }
         html += '>' + valeur + '</td>';
      }
      html += '</tr>';
   }
   return html;
}

/**
* Retourne le nombre de jours contenus dans moisCourantDC
*/
function getNbJoursMoisDC(mois, annee) {
   mois = enEntier(mois);
   if (mois == 1) {
      var a = annee;
      if (((a % 4 == 0) && (a % 100 != 0)) || (a % 400 == 0)) {
         // Année bissextile donc on ajoute un jour a février
         var nb = 29;
      }
      else {
         var nb = 28;
      }
   }
   else {
      // un recupere le nombre de jour dans le mois
      var nb = nbJoursDC[mois];
   }
   return nb;
}

/**
* Cache complètement le calendrier
*/
function hideDateChooserDiv() {
   if (dateChooserDiv) {
      champsTexteDC.className = 'champsTexte';
      dateChooserDiv.style.visibility = "hidden";
   }
}

/**
* Rends le calendrier visible
*/
function showDateChooserDiv() {
   if (dateChooserDiv) {
      setEmplacementDateChooser();
      dateChooserDiv.style.visibility = "visible";
   }
}

// Actions sur le calendrier :

/**
* Action executée lorsqu'on clique sur un jour du calendrier : met cette date
* dans le champs texte et ferme le calendrier
* @param {Object} numeroJour
*/
function selectionnerJourDC(numeroJour) {
   var d = construitDate(numeroJour, moisCourantDC + 1, anneeCouranteDC);
   setDate(champsTexteDC, d);
   hideDateChooserDiv();
}

/**
* Construit une string date au format jj/mm/aaa à partir de j, m et a
*/
function construitDate(j, m, a) {
   j = enEntier(j);
   m = enEntier(m);
   a = enEntier(a);
   if (j < 10) {
      j = "0" + j.toString();
   }
   if (m < 10) {
      m = "0" + m.toString();
   }
   return j + "/" + m + "/" + a;
}

/**
* Affiche le même mois mais de l'année précédente
*/
function anneePrecDC(dblClick) {
   if (dblClick && !is_ie) {
      return;
   }
   changeMoisDC(moisCourantDC, --anneeCouranteDC);
}

/**
* Affiche le mois précédent
*/
function moisPrecDC(dblClick) {
   if (dblClick && !is_ie) {
      return;
   }
   moisCourantDC--;
   if (moisCourantDC < 0) {
      moisCourantDC = 11;
      anneeCouranteDC--;
   }
   changeMoisDC(moisCourantDC, anneeCouranteDC);
}

/**
* Affiche le mois suivant
*/
function moisSuivDC(dblClick) {
   if (dblClick && !is_ie) {
      return;
   }
   moisCourantDC++;
   if (moisCourantDC > 11) {
      moisCourantDC = 0;
      anneeCouranteDC++;
   }
   changeMoisDC(moisCourantDC, anneeCouranteDC);
}

/**
* Affiche le même mois mais de l'année suivante
*/
function anneeSuivDC(dblClick) {
   if (dblClick && !is_ie) {
      return;
   }
   changeMoisDC(moisCourantDC, ++anneeCouranteDC);
}


// Fonctions de calcul de position du calendrier :

/**
* Calcule le décalage à droite de l'objet
*/
function calculateOffsetLeft(r) {
   return calculateOffset(r, "offsetLeft");
}
/**
* Calcule le décalage vertical de l'objet
*/
function calculateOffsetTop(r) {
   return calculateOffset(r, "offsetTop");
}

/**
* Calcule un décalage
*/
function calculateOffset(r, attr) {
   var kb = 0;
   while (r) {
      kb += r[attr];
      r = r.offsetParent;
   }
   return kb;
}

/**
* Calcule l'emplacement de la liste de suggestions
*/
function setEmplacementDateChooser() {
   if (dateChooserDiv) {
      var wViewport = getViewportWidth();
      var hViewport = getViewportHeight();
      // Positionnement en hauteur : si il y a assez de place en bas du champs,
      // on le place la sinon au-dessus
      var pos = calculateOffsetTop(champsTexteDC) - dateChooserDiv.offsetHeight;
      if (pos < 0) {
         pos = calculateOffsetTop(champsTexteDC) + champsTexteDC.offsetHeight;
      }
      dateChooserDiv.style.top = pos + "px";

      // Positionnement en largeur : si il y a assez de place en droit du
      // champs, on le place la sinon a gauche
      var delai = calculateOffsetLeft(champsTexteDC)
      + dateChooserDiv.offsetWidth;
      var pos = calculateOffsetLeft(champsTexteDC);
      if (delai > wViewport) {
         pos = calculateOffsetLeft(champsTexteDC) - dateChooserDiv.offsetWidth
         + champsTexteDC.offsetWidth;
      }
      dateChooserDiv.style.left = pos + "px";
   }
}

/**
* Fonction qui vérifie la validité de la date
*/
function verifDate(input) {
   var regex = new RegExp("[/-]");
   var date = input.split(regex);

   if(isNaN(date[2]) || date[2] < 0) { return false; }

   if (isNaN(date[1]) || date[1] > 12 || date[1] < 1) { return false; }

   if (isNaN(date[0]) || date[0] > getNbJoursMoisDC(date[1] - 1, date[2]) || date[0] < 1) {
      return false;
   }
   date[0] = enEntier(date[0]);
   date[1] = enEntier(date[1]);
   date[2] = enEntier(date[2]);
   return date;
}

function enEntier(chaine) {
   if (isNaN(chaine)) {
      return 0;
   }
   chaine = chaine.toString();
   if (chaine.length > 1 && chaine.charAt(0) == "0") {
      chaine = chaine.substr(1, 1);
   }
   return parseInt(chaine);
}

var agt = navigator.userAgent.toLowerCase();
var is_opera = (agt.indexOf("opera") != -1);
var is_mac = (agt.indexOf("mac") != -1);
var is_konq = (agt.indexOf('konqueror') != -1);
var is_safari = ((agt.indexOf('safari') != -1)
&& (agt.indexOf('mac') != -1)) ? true : false;
var is_khtml  = (is_safari || is_konq);
var is_ie   = ((agt.indexOf('msie') != -1) && (!is_opera) && (!is_khtml));
