//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//! D&eacute;claration des variables globales !
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

var calendarRoot = "calendar";
var nomMois       = new Array("Janvier","F&eacute;vrier","Mars","Avril","Mai","Juin","Juillet","Ao&ucirc;t","Septembre","Octobre","Novembre","D&eacute;cembre");   //Tableau contenant le nom des mois (12 valeurs de 0 à 11)
var nomJours      = new Array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");             //Tableau contenant le nom des jours (7 valeurs de 0 à 6)
var nbDaysInMonth = new Array(31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);         //Tableau contenant le nombre de jours dans un mois (valeurs fixes, cas particulier pour le mois de f&eacute;vrier qui n&eacute;c&eacute;ssite une fonction de bissextilit&eacute;)
var joursferies   = new Array("01/01",  "01/05",  "08/05",  "14/07",  "15/08",  "01/11",  "11/11",  "25/12");

var feriesaleatoires = new Array;                           //Tableau qui contiendra les dates g&eacute;n&eacute;r&eacute;es par la fonction jours_f&eacute;ri&eacute;s pour une ann&eacute;e donn&eacute;e
feriesaleatoires[0]  = "1";                                 //Date de paques (initialis&eacute;e à 1)
feriesaleatoires[1]  = "1";                                 //Date de l'ascension (idem)     
feriesaleatoires[2]  = "1";                                 //date de pentecôte (idem)

var sJour  = 0;                                             //Variable qui contient le jour s&eacute;lectionn&eacute;
var sMois  = 0;                                             //Variable qui contient le mois s&eacute;l&eacute;ction&eacute;
var sAnnee = 0;                                             //Variable qui contient l'ann&eacute;e s&eacute;lection&eacute;e

var crtdate = new Date();                                   //crtdate pour current date

var jour = crtdate.getDay();                                //Variable qui contient le jour actuel !!0 pour dimanche, 1 pour lundi ... 6 pour samedi!!
var mois = crtdate.getMonth();                              //Variable qui contient le mois actuel !! 0 pour janvier, 11 pour d&eacute;cembre !!

indice_mois = (mois + 1);                                   //Mise en forme USA -> EU
if(indice_mois < 10) {indice_mois = ("0"+indice_mois)}      //Mise en forme : rajoute un 0 devant le chiffre si il est inf&eacute;rieur à 10

var annee = crtdate.getFullYear();                          //Variable qui contient l'ann&eacute;e actuelle
                                                            //!!Permet de r&eacute;cup&eacute;rer la valeur de l'ann&eacute; sur 4 chiffres pour la date pass&eacute;e en paramètre!!

var indice_jour = crtdate.getDate();                        //Variable qui contient la valeur du jour du mois [1 à 31]
if(indice_jour < 10) {indice_jour = ("0"+indice_jour)}      //mise en forme...

var Mouse_X;                                                //Variable globale Position X de la souris
var Mouse_Y;                                                //Variable globale Position Y de la souris

if(sJour  == "") { sJour = jour; }                          //Initialisation des variables au d&eacute;but si l'on ne s&eacute;lectionne rien
if(sMois  == "") { sMois = mois; }                          //Pareil pour le mois
if(sAnnee == "") {sAnnee = annee;}                          //Pareil pour l'ann&eacute;e

document.onmousemove = WhereMouse;                          //Indique la position de la souris sur la page

//*********************************************************************************************************************************
//* Se charge de montrer/cacher l'&eacute;lement calendrier selon le navigateur internet (firefox ne prend pas en charge l'objet .event) *
//*********************************************************************************************************************************
function affiche_calendrier(id_input)
{
  vient_d_etre_affiche = true;
  champ_a_modifier = id_input;
  //alert("Vous allez maintenant modifier le contenu de "+champ_a_modifier);
  if(document.getElementById("calendrier").style.visibility == "visible")
  {
    document.getElementById("calendrier").style.visibility = "hidden";        //si le calendrier est d&eacute;jà affich&eacute;, on le cache.
  } else { 
    document.getElementById("calendrier").style.visibility = "visible";
    dispCal();                                                                //appelle la fonction dispCal (g&eacute;n&eacute;ration du tableau calendrier)
  }
}

//****************************************************************************************************************************
//* D&eacute;termine si une ann&eacute;e est bissextile ou non, tout simplement en v&eacute;rifiant s'il existe le 29 f&eacute;vrier de l'ann&eacute;e en cours *
//* Entr&eacute;e: variable annee                                                                                                   *
//* Sortie: bool&eacute;en VRAI ou FAUX                                                                                             *
//****************************************************************************************************************************
function isBissextile(annee)
{
  fev = new Date(annee, 1, 29);
  if(fev.getDate() == 29) {return(true);} else {return(false);}
}


