﻿// requière xml.js
// requière tag.js
// requiere ctrl.js
// requiere input.js

// Nombre de valeurs dans une liste mono-valuée au delà duquel on ouvre un assistant de saisie
var MAX_ITEM_IN_LIST = 30;
// Longueur d'un label d'une liste au delà de laquelle il est tronqué
var MAX_LIST_LABEL_LENGTH = 40;
// Longueur visible d'une zone de saisie texte
var MAX_INPUT_SIZE = 60;

// Renvoie true si la langue utilise l'écriture de droite à gauche
function LocaleUtil_isRtlLang(lang)
{
   return ((lang == "ar") || (lang == "he" ));
}

// Générateur de code HTML pour la saisie
//
// En sortie, on renvoie le code HTML de l'input
//
// inputWindow : fenêtre qui gère les actions sur le widget
function Widget_generateInputElement(inputWindow, schemaData, dataElement)
{
   var schemaDesc = schemaData.schema;
   var schemaManager = schemaDesc.schemaManager;
   var fieldName = dataElement.tagName;
   var fieldDesc = schemaDesc.getFieldByName(fieldName);
   var fieldLabel = fieldDesc.getAttribute("screen_name"); 
   
   // Sous champ d'un champ appartenant à un schema composite
   var is_subFieldOfCompositeField = false;
   if (schemaDesc.compositeField != null)
      is_subFieldOfCompositeField = true;
       
   // L'id de l'élément HTML est composé à partir de l'id du champ + _input
   var elemId = dataElement.getAttribute("id");
   var inputId = elemId + "_input";
   
   // fieldDesc.getAttribute("NomAttribut") renvoie null ssi 
   // l'attribut n'existe pas ou est vide
   // Association nomVariable <=> nomContrôle
   var is_composite = ( fieldDesc.getAttribute("composite") == "true" );      
   var concat_ctrl = fieldDesc.getAttribute("concat_ctrl");
   // def_value géré au niveau serveur
   //var def_value = fieldDesc.getAttribute("def_value");
   var is_date = ( fieldDesc.getAttribute("date") == "true" );
   var is_decimal = ( fieldDesc.getAttribute("decimal") == "true" );
   var is_integer = ( fieldDesc.getAttribute("integer") == "true" );
   var len_maxi = fieldDesc.getAttribute("len_maxi");
   var is_link = ( fieldDesc.getAttribute("link") == "true" );
   var liste = fieldDesc.getAttribute("liste");
   var is_marc = ( fieldDesc.getAttribute("marc") == "true" );      
   var is_multiple = ( fieldDesc.getAttribute("multiple") == "true" );
   var mult_maxi = fieldDesc.getMaxOccurs();         
   var is_no_input = ( fieldDesc.getAttribute("no_input") == "true" );
   var is_no_modif = ( fieldDesc.getAttribute("no_modif") == "true" );
   var is_oblig = ( fieldDesc.getAttribute("oblig") == "true" );
   
   var thesProperty = fieldDesc.getAttribute("thesaurus");
   var is_thesaurus = false;
   if (thesProperty)
      is_thesaurus = ( thesProperty.length > 0 );
   
   var separ0 = fieldDesc.getAttribute("separ0");
   
   // Si pas ctrl separ0, le séparateur par défaut est : "/" 
   if (separ0 == null  ||  separ0.length == 0)
      separ0 = "/";
             
   // champ lié ? ==> Renvoie null si pas de table liée
   var linkTable = fieldDesc.getLinkTable();   
   // Source des autorités
   var linkSource = fieldDesc.getLinkSource();
   // Droit de création d'autorité de l'utilisiateur connecté
   var userHasRightToCreateAutority = ( fieldDesc.getAttribute("create") == "true" );
   
   // texte multiligne ?
   var is_multiline_text = false;
   if ( is_multiple && liste==null && linkTable==null )
   {
      is_multiline_text = true;
   }

   //******************************
   // Valeur initiale de la donnée dans la grile de saisie 
   //******************************
   // Si le champ a un display, c'est lui qu'on affiche (cas champ lié)
   // ou lorsque Valeur à saisir == valeur à afficher
   var initValue = dataElement.getAttribute("display"); // valeur à afficher

   if ( initValue == null  ||  liste  ||  is_marc)
   {
      // Prise en compte de la valeur réelle 
      initValue = schemaData.getFieldValue(dataElement);
   }
   
   // Traitement particulier
   if ( is_marc )
      initValue = getInputDataCtrlMarc(initValue);
   else if ( linkTable && is_multiple )
   {
      // Pour la valeur affichée, on remplace le séparateur 
      // de display DORIS "_RS_" par separ0
      initValue = initValue.replace(/_RS_/g, separ0);
   }   
                     
   // widget par défaut   
   var widget = 
         new Tag("input").att("name", inputId).att("id",inputId)
          .att("value", initValue).att("class", "marc")
          .att("size", MAX_INPUT_SIZE)
          .att("onChange", "getView().updateData('"+fieldName + "','" + elemId+"', true);getView().showInputFieldDisplayValue('" + elemId +"') ")
          .att("onKeyUp", "getView().showInputFieldDisplayValue('" + elemId +"')")
          .att("onMouseOver", "getView().showInputFieldDisplayValue('" + elemId +"')")
          .att("onMouseOut", "getView().hideInputFieldDisplayValue()");

   // tdn 23/06/2005 Si 'lang' est spécifié, positionne 'dir'
   var lang = fieldDesc.getAttribute("lang");
   if ( lang )
   {
      var langDir = "ltr";
      if ( LocaleUtil_isRtlLang(lang) ) langDir = "rtl";
      widget.att("dir", langDir);
   }
   
   // Non saisissable
   //----------------
   //appendDebug(fieldDesc.name + ".concat=[" + concat_ctrl + "]");
   // SAU 31.05.2005 : si le champ dispose du contrôle"link", il n'est pas saissable
   if (   is_composite || (concat_ctrl != null)  || is_no_input || is_link
       || (linkTable != null) 
       || (   is_no_modif  &&  initValue != "" 
           && (schemaManager.getCurrentRecordAction() == "updateRecord") ) )
   {
      // Attribut disabled pour <input>, <select>
      // L'attribut disabled ne permet pas de positionner le focus sur la zone, via la fct .focus()
      // L'attribut readonly permet de positionner le focus sur la zone, via la fct .focus()
      widget.att("readonly", "true");
      widget.att("class", "marcReadOnly");
   }
   
  	// SAU 2005.06.21 : dans le cas suivant on force le contrôle "no_input"
   if (    is_no_modif  &&  initValue != "" 
       &&  (schemaManager.getCurrentRecordAction() == "updateRecord")  )
   {
      is_no_input = true;
   }

   if ( is_multiline_text )
   {
      widget.name = "textarea";
      widget.setBody("\n" + initValue); // \n obligatoire pour textarea
      widget.att("rows", 5).att("cols", MAX_INPUT_SIZE).att("wrap", "hard");
   }


   // Ctrl : len_maxi - Nbre maxi de caractères saisissables
   // Non appliqué sur les input associés au contrôle liste et champs liés
   if ( len_maxi != null  &&  liste == null  && linkTable == null)
   {   
      var vlen_maxi = 0;
      if ( isNaN(len_maxi) )
      {
         var mess = "Error \n Field: " + fieldLabel + "\n";
         mess += "The value of len_maxi control is not a number: ";
         mess += len_maxi;
         alert(mess);
      }
      else
      {
         try
         {
            vlen_maxi = parseInt(len_maxi); 
         } 
         catch (ex){};
      }   
      if ( vlen_maxi > 0 )
      {
         widget.att("maxlength", vlen_maxi);
         if ( vlen_maxi <= MAX_INPUT_SIZE )
            widget.att("size", len_maxi);
      }
   }
   
   
   // Ctrl date
   if ( is_date )
   {
      // 10 caractères saisissables au maximum
      widget.att("maxlength", 10);
      widget.att("size", 10);
   }
   
   // Ctrl liste=NomListe
   if ( liste != null )
   {
      // Contenu de la liste
      var list = schemaDesc.getList(liste);
      if ( ! list )
         alert(liste + ": list not found in schema");
   
      // Remplacement du input par une liste html si le nombre de valeur 
      // n'est pas trop élevé. Sinon, on va ouvrir un assistant de saisie
      // Pour une liste multivalué, on va dans tous les cas ouvrir un 
      // assistant
      var useAssist = false;
      if ( (list.length <= MAX_ITEM_IN_LIST) && (mult_maxi <= 1) )
      {
         widget.name = "select";
         // SAU : 31.05.2005, il faut ajouter l'attribut disabled pour ne pas 
         // autoriser la modification
         if ( is_no_input )
            widget.att("disabled", "true");
      }
      else
      {
         widget.att("readonly", "true"); // désactivé
         widget.att("class", "marcReadOnly");
         useAssist = true;
      }
      
      /*
      Si multiple, on initialise la liste des valeurs initiales
      multi_init_value
      */
      var multi_init_value = new Array();
      if ( mult_maxi > 1 )
      {
         // Taille par défaut à 5
         if ( list.length <= 5 )  
            widget.att("multiple", "true").att("size", list.length);
         else   
            widget.att("multiple", "true").att("size", "5");

         // Valeur initiale
         // Cas 1 : Le champ appartient à un schema composite
         if ( is_subFieldOfCompositeField )
         { 
            // Pas de séparateur on découpe la valeur selon la longueur
            // des codes de la liste qui sont identiques
            if ( initValue && initValue.length > 0 )
            {
               // Longueur des codes de la liste
               var codeLength = 0;
               for (var k in list)
               {
                  codeLength = k.length;
                  break;
               }
               // Parcours de la valeur initiale pour extraire les codes
               for (var i=0; i<initValue.length; i++)
               {
                  var listCode = ""; 
                  for (var j=0; j<codeLength; j++)
                     listCode += initValue.charAt(i+j);
                  i += (codeLength - 1);
                  multi_init_value[listCode] = listCode;
               }   
            }   
         }
         else // cas 2 : Le champ n'appartient pas à un schema composite 
         { 
            if ( initValue && initValue.length > 0 )
            {
               var values = initValue.split(separ0);
               for (var i=0; i<values.length; i++)
                 multi_init_value[values[i]] = values[i]; 
            }
         }
      }
      else // sinon il y a peut-être une seule valeur à positionner
      {
         widget.att("size", "1");
         if ( initValue && initValue.length > 0 )
            multi_init_value[initValue] = initValue;
      }
      
      // On construit la liste que si on n'utilise pas l'assistant
      if ( ! useAssist )
      {
         // On ajoute une option vide tout le temps
         var optionWidgets = new Array();
         var optw = new Tag("option").setBody("");
         optionWidgets[optionWidgets.length] = optw; 
         
         // Remplit la liste en positionnant la valeur initiale
         //appendDebug("liste " + fieldDesc.name + " initValue = [" + initValue + "]");  
         // var first = true;   
         if ( list ) for (var key in list)
         {
            var listLabel = list[key];
            // Tronque les libellés trop long
            if ( listLabel.length > MAX_LIST_LABEL_LENGTH )
               listLabel = listLabel.substring(0,MAX_LIST_LABEL_LENGTH) + "...";
            var optw = new Tag("option").att("value", key).setBody(listLabel);
            // Positionne le label complet dans l'attribut title
            optw.att("title", list[key]);
            
            // valeur initialement sélectionnée
            if( initValue && initValue != '' )
            {
               if ( multi_init_value[key] != null )
                  optw.att("selected", "yes");
            }
            optionWidgets[optionWidgets.length] = optw; 
         }
   
         // Compose le texte des options
         var optionsHTML = "";
         for (var i=0; i<optionWidgets.length; i++)
         {
            optionsHTML += optionWidgets[i].text();
         }
         widget.setBody(optionsHTML);
         
         // texte retourné
         ret = widget.text();
      }
      else // on utilise l'assistant
      {
         var visibleValue = "";
         var inputValue = "";
         
         if ( list ) for (var key in list)
         {
            // valeur initialement sélectionnée
            if( initValue && initValue != '' )
            {
               if ( multi_init_value[key] != null )
               {
                  var listLabel = list[key];
                  if  ( visibleValue != "" )
                  {
                     visibleValue += separ0; // ajoute séparateur
                     if ( !is_subFieldOfCompositeField )
                        inputValue += separ0;
                  }
                  visibleValue += listLabel;
                  inputValue += key;
               }
            }
         }
         // On positionne la valeur réelle dans l'attribut inputValue
         // On positionne la valeur visible dans le champ texte lui-même
         widget.att("inputValue", inputValue);
         widget.att("value", visibleValue);
         widget.att("size", MAX_INPUT_SIZE);
         
         var img = new Tag("img").att("src", "icons/css/default/input/input_list.gif");
         img.att("border", "0").att("title", mess_input_list_search);
         var btn = 
            new Tag("a").setBody(img.text())
             .att("href", "javascript:getView().listEdit('"+fieldName + "','" + elemId+"')");
         // texte retourné
         
         // SAU 23.06.2005 : On affiche le bouton de modification de la liste
         // ssi le champ ne dispose pas du contrôle no_input
         if ( is_no_input )
            ret = widget.text();
         else
         ret = btn.text() + widget.text();
      }
      
      
   }
   // COMPOSITE
   else if ( is_composite  &&  !is_no_input)
   {
      // Ajoute un bouton éditer
      var img = new Tag("img").att("src", "icons/css/default/input/input_composite.gif");
      img.att("border", "0").att("title", mess_input_modify_composite_field);
      var btn = 
         new Tag("a").setBody(img.text())
          .att("href", "javascript:getView().compositeEdit('"+fieldName + "','" + elemId+"')");
      ret = btn.text() + widget.text();
   }
   // CHAMP LIE
   else if ( linkTable != null  &&  !is_no_input)
   {
      // Recherche des autorités
      var img = new Tag("img").att("src", "icons/css/default/input/input_link.gif");
      img.att("border", "0").att("title", mess_input_authority_search);
      var btn = 
         new Tag("a").setBody(img.text())
          .att("href", "javascript:getView().linkEdit('"+fieldName + "','" + elemId+"')");
          
      ret = btn.text(); 
      
      // Ajout direct d'autorité    
      if ( userHasRightToCreateAutority )
      {
         var img2 = new Tag("img").att("src", "icons/css/default/input/add_authority.gif");
         img2.att("border", "0").att("title", mess_input_add_authority);
         var btn2 = 
            new Tag("a").setBody(img2.text())
             .att("href", "javascript:getView().createAuthority('"+linkSource+"','"+linkTable+"','"+fieldName + "','" + elemId+"')");
         ret = ret + btn2.text();
      }   
      ret += widget.text();
   }
   // CHAMP LIE THESAURUS EXTERNE
   else if (is_thesaurus)
   {
      //Récupérer les valeurs réelles mais aussi les valeurs visibles ...
      var thesId = fieldDesc.getAttribute("thesaurus");
      var thesTypeFilter = fieldDesc.getAttribute("thesaurus_filter");
      var localformName = "frmInput";   
      var localFieldName = fieldName + "_THESAURUS_LIST";
      var optionsHTML = "";
      var optionWidgets = new Array();
                
      //Liste thesaurus
      //Récupération des valeurs réelles et visibles éventuelles
      var thesLabelValue = dataElement.getAttribute("display");
      var thesIdValue = dataElement.getAttribute("value");      
      //if (fieldName == "SCENARIO")
      //{
      //   alert(thesLabelValue);
      //   alert(thesIdValue);
      //}
      //var thesIdValue = "default:TDE_GEO:660\ndefault:TDE_GEO:662";
      //var thesLabelValue = "TODO label 1\nTODO label 2"
      if (thesLabelValue && thesIdValue)
      {
        var thesLabelValues = thesLabelValue.split("_RS_");
        var thesIdValues = thesIdValue.split("_RS_");
        //var thesIdValues=new Array("default:TDE_GEO:660", "default:TDE_GEO:662");
        //var thesLabelValues=new Array("TODO label 1", "TODO label 2");         
       
         if ( thesLabelValues && thesIdValues) 
         {
            for (var i=0; i<thesLabelValues.length; i++)
            {
               var curLabel = thesLabelValues[i];
               var curId = thesIdValues[i];
               // Tronque les libellés trop long
               if ( curLabel.length > MAX_LIST_LABEL_LENGTH )
                  curLabel = curLabel.substring(0,MAX_LIST_LABEL_LENGTH) + "...";
               var optw = new Tag("option").att("value", curId).setBody(curLabel);
               // Positionne le label complet dans l'attribut title
               optw.att("title", thesLabelValues[i]);
               optionWidgets[optionWidgets.length] = optw; 
            }
         
            // Compose le texte des options
            for (var i=0; i<optionWidgets.length; i++)
            {
               optionsHTML += optionWidgets[i].text();
            }
         }
      }

      //Génération de l'objet liste
      var thesList = new Tag("select").att("multiple", "true");
      thesList.att("name", localFieldName).att("size", "5").att("id", inputId);
      if (optionsHTML.length > 0)
         thesList.setBody(optionsHTML);
      else
         thesList.setBody("\n");
      
      //Bouton d'assistant sur thésaurus
      var imgAssist = new Tag("img").att("src", "icons/css/default/tools/assist_thes.gif");
      imgAssist.att("border", "0").att("title", mess_input_authority_assistant);

      //On se sert de table pour passer le elemId
      var thesTable = elemId;
      var thesAssist = "NULL_DEFAULT_CRIT";
      var thesAction = sysGetAppBaseUrl() + "jsp/thesaurus/thesaurus_assist.jsp";
      var thesTarget = "win_input." + localformName + "." + localFieldName;
      var thesActionType = "thesaurus-input-generic";
      var thesCritNotOblig = "1";

      var btnAssist = new Tag("a").setBody(imgAssist.text());
      var formCall = "javascript:frmShowThesaurusAssist('" + localformName + "','" +
                          thesAction + "','','" + thesTable + "','','" + thesId + "','','" + thesAssist + "','','" + 
                          thesTarget + "','','" + thesActionType + "','','" +thesCritNotOblig + "'";
      if ( thesTypeFilter )
      {
         formCall += ", '', '" + thesTypeFilter + "'";
      }
      formCall += ")";
      btnAssist.att("href", formCall);
      
      //Bouton suppression d'une ligne dans la liste
      var frameName = "win_input";
      
      var imgDelete = new Tag("img").att("src", "icons/css/default/action/input_delete.gif");
      imgDelete.att("border", "0").att("title", mess_input_delete);
      var btnDelete = 
           new Tag("a").setBody(imgDelete.text())
             .att("href", "javascript:inputRemoveSelectedOptions('"+localformName+"','"+localFieldName+
             "');javascript:thesaurusListToSchemaData('" + frameName + "','" + localformName + "','" +
             fieldName + "','" + elemId + "','" + localFieldName +"')");   
                 
      // texte retourné pour affichage dans la div      
     
      // SAU 23.06.2005 : On affiche les boutons d'assitance et de surpression
      // ssi le champ ne dispose pas du contrôle no_input
      if ( is_no_input )
         ret = thesList.text();
      else
      ret = btnAssist.text() + btnDelete.text() + thesList.text();      
   }
   // DATE
   else if ( is_date )
   {
      // tdn 18/07/2005 ajoute l'assistant de saisie que si en modif
      ret = widget.text();
      if ( ! is_no_input )
      {
         var img = new Tag("img").att("src", "icons/css/default/tools/assist_calendar.gif");
         img.att("border", "0").att("title", sysGetMessage("input.date.choose"));
         // Le nom du champ de saisie est l'id de l'élément + "_input"
         var btn = 
            new Tag("a").setBody(img.text())
             .att("href", "javascript:frmShowDateAssist('','crit','" + elemId + "_input')");
         
         ret += btn.text();
      }
   }
   else
   {
      ret = widget.text();
   }
   return ret;
}