//***************************************************************************
//* Fonction qui d&eacute;termine la position du curseur de la souris dans la page *
//***************************************************************************
function WhereMouse(e)
{
  // L'&eacute;v&eacute;nement est pass&eacute;e à la fonction
  // donc tous sauf IE…
  if(e)                          // Si le curseur de la souris a boug&eacute;...
  {                              // Dans ce cas on obtient directement la position dans la page
    Mouse_X = e.pageX;
    Mouse_Y = e.pageY;
  } else {                       // Dans ce cas on obtient la position relative à la fenêtre d'affichage
    Mouse_X = event.clientX;
    Mouse_Y = event.clientY;
  }

}

//*************************************************************
//* Fonction qui actualise le calendrier selon l'incr&eacute;mention *
//*************************************************************
function changeMonth(type)
{
  if(type == "+")
  {
    if(sMois == 11) {sAnnee++; sMois = 0;} else {sMois++;} //Si l'on &eacute;tait au mois de d&eacute;cembre lors d'une incr&eacute;mentation, on retombe sur le mois 0 (janvier) sinon on incr&eacute;mente de 1
  }
  if(type == "-")
  {
    if(sMois == 0) {sAnnee--; sMois = 11;} else {sMois--;} //Si l'on &eacute;tait au mois de janvier lors d'une d&eacute;cr&eacute;mentation, on retombe sur le mois 11 (d&eacute;cembre) sinon on d&eacute;cr&eacute;mente de 1
  }
  dispCal();                                               // puis on reg&eacute;nère un nouveau calendrier
}


//*********************************************************************************************************
//* Fonction qui d&eacute;termine le nombre de jours maximum d'un mois, selon que l'ann&eacute;e soit bissextile ou non *
//*********************************************************************************************************
function getNbDay(month, year)
{
   if((month == 1) && (isBissextile(year)))  {return(29);}      //Dans le cas où une ann&eacute;e est bissextile et que l'on demande pour le mois de f&eacute;vrier, la fonction retournera 29...
   if((month == 1) && (!isBissextile(year))) {return(28);}      //Dans le cas où une ann&eacute;e est non bissextile et que l'on demande pour le mois de f&eacute;vrier, la fonction retournera 28...
   return(nbDaysInMonth[month]);                                //Sinon, la fonction ira chercher dans le tableau nbDaysInMonth le nombre de jours du mois voulu à l'indice du mois indiqu&eacute;...
}


//*******************************************************
//* Fonction qui g&eacute;nère un calendrier d'un mois en HTML *
//*******************************************************
function dispCal()
{
  //Cr&eacute;ation d'un objet date pour savoir le mois et l'ann&eacute;e actuelle à chaque appel de la fonction dispCal (la variable globale "mois" cr&eacute;e des erreurs si la fonction dispCal est appel&eacute;e plus d'une fois)
  var avoir_date = new Date();
  var le_mois = avoir_date.getMonth();
  var l_annee = avoir_date.getFullYear();

 //Entête du calendrier (peut être pass&eacute; par style CSS... mais pr&eacute;sente certaines incompatibilit&eacute;es: border-collapse)
  codeHtml="<table border=\"1\" cellpadding=\"2\" cellspacing=\"0\" style=\"cursor:default; width=\"50\" class=\"calendar\>";
  codeHtml+="    <tr align=\"center\">";

 //Structure conditionelle qui empêche d'aller sur les mois ant&eacute;rieurs au mois actuel.
  if (((sMois < le_mois) || (sMois == le_mois)) && (l_annee == sAnnee)){
  codeHtml+="         <th class=\"titre\"> </th> <td class=\"titre\" colspan=\"5\" bgcolor=\"#FFFFFF\"><b> "+nomMois[sMois]+" "+sAnnee+" </b></td> <th class=\"titre\" style=\"cursor:pointer; border:0px solid\" onClick=\"javascript:changeMonth('+');\"> <img src=\""+calendarRoot+"/img/droite_16.png\"> </th>";
  }
  else if ((sMois > le_mois) || (sAnnee > l_annee)){
  codeHtml+="         <th class=\"titre\" style=\"cursor:pointer\" onClick=\"javascript:changeMonth('-');\"> <img src=\""+calendarRoot+"/img/gauche_16.png\"> </th> <td class=\"titre\" colspan=\"5\" bgcolor=\"#FFFFFF\"><b> "+nomMois[sMois]+" "+sAnnee+" </b></td> <th class=\"titre\" style=\"cursor:pointer\" onClick=\"javascript:changeMonth('+');\"> <img src=\""+calendarRoot+"/img/droite_16.png\"> </th>";
  }

  codeHtml+="        </tr>";
  codeHtml+="    <tr align=\"center\" class=\"libelle_jour\">";

  //Boucle POUR qui rempli le nom des jours dans la 2ème ligne du tableau.
  for(i = 0; i < nomJours.length; i++)
  {
    codeHtml+="          <td style=\"border:0px\"><b>"+nomJours[i]+"</b></td>";
  }  
  codeHtml+="    </tr>";

  // Corps du calendrier:
  
  // +++ Premiers jours du mois +++
  jMois = new Date(sAnnee, sMois, 1);
  wday = jMois.getDay();        //variable wday (pour "week day") : charg&eacute; de r&eacute;cup&eacute;rer à quel jour correspond le 1er jour du mois (0: dimanche, 1:lundi ... 6:samedi)
  if(wday == 0) {wday = 7;}     //si ce jour correspond à un dimanche (javascript est au format US et place le dimanche en d&eacute;but de semaine -> sunday: 0), on le d&eacute;terminera cette valeur en pos 7 pour la placer en fin de semaine
                                //ainsi on aura les correspondances suivantes: lundi: 1, mardi: 2, mercredi: 3, jeudi: 4, vendredi: 5, samedi: 6, dimanche: 7
  wday--;                       //Pour revenir avec 7 &eacute;lements de 0 à 6, on d&eacute;cr&eacute;mente la variable wday de 1 (lundi: 0, mardi: 1, mercredi: 2, jeudi: 3, vendredi: 4, samedi: 5, dimanche: 6)    
  crtDay = 1;                   // crtDay pour current Day (au d&eacute;but, c'est le 1er du mois)

  codeHtml+="    <tr align=\"center\">";

  // +++ Colonne de d&eacute;callage pour les jours du mois d'avant +++ (sert à remplir les premières cases du calendrier par les derniers jours du mois pr&eacute;c&eacute;dent)
  for(decal = 0; decal < wday; decal++)
  {
    calJ = new Date(sAnnee, sMois, 1-(wday-decal));
    codeHtml += "<td style=\"border:0px\"><font color=\"#cccccc\">"+calJ.getDate()+"</font></td>";
  }  
    date_actuelle = (indice_jour+"/"+indice_mois+"/"+annee);
    test = new Date(sAnnee, sMois, crtDay);

  //On cr&eacute;e une boucle POUR qui va incr&eacute;menter le 1er jour du mois et l'inscrire entre des balises TD pour 7 balises TD (fini de remplir une ligne du jour actuel jusqu'en fin de semaine)
  //Boucle qui rempli le reste de la 1ère ligne par les premiers jours du mois en cours
  //Pour cette boucle, on fait appel à 5 sous-fonctions.
  //Ensuite, selon que la date soit sup&eacute;rieure ou inf&eacute;rieure à la date actuelle, on g&eacute;nère une case TD...

  for(j = 0; j < 7-wday; j++)             
  {
    test = new Date(sAnnee, sMois, crtDay);             //D&eacute;fini une date grâce à l'objet date
    num_jour_de_case = test.getDay();                   //R&eacute;cupère le num&eacute;ro de jour de case (0 1 2 3 4 5 6)
    jour_de_case = correspond(num_jour_de_case);        //Converti ce num&eacute;ro en sa valeur r&eacute;elle (dimanche, lundi, mar...)
    date_courante = id_case(crtDay);                    //D&eacute;fini la date au format jj/mm/aaaa de la case qui va être g&eacute;n&eacute;r&eacute;e
    jours_feries(sAnnee);                               //Appel à la fonction qui se charge de d&eacute;terminer les 3 jours f&eacute;ri&eacute;s al&eacute;atoires en focntion de l'ann&eacute;e au format aaaa
    style = style_case(crtDay);                         //D&eacute;fini le style CSS à appliquer
    etat = compare_dates(date_courante);                //D&eacute;termine le type de TD à g&eacute;n&eacute;rer en fonction de la date à g&eacute;n&eacute;rer

    if (etat == "INF"){                                 // Si la case que l'on va cr&eacute;er est un jour pass&eacute;
    codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , old\" onClick=\"alert('vous ne pouvez pas s&eacute;lectionner un jour pass&eacute;')\" onMouseOver=\"this.style.color='#606060'\" onMouseOut=\"this.style.color='#606060'\" >" +crtDay+ "</td>";
    }

    else if (etat == "EGAL"){                           // Si la date que l'on va cr&eacute;er est un jour pr&eacute;sent.
    codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , "+style+"\" onClick=\"javascript:clic_jour(this.id); javascript:affiche_calendrier()\" onMouseOver=\"this.style.color='#ff6000'\" onMouseOut=\"this.style.color='#000000'\" >" +crtDay+ "</td>"; 
    }
    
    else if (etat == "SUP"){                            // Si la date que l'on va cr&eacute;er est un jour futur.
    codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , "+style+"\" onClick=\"javascript:clic_jour(this.id); javascript:affiche_calendrier()\" onMouseOver=\"this.style.fontWeight='bold' ; this.style.color='#208000'\" onMouseOut=\"this.style.fontWeight='normal' ; this.style.color='#000000'\" >" +crtDay+ "</td>"; 
    }

    crtDay++;
  }
  codeHtml+="    </tr>";                                //Et qui fait un retour à la ligne une fois les 7 balises(premières cases) cr&eacute;ees (fin de boucle POUR)

  // +++ Autres lignes du calendrier +++
  lastDay = getNbDay(sMois, sAnnee);                    //Fait appel à la fonction getNbDay pour avoir le nombre de jours dans le mois courant (envoie en paramètre sMois et sAnnee)
  while(crtDay <= lastDay)                              //On cr&eacute;e une boucle TANTQUE la variable crtDay est inf&eacute;rieure ou &eacute;gale au nombre de jours dans le mois 
  {
    codeHtml+="    <tr align=\"center\">";
    // Rempli pour le mois entier jusqu'au dernier jour du mois...
    //On fait aussi appel aux 5 mêmes sous-fonctions
    for(j = 0; j < 7; j++)
    {        
      cMois = new Date(sAnnee, sMois, crtDay);
      if(cMois.getMonth() == sMois)
      {
        test = new Date(sAnnee, sMois, crtDay);
        num_jour_de_case = test.getDay();
        jour_de_case = correspond(num_jour_de_case);
        date_courante = id_case(crtDay);
        jours_feries(sAnnee);
        style = style_case(crtDay);
        etat = compare_dates(date_courante);

        if (etat == "INF"){                             // Si la case que l'on va cr&eacute;er est un jour pass&eacute;
        codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , old\" onClick=\"alert('vous ne pouvez pas s&eacute;lectionner un jour pass&eacute;')\"onMouseOver=\"this.style.color='#606060'\" onMouseOut=\"this.style.color='#606060'\" >" +crtDay+ "</td>";
        }

        else if (etat == "EGAL"){                       // Si la date que l'on va cr&eacute;er est un jour pr&eacute;sent.
        codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , "+style+"\" onClick=\"javascript:clic_jour(this.id); javascript:affiche_calendrier()\" onMouseOver=\"this.style.color='#ff6000'\" onMouseOut=\"this.style.color='#000000'\" >" +crtDay+ "</td>"; 
        }
        
        else if (etat == "SUP"){                        // Si la date que l'on va cr&eacute;er est un jour futur.
        codeHtml += "<td id=\""+date_courante+"\" class=\""+jour_de_case+" , "+style+"\" onClick=\"javascript:clic_jour(this.id); javascript:affiche_calendrier()\" onMouseOver=\"this.style.fontWeight='bold' ; this.style.color='#208000'\" onMouseOut=\"this.style.fontWeight='normal' ; this.style.color='#000000'\" >" +crtDay+ "</td>"; 
        }


      } else {
        codeHtml += "<td style=\"border:0px\"><font color=\"#cccccc\">"+cMois.getDate()+"</font></td>";
      }
      crtDay++;
    }
    codeHtml+="    </tr>";
  }

  codeHtml+="</table>";

  document.getElementById("calendrier").innerHTML = codeHtml;
}