/*********************************************************
 * Objet assistant calendrier générique
 * @author tdn
 *********************************************************/
// name : nom de la variable de la window qui référence cet objet
// divDest : la div qui accueille le code HTML
// inputDestElem : id de l'élément du formulaire qui accueille la valeur sélectionnée
// iconPrevHTML, iconNextHTML (opt) : le code HTML des images des boutons
//   pour activer mois suivant/précédent
function CalendarWidget(name, divDest, inputDestElem, iconPrevHTML, iconNextHTML)
{
   this.name = name; // nom de la variable
   this.divContainer = divDest;
   this.inputDestElem = inputDestElem;
   
   this.curDate = new Date(); // date courante sélectionnée
   this.displayDate = new Date(); // date de l'affichage en cours
   
   
   // Code HTML des icones pour naviguer entre mois
   if ( ! iconPrevHTML )
   {
      // TODO RTL
      iconPrevHTML = "<img border='0' src='icons/css/default/nav/nav_prev.gif' alt=\"" + 
         sysGetMessage("calendar.nav.previous") + "\">";
   }
   if ( ! iconNextHTML )
   {
      // TODO RTL
      iconNextHTML = "<img border='0' src='icons/css/default/nav/nav_next.gif' alt=\"" + 
         sysGetMessage("calendar.nav.next") + "\">";
   }
   this.iconPrevHTML = iconPrevHTML;
   this.iconNextHTML = iconNextHTML;
}