//************************************************************************
//*Fonction qui attribue pour une case sa date (format jj/mm/aaaa) en ID:*
//************************************************************************
function id_case(jour_case)
{
  mois_case = (sMois + 1);
  jour_case = crtDay;

  if(jour_case < 10){
  jour_case = ("0"+jour_case);
  }

  if(mois_case < 10){
  mois_case = ("0"+mois_case);
  }
  return (jour_case+"/"+mois_case+"/"+sAnnee);
}

//****************************************************************************
//*Fonction qui d&eacute;termine le style CSS d'une case en fonction de sa date     *
//*3 styles sont  possible selon la date: normal, jour present ou jour f&eacute;ri&eacute; *
//****************************************************************************
function style_case(le_jour)
{
  le_mois = (sMois + 1);            //Mise en forme USA -> EU

  if(le_jour < 10){                 //Mise en forme si nombre inf. à 10, on ajoute un 0 devant
  le_jour = ("0"+le_jour);
  }

  if(le_mois < 10){                 //Idem...
  le_mois = ("0"+le_mois);
  }

  //Dans le cas où une case correspond à la date de d&eacute;but s&eacute;lectionn&eacute;...
  if(date_courante == (champ_a_modifier.value)){return ("debut")}

  //Dans le cas où une case correspond à la date de fin s&eacute;lectionn&eacute;...
 // if(date_courante == (document.formulaire.date_fin.value)){return ("fin")}

  //Dans le cas où une case correspond à la date actuelle...
  if(date_actuelle == date_courante){return ("present")}

  //Dans le cas où une case correspondrait à un jour f&eacute;ri&eacute; du tableau joursferies...
  for (k = 0; k < joursferies.length; k++){
  if(joursferies[k] == (le_jour+"/"+le_mois)){return ("ferie")}
  }

  //Dans le cas où une case correspondrait à un des 3 jours f&eacute;ri&eacute;s al&eacute;atoires...
  for (l = 0; l < feriesaleatoires.length; l++){
  if(feriesaleatoires[l] == (le_jour+"/"+le_mois)){return ("ferie")}
  }

  return ("normal");
}

//*********************************************************************************
//* Fonction qui met en forme l'attribut CSS avec l'indice du jour correspondant  *
//* (il est impossible qu'un style CSS commence par un chiffre)                   *
//*********************************************************************************
function correspond(num_jour)
{
  if (num_jour == 0){return ("dimanche");}
  if (num_jour == 1){return ("lundi");}
  if (num_jour == 2){return ("mardi");}
  if (num_jour == 3){return ("mercredi");}
  if (num_jour == 4){return ("jeudi");}
  if (num_jour == 5){return ("vendredi");}
  if (num_jour == 6){return ("samedi");}
}


//***********************************************************************************************************************
//*Fonction qui se charge de mettre dans le champ (input) en question la date du jour cliqu&eacute; sur une case du calendrier *
//***********************************************************************************************************************
function clic_jour(jour_clique) 

{
  document.getElementById(champ_a_modifier).value = jour_clique;
}


//******************************************************************************************
//* Fonction qui compare si une date est inf&eacute;rieur, &eacute;gale ou sup&eacute;rieure à al date actuelle *
//******************************************************************************************
function compare_dates(testez_moi)
{ 
  var date_a_tester = new String(testez_moi);                  //d&eacute;coupage de la date d'iD de la case (qui est une date au format jj/mm/aaaa) en 3 variables pour pouvoir y effectuer des op&eacute;rations de comparaison...

  annee_a_tester = date_a_tester.substr(6,4);                  //pour l'ann&eacute;e
  mois_a_tester = date_a_tester.substr(3,2);                   //...
  jour_a_tester = date_a_tester.substr(0,2);                   //...


  if (annee_a_tester < annee ){return ("INF")}                 //L'ann&eacute;e de la case est sup&eacute;rieure à l'ann&eacute;e actuelle
  if (annee_a_tester > annee ){return ("SUP")}                 //L'ann&eacute;e de la case est inf&eacute;rieure à l'ann&eacute;e actuelle
  if (annee_a_tester == annee){                                //Si l'ann&eacute;e de la case est &eacute;gale à l'ann&eacute;e actuelle...
    if (mois_a_tester < indice_mois ){return ("INF")}          //...et que le mois de la case est inf&eacute;rieur au mois actuel
    if (mois_a_tester > indice_mois ){return ("SUP")}          //...et que le mois de la case est sup&eacute;rieur au mois actuel
    if (mois_a_tester == indice_mois){                         //...et que le mois de la case est &eacute;gal au mois actuel...
      if(jour_a_tester < indice_jour ){return ("INF")}         //...et que le jour de la case est inf&eacute;rieur au jour actuel
      if(jour_a_tester > indice_jour ){return ("SUP")}         //...et que le jour de la case est sup&eacute;rieur au jour actuel
      if(jour_a_tester == indice_jour){return ("EGAL")}        //...et que le jour de la case est &eacute;gal au jour actuel
    }
  }
}