// Positionne la date sélectionnée comme date affichée
// - dateVal : aux formats de DateUtil_guessDate
CalendarWidget.prototype.setSelectedDate = function(dateVal)
{
   var dateObj = DateUtil_guessDate(dateVal);
   if ( dateObj )
   {
      this.curDate = dateObj;
      this.displayDate = dateObj;
   }
}

// Renvoie les 2 caractères du jour
// ex: lu, Ma, ....
CalendarWidget.prototype.getDayShortTitle = function(day_name)
{
   var dname ="<TD class='calendarDayTitle'>"+day_name+"</TD>";
   return dname;
}

// Retourne la version anglaise du nom d'un mois pour etre utiliser avec
// new Date();
CalendarWidget.prototype.getMonthLiteralEnglish = function(monthNumber)
{ 
   var monthIndex = eval(monthNumber) - 1;
   var monthName = new Array("January", "February", "March", "April",
                              "May", "June", "July", "August", "September",
                                           "October", "November", "December");
   return monthName[monthIndex];
}    

// Refresh le container
// - displayDate (opt) : si non spécifié, date du moment
// - autoHideDelay (opt) : si > 0, délai en secondes au delà duquel, si la div est
//  encore visible et qu'aucun mouvement de souris n'a eu lieu, masque
//  la div
CalendarWidget.prototype.show = function(displayDate, autoHideDelay) 
{
   if ( ! displayDate ) 
   {
      displayDate = new Date();
   }
   this.displayDate = displayDate;
   
   var mm = this.displayDate.getCurrentMonth();
   var yy = this.displayDate.getCurrentYear();
   this.divContainer.innerHTML = this.getHTML(mm,yy);
   sysShow(this.divContainer.id, sysMouseX, sysMouseY);      
   if ( autoHideDelay > 0 )
      this.checkAutoHideDelay(autoHideDelay, true);
}   
// initialCall = true si premier appel pour déclencher uniquement le timer
CalendarWidget.prototype.checkAutoHideDelay = function(autoHideDelay, initialCall) 
{
   if ( ! sysIsVisible(this.divContainer.id) ) return;
   var x = this.curMouseX;
   var y = this.curMouseY;
   if ( initialCall || (x==0 && y==0) || (this.lastMouseX != x && this.lastMouseY != y) )
   {
      this.lastMouseX = x;
      this.lastMouseY = y;
      this.hideTimer = setTimeout(this.name + ".checkAutoHideDelay(" + autoHideDelay + ")", autoHideDelay*5000);
      return;
   }
   this.hide();
}
CalendarWidget.prototype.onMouseMove = function ()
{
   this.curMouseX = sysMouseX;
   this.curMouseY = sysMouseY;
}
CalendarWidget.prototype.restartTimer = function()
{
   // Remet à zéro l'état du timer
   this.curMouseX = 0;
   this.curMouseY = 0;   
}
CalendarWidget.prototype.hide = function()
{
   clearTimeout(this.hideTimer);
   sysHide(this.divContainer.id);
   this.restartTimer();
}

// Refresh le container avec le mois suivant
CalendarWidget.prototype.showNext = function() 
{
   this.displayDate.addMonth();
   var mm = this.displayDate.getCurrentMonth();
   var yy = this.displayDate.getCurrentYear();
   this.divContainer.innerHTML = this.getHTML(mm,yy);
   
   // Remet à zéro l'état du timer
   this.restartTimer();
}

// Refresh le container avec le mois précédente
CalendarWidget.prototype.showPrevious = function() 
{
   this.displayDate.getPreviousMonth();
   var mm = this.displayDate.getCurrentMonth();
   var yy = this.displayDate.getCurrentYear();
   this.divContainer.innerHTML = this.getHTML(mm,yy);
   
   // Remet à zéro l'état du timer
   this.restartTimer();
}  


// Renvoie le code cliquable d'un jour
// Si isCurDay ou isSelectedDay, met en style différent
CalendarWidget.prototype.getDayHref = function(day,mm,yy, isCurDay, isSelectedDay) 
{
   var isoDate = DateUtil_getISOFormat(new Array(day,mm,yy));
   var style = (isCurDay ? "calendarDayCurrent" : (isSelectedDay ? "calendarDaySelected":""));
   var ret = "<a href=\"javascript:" + this.name + ".retrieveDate('" + isoDate + "')\" ";
   ret += " class='" + style + "' >";
   ret += day + "</a>";
   return ret;
}

// Rapatrie la date spécifiée dans la zone
// doNotAutoClose (opt) : si true, ne fermr pas le calendrier
CalendarWidget.prototype.retrieveDate = function(dateIso, doNotAutoClose) 
{
   if ( ! this.inputDestElem )
   {
      alert("retrieveDate impossible, membre inputDestElem non initialisé");
   }
   else
   {
      this.inputDestElem.value = DateUtil_getVisibleFormat(dateIso);
   }
   // Fermeture auto
   if ( ! doNotAutoClose ) this.hide();
}

// Renvoie le code HTML pour afficher un mois et une année donnée
// Si date n'est pas spécifiée, prend la date du jour
CalendarWidget.prototype.getHTML = function(mm,yy) 
{  
   var htmlTable = '';
   var month_length  = this.getDaysInMonth(mm,yy);
   
   var formatDate = this.getMonthLiteralEnglish(mm);
   var begin_date = new Date(formatDate+" 1, "+yy);
   var start_day = begin_date.getDay()-1;
   var year_up = yy;
   
   if (start_day == -1)
      start_day = 06;
         
   var day = 1;
   htmlTable += "<TABLE class='calendarTable' border='1' onMouseMove='" + this.name + ".onMouseMove()'><TR>";
   // Titre du mois
   htmlTable += "<TD colspan='7' class='calendarMonthTitle' >"
   // TODO : RTL
   htmlTable += "<a href='javascript:" + this.name + ".showPrevious()" + "'>" + this.iconPrevHTML + "</a>";
   htmlTable += "&nbsp;<a href='javascript:" + this.name + ".showNext()" + "'>" + this.iconNextHTML + "</a>";
   htmlTable += "&nbsp;";
   htmlTable += this.getMonthLiteral(mm) + " " + yy
   htmlTable += "&nbsp;<a href='javascript:" + this.name + ".hide()" + "'>[X]</a>";
   htmlTable += "</TD></TR>";
   
   // Ligne de titre des jours
   htmlTable += "<TR>";
   htmlTable += this.getDayShortTitle(mess_day_1);
   htmlTable += this.getDayShortTitle(mess_day_2);
   htmlTable += this.getDayShortTitle(mess_day_3);
   htmlTable += this.getDayShortTitle(mess_day_4);
   htmlTable += this.getDayShortTitle(mess_day_5);
   htmlTable += this.getDayShortTitle(mess_day_6);
   htmlTable += this.getDayShortTitle(mess_day_7);
   htmlTable += "</TR>";
   
   // Date du jour
   var today = new Date();
   var curYY = today.getCurrentYear();
   var curMM = today.getCurrentMonth();
   var curDD = today.getDate();
   // Date sélectionnée
   var selYY = this.curDate.getCurrentYear();
   var selMM = this.curDate.getCurrentMonth();
   var selDD = this.curDate.getDate();
   
   // Décale jusqu'au premier jour du mois
   htmlTable += "<TR>";
   var tdClass = "<TD class='calendarDayCell'>"
   var tdClassSelected = "<TD class='calendarDayCellSelected'>"
   for (var i=0;i<start_day;i++)
   { 
      htmlTable += tdClass + "&nbsp;</TD>";
   }
   for (var i=start_day;i<=6;i++)
   {
      var isCurDay = (curDD==day && curMM==mm && curYY==yy);
      var isSelectedDay = (selDD==day && selMM==mm && selYY==yy);
      htmlTable += (isSelectedDay ? tdClassSelected : tdClass ) +
         this.getDayHref(day,mm,yy, isCurDay, isSelectedDay) + "</TD>";
      day++;
   }
   htmlTable +="</TR>";
   
   while (day <= month_length)
   {
      htmlTable +="<TR>";
      for (var i=1;i<=7;i++)
      {  
         var isCurDay = (curDD==day && curMM==mm && curYY==yy);
         var isSelectedDay = (selDD==day && selMM==mm && selYY==yy);
         htmlTable += (isSelectedDay ? tdClassSelected : tdClass ) +
            this.getDayHref(day,mm,yy, isCurDay, isSelectedDay) + "</TD>";
         if ( day<month_length )
            day++
         else
            day = "&nbsp;";
      }
      htmlTable +="</TR>";
   }
   htmlTable +="</TABLE>";
   return htmlTable;
}

var CalendarWidget_monthName = new Array( mess_month_1, mess_month_2, mess_month_3, mess_month_4,
                              mess_month_5, mess_month_6, mess_month_7, mess_month_8,
                              mess_month_9, mess_month_10, mess_month_11, mess_month_12);

// Retourne le nom en clair du mois
CalendarWidget.prototype.getMonthLiteral = function(monthNumber)
{ 
   var monthIndex = eval(monthNumber) - 1;
   return CalendarWidget_monthName[monthIndex];
}

// Retourne le nombre de jours dans un mois précis
CalendarWidget.prototype.getDaysInMonth = function(month,year)
{
   var days;
   if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) 
      days=31;
   else if(month==4 || month==6 || month==9 || month==11)
      days=30;
   else if(month==2) 
   {
      if (this.isLeapYear(year)) 
         days=29;
      else
         days=28;
   }
   return days;
}

// Renvoie true si une année est bissextile(28 ou 29 jours en fevrier)
CalendarWidget.prototype.isLeapYear = function(yy)
{ 
   if (((yy % 4)==0) && ((yy % 100)!=0) || ((yy % 400)==0)) 
       return true;
   return false;
}

