// Fonctions de contrôle pour la saisie sur formulaire
// Nécessite form.js

////////////////////////////////////////////////////////////////////////////////
// Objet date
date.prototype.display = function () 
{
   if ( this.dval != null )
   {

      var year = this.dval.getFullYear();
      //if ( year < 2000) 
        //year = year + 1900;
    
      var day = this.dval.getDate();
      if ( day <10)
        day = "0"+day;
      var month = this.dval.getMonth()+1;
      if (month <10)
        month = "0"+month;
      this.ddisp.value=day + "/" + month + "/" + year; 
   }
   else
   {
      this.ddisp.value = "";
   }   
}
//
date.prototype.getISO = function () 
{
   if (this.dval != null) 
   {
      var year = this.dval.getYear();
      if ( year < 2000)
         year = year + 1900;
      var day = this.dval.getDate();
      if ( day <10)
         day = "0"+day;
      var month = this.dval.getMonth()+1;
      if (month <10)
         month = "0"+month;
      return year + "" + month + "" + day;
   }
   else
   {
      return "";
   }     
}
//
date.prototype.clear = function ()
{ 
  this.ddisp.value = "";
}
date.prototype.setDate = function (realDateISO)
{
   var annee = realDateISO.substring(0,4);
   var mois = realDateISO.substring(4,6);
   var jour = realDateISO.substring(6,8);
   if (jour && annee && mois)
   {
       var dateJJMMAAAA = jour+"/"+mois+"/"+annee;
       this.ddisp.value = dateJJMMAAAA;
   }
   else
   {
       this.ddisp.value = "";
   }
}
//
date.prototype.refresh = function (mess) 
{
   var val=0;
   var ok = 0;
   var flag = 0;
   
   if ( (this.ddisp.value == "") && (! this.required) )
   {
      // SAU 07.10.2005 : Prise en compte de la suppression 
      // du contenu de la zone de saisie.
      this.dval = null;
      return true;
   }
   var dateObj = DateUtil_guessDate(this.ddisp.value.trim());
   if ( ! dateObj )
   {
      if (mess) { alert (mess_control_date); }
      this.ddisp.focus(); 
      return false;
   }
   this.dval = dateObj;
   this.display(); 
return true; 
}
//
date.prototype.copy = function (dateSrc) 
{
    this.dval.setTime(dateSrc.dval.getTime());
    this.display(); 
}

date.prototype.getdiff = function (dateMax) 
{
   return (dateMax.dval.getTime()-this.dval.getTime())/86400000;
}

date.prototype.addDays = function(nbdays) 
{
  if (!this.refresh(true)) return;
  this.dval.setTime(this.dval.getTime()+nbdays*86400000);
  this.display();
}

date.prototype.addYears = function(nbdays) 
{
  if (!this.refresh(true)) return;
  this.dval.setTime(this.dval.getTime()+nbdays*86400000*(365.25));
  this.display();
}

date.prototype.setToday = function ()
{
  this.dval = new Date();
  this.display();
}
date.prototype.setTime = function(time)
{
  this.dval.setTime(time); 
}

date.prototype.getTime = function()
{
  return this.dval.getTime(); 
}

date.prototype.setFocus = function()
{
   if ( this.ddisp != null )
      this.ddisp.focus();
}

function date (disp, required)
{
 this.dval=null;
 if (disp!=null) 
 {
    if (disp.value != "") {  this.dval=new Date(disp.value); }
 }
 // 23.08.2005 : SAU si pas de valeur saisie dans le champ
 // On ne prend pas en compte la date courante par défaut
 //if (this.dval==null)
 //  this.dval=new Date();
 this.ddisp=disp;
 this.required = (required == null) ? false : ((required==1)?true:false);
 return this;
}
////////////////////////////////////////////////////////////////////////////////
// Objet Field
// path est un chemin de type frameName.formName.fieldName
// tdn 28/06/2006 Si à ce chemin correspond plusieurs nom de champ un message
// d'erreur est affiché. On peut passer path=frameName et inputId= id de l'élément
// input HTML/
function Field(path, inputId)
{
   this.path = path;
   var parts = path.split(".");
   if ( parts.length != 3 && inputId == null)
   {
      alert("Bad use of Field object : path=" + path + " inputId=" + inputId + "\n" +
      	"Path must be 'frameName.formName.fieldName', or path='frameName' and inputId is not null");
      return null;
   }
   this.frameName = parts[0];
   this.formName  = parts[1];
   this.elemName  = parts[2];
   
   var frame = findFrameWithinApp(this.frameName);
   if ( frame )
   {
      // L'id est spécifié, on le recherche en priorité
      if ( inputId != null )
      {
         var elem = frame.document.getElementById(inputId);
         if ( elem != null )
         {
            this.frame = frame;
            this.form  = elem.form;
            this.element = elem;
         }
         else
         {
            alert(mess_field_not_found + this.elemName + " id=" + inputId);
         }
         return;
      }
      var form = frame.document.forms[this.formName];
      if ( form )
      {
         for (var i=0; i<form.elements.length; i++)
         {
         	var elem = form.elements[i];
         	if ( elem.name == this.elemName )
         	{
         	   if ( this.element )
         	   {
         	      alert("There are several input elements with name " + this.elemName);
         	      return;
         	   }
               this.frame = frame;
               this.form  = form;
               this.element = elem;
         	}
         }//for
         if ( this.element )
         { 
            return;
         }
         else
         {
            alert(mess_field_not_found + this.elemName);
         }
      }
      else
      {
         alert(mess_form_not_found + this.frameName + "." + this.formName);
      }
   }
   else
   {
      alert(mess_frame_not_found + this.frameName);
   }
}
// Renvoie le nom de la frame
Field.prototype.getFrameName = function ()
{
   return this.frameName;
}
// Renvoie la frame
Field.prototype.getFrame = function ()
{
   return this.frame;
}
// Renvoie le nom du formulaire
Field.prototype.getFormName = function ()
{
   return this.formName;
}
// Renvoie le nom de l'élément
Field.prototype.getElementName = function ()
{
   return this.elemName;
}

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

// Selectionne toutes les valeurs sauf emptyValue (vaut "0" par défaut)
function inputSelectAllOptions(formName, listeName, emptyValue)
{
   var liste = frmCheckField(formName, listeName);
   if ( liste && liste.options )
   {
      if ( emptyValue == null ) emptyValue = "0";
      for (i=0; i<liste.options.length; i++)
      {
         if (liste.options[i].value != emptyValue)
         {
            liste.options[i].selected = true;
         }
      }
   }
}

// Supprime un élément d'un tableau
function deleteElement(array, delindex)
{
   var size = array.length;
   var validNo = (delindex != "NaN");
   var inRange = ( (delindex >= 0) && (delindex < size) );

   if (validNo && inRange)
   {
      if(array.remove)
      {
         // méthode propre à IE
         array.remove(delindex);
      }
      else
      {
         // pour les autres navigateurs
         for(var j = delindex; j < size-1; j++)
         {      
            array[j] = array[j+1];
         }
         array.length = size-1;
      }
   }
}

// Supprime un élément d'un tableau d'options
// On ne pas utiliser deleteElement qui ne fonctionne pas
// correctement sous Mozilla
function deleteListOption(array, delindex)
{
   var size = array.length;
   var validNo = (delindex != "NaN");
   var inRange = ( (delindex >= 0) && (delindex < size) );

   if (validNo && inRange)
   {
      if(array.remove)
      {
         // méthode propre à IE
         array.remove(delindex);
      }
      else
      {
         // pour les autres navigateurs
         for(var j = delindex; j < size-1; j++)
         {      
            array[j].value = array[j+1].value;
            array[j].text  = array[j+1].text;
         }
         array.length = size-1;
      }
   }
}

// Permet de supprimer des éléments contenus dans une liste
// tdn 29/06/2006 : le recherche par son id si spécifie, sinon par le nom
function inputRemoveSelectedOptions(formName, fieldName, fieldId)
{
   var elt = frmCheckField( formName, fieldName, fieldId)
   if ( elt && elt.options )
   {
      listRemoveSelectedOptions(elt);
   }
}
function listRemoveSelectedOptions(elt)
{    
   var len    = elt.options.length;
   for (var i=len-1; i >= 0; i--)
   {
      if (elt.options[i].selected)
      {
         deleteListOption(elt.options, i);
      }
   }
}

// Supprime toutes les options d'une liste
function listRemoveAllOptions(elt)
{
   listRemoveAllOptionFrom(elt,0); 
}

/**
 * Supprime toutes les options d'un select ayant un index >= fromIndex
 * @param {Select} elt select contenant les options
 * @param {int} fromIndex Index de la première option supprimée
 */
function listRemoveAllOptionFrom(elt,fromIndex)
{
   for (var i=elt.options.length; i >=fromIndex; i--)
   {
      deleteElement(elt.options, i);
   } 
}


// Vide un champ lié monovalué
function inputEmptyLinkField(formName, fieldName)
{
   var elt = frmCheckField( formName, fieldName)
   if ( elt )
      elt.value = "";
   elt = frmCheckField( formName, fieldName + "_EVERDISP")
   if ( elt )
      elt.value = "";
}

//
//
function isANumber (str)
{
   if ( str == "" ) return true;
   var num = parseFloat(str);
   return  ! isNaN(num);
/*   
   for (var i=0; i<str.length; i++){
       var n = parseInt(str.charAt(i));
       if (isNaN(n)) { return false; }
 }
return true;
*/
}
function toNumber(str)
{  
   // sau 30.03.2007 : parseFloat prend uniquement la partie entière 
   // si le séparateur est la virgule !!
   if (    str != null
       &&  str != undefined
       &&  str.length > 0 ) 
      str = str.replace(/\,/, '.');
   
   var num = parseFloat(str);
   if (isNaN(num)) return 0;
   return num;
}


// Contrôle le nombre de sélection max dans une liste
function inputControlListMultiple(frmName, field_name, no_msg, field_label, multi_maxi)
{
   var fld_msg = field_name;
   if ( field_label != '' )
   {
     fld_msg = field_label;
   }
   var elt = frmCheckField(frmName, field_name);
   if ( elt && elt.options )
   {
      var nb_selected = 0;
      for (var j=0; j< elt.options.length; j++)
      {
         if (elt.options[j].selected ) { nb_selected ++; }
      }
      if ( nb_selected > multi_maxi )
      {
         if ( ! no_msg) 
         { 
            alert(mess_control_liste_multi + " " + fld_msg + "\n" + mess_control_liste_multi2 + " " + multi_maxi);
            elt.focus();
         }
         return false;
      }
      return true;
   }
   return false;
}

//
function inputControlDecimal(formName, fieldName, fieldLabel, precision)
{
   var isDecimal = false;
   var value = "";
   var field;
   var formulaire = document.forms[formName];

   if ( ! formulaire )
   {
      alert(mess_form_not_found + formName);
      return false;
   }
   
   // Récupération de la valeur saisie
   for (var i=0;i<formulaire.elements.length;i++)
   {
      var elt = formulaire.elements[i];
      var elt_type = elt.type;
      if (elt.name == fieldName)
      {
         field = elt;
         if ( (elt_type == 'text') || (elt_type == 'hidden') )
         {
            value = elt.value;
            break;
         }
      }
   }
   var showErrorMessage = true;
   isDecimal = inputCtrlDecimal(value, showErrorMessage, fieldLabel);
   
   if ( isDecimal )
   {
      // Application de l'arrondi à precision décimales   
      field.value = getDataCtrlDecimal(value, precision)
   }   
   else   
   {
      // Le nbre saisi n'est pas un décimal
      // On positionne le focus dans la zone de saisie
      field.focus();
      return false;
   }
   return true;  
}

function inputControlDateFormat15(formName, field_name, mess)
{
   var value = "";
   var field;
   var formulaire = document.forms[formName];

   if ( ! formulaire )
   {
      alert(mess_form_not_found + formName);
      return false;
   }
   
   for (var i=0;i<formulaire.elements.length;i++)
   {
      var elt = formulaire.elements[i];
      var elt_type = elt.type;
      if (elt.name == field_name)
      {
         field = elt;
         if ( (elt_type == 'text') || (elt_type == 'hidden') )
         {
            value = elt.value;
            break;
         }
         else if ( (elt_type == 'checkbox') || (elt_type == 'radio') )
         {
            value = elt.value;
         }
         else if ( (elt_type == 'select-one') || (elt_type == 'select-multiple') )
         {
            for (var j=0; j< elt.options.length; j++)
            {
               if (elt.options[j].selected)
               {
                  value = elt.options[j].value;
               }
            }
         }
      }
   }
   if ( ! isANumber(value) )
   {
      alert(mess_control_integer);
      field.focus();
      return false;
   }
   if (value.length != 4)
   {
      alert(mess_control_date_format_15);
      field.focus();
      return false;  
   }
   return true;
}


//
function inputControlInteger(formName, field_name, mess)
{
   var value = "";
   var field;
   var formulaire = document.forms[formName];

   if ( ! formulaire )
   {
      alert(mess_form_not_found + formName);
      return false;
   }
   
   for (var i=0;i<formulaire.elements.length;i++)
   {
      var elt = formulaire.elements[i];
      var elt_type = elt.type;
      if (elt.name == field_name)
      {
         field = elt;
         if ( (elt_type == 'text') || (elt_type == 'hidden') )
         {
            value = elt.value;
            break;
         }
         else if ( (elt_type == 'checkbox') || (elt_type == 'radio') )
         {
            value = elt.value;
         }
         else if ( (elt_type == 'select-one') || (elt_type == 'select-multiple') )
         {
            for (var j=0; j< elt.options.length; j++)
            {
               if (elt.options[j].selected)
               {
                  value = elt.options[j].value;
               }
            }
         }
      }
   }
   if ( ! isANumber(value) )
   {
      alert(mess_control_integer);
      field.focus();
      return false;
   }
   return true;
}

//
function inputControlLenMin(formName, fieldName, len, fieldId)
{
   var elt = frmCheckField(formName, fieldName, fieldId);
   if ( elt )
   {
      if ( elt.value == "") return true;
      if ( elt.value.length >= len ) return true;
      var f0 = mess_control_lenmin;
      alert(f0 + " [" + len + "]");
      elt.focus();
   }
   return false;
}

//
function inputControlValMax(formName, fieldName, val)
{
   var elt = frmCheckField(formName, fieldName);
   if ( elt )
   {
      if (elt.value <= val )
         return true;
      var f0 = mess_control_valmax;
      alert(f0 + " [" + val + "]");
      elt.focus();
   }
   return false;
}

//
function inputControlValMin(formName, fieldName, val)
{
   var elt = frmCheckField(formName, fieldName);
   if ( elt )
   {
      if (elt.value >= val )
         return true;
      var f0 = mess_control_valmin;
      alert(f0 + " [" + val + "]");
      elt.focus();
   }
   return false;
}

//
function inputControlMajus(formName, fieldName)
{
   var elt = frmCheckField(formName, fieldName);
   if ( elt )
   {
      elt.value = elt.value.toUpperCase();
   }
}

//
function inputControlMinus(formName, fieldName)
{
   var elt = frmCheckField(formName, fieldName);
   if ( elt )
   {
      elt.value = elt.value.toLowerCase();
   }
}

/**
 * @author pru: ajoute le champ timeField si le champ time et requis
 * il est simplement concaténé a la date
 */
function inputSetDateISO(frmName, dateObj, fieldName,timeFieldId)
{
   var dateField = frmCheckField(frmName, fieldName);
   
   
   var timeValue = null;
   if(timeFieldId!=null)
   {
      var fieldTime = document.getElementById(timeFieldId);
      if(fieldTime!=null)
         timeValue= fieldTime.value;
   }
   
   if ( dateField )
   {
      dateField.value = dateObj.getISO();
      if(timeValue!=null)
         dateField.value+=timeValue;
   }
}

// Ouvre la fenêtre assistant de saisie
// tableName peut être au format source.nomTable
// ** tdn 04/11/2005 fieldFrom est au format : sourceOrig:tableOrig:fieldOrig pour appliquer
// sql_command
// ** sau 10/01/2006 : ajout de la variable filter pour appliquerle contrôle 
// sql_command du type sql_command=NOM_CHAMP_NOTICE_AUTORITE=$NOM_CHAMP_FORMULAIRE$
// avec $NOM_CHAMP_FORMULAIRE$ est remplacé par la valeur du champ NOM_CHAMP_FORMULAIRE,
// présent dans le formulaire
// ** sau 02.06.2006 : ajout de l'attribut isLink qui permet s'il est positionné à 'true'
// de renseigner le champ lié par le recordId de la notice liée
// ** sau 20.07.2006 : ajout de l'attribut onunloadLinkAssist qui permet de passer la fonction
// javascript a exécuter sur le onunload de l'assistant de saisie
function inputCallLinkAssist(formName, action, tableName, dest, multimax, fieldFrom, filter, isLink, onunloadLinkAssist)
{
   // Ajoute automatiquement le paramètre source si nécessaire
   var sourceName = null; 
   var parts = tableName.split(".");
   if ( parts.length == 2 )
   {
      sourceName = parts[0];
      tableName = parts[1];
   }
   var frame = this.name;
   var cgi = action;
   //Verifie si il n'existe pas deja des parametres.
   if( action.indexOf("?") == -1 )
   {
      cgi += "?";
   }
   else if( action.indexOf("&")!= (action.lenght-1) )
   {
         cgi += "&";
   }
   
   if ( sourceName != null )
      cgi += "source=" + myEscape(sourceName) + "&";
      
   cgi += "tableName=" + myEscape(tableName)
       + "&targetInput=" + myEscape( frame + "." + formName + "." + dest)
       + "&fieldFrom=" + myEscape(fieldFrom)
       + "&isLink=" + myEscape(isLink)
       + "&onunloadLinkAssist=" + myEscape(onunloadLinkAssist);
   
   // Si pas de filtre, on interroge par a%
   if ( filter.length == 0 )    
   {
      cgi += "&criteria=" + myEscape("a");
      cgi += "&filter=";
   }   
   else  // Présence d'un filtre sql
   {
      // sql_command=nom_champ=$NOM_CHP_1$ AND ...
      // ==> Parties impaires == NOM_CHP_N
      var filterParts = filter.split("$");
      var filter = "";
      for ( var i=0; i < filterParts.length; i++ )
      {
         filter += filterParts[i];         
         i++;
         if ( i < filterParts.length )
         {
            var fieldName = filterParts[i];
            fieldName = StringUtil_trim(fieldName);
            var field = frmCheckField(formName, fieldName);            
            filter += field.value;
         }   
         
      }
      cgi += "&criteria=";
      cgi += "&filter=" + myEscape(filter);       
   }
      
   if ( multimax > 1 )
      cgi += "&multimax=" + myEscape(multimax);
   var h        = 450;
   var w        = 350;
   var top_pos  = 400;
   var left_pos = 400;

   // Ouvre la fenêtre   
   var winName = "win_inputlink" + sysGetAppName();
   sysOpenWindow(winName, cgi);
}

//Ouvre une nouvelle fenêtre pour exécuter l'action en paramètre
//formNane est le formulaire où se trouve le champ dest
//requête à executer
function openWindowForAction(formName, action, dest,requete)
{
   // Ajoute automatiquement le paramètre source si nécessaire
   var frame = this.name;
   var cgi = action;
   //Verifie si il n'existe pas deja des parametres.
   if( action.indexOf("?") == -1 )
   {
      cgi += "?";
   }
   else if( action.indexOf("&")!= (action.lenght-1) )
   {
         cgi += "&";
   }
      
   cgi += "targetInput=" + myEscape( frame + "." + formName + "." + dest);
   cgi += "&queryName="+requete;
   var h        = 450;
   var w        = 350;
   var top_pos  = 400;
   var left_pos = 400;

   // Ouvre la fenêtre   
   var winName = "win_inputlink" + sysGetAppName();
   sysOpenWindow(winName, cgi);
}

// formName : nom du formulaire d'origine
// field_name : nom de la liste du formulaire d'origine contenant les valeurs à
//              rapatrier
// destFieldPath : chemin nom du champ destination
// ** sau 02.06.2006 : ajout de l'attribut isLink qui permet s'il est positionné 
// à 'true' de renseigner le champ lié par le recordId de la notice liée
function frmRetrieveLinks(formName, action, p0, fieldName, p1, destFieldPath,
   p2, multimax, p3, linkSource, p4, linkTableName, p5, isLink)
{
   var field = new Field(destFieldPath);

   // Normalise le nom de champ
   if ( fieldName.indexOf(".") == 0 )
      fieldName = fieldName.substring(1);
   
   if ( ! field )
      return;

   // Valeur sélectionnée dans la liste
   var list = frmCheckField(formName, fieldName);
   if ( ! ( list && list.options) )
   {
      alert(mess_wrong_field_type + " liste : " + formName + "." + fieldName);
      return;
   }
      
   var end_single_selection = false;
   var input_type = field.element.type;
   var hasSelections = false;
      
   // On ajoute toutes les valeurs sélectionnées dans la liste
   for (var j=0; (j< list.options.length) && (!end_single_selection); j++)
   {
      if (list.options[j].selected)
      {
         hasSelections = true;
         var realVal = list.options[j].value;
         var dispVal = list.options[j].text;
         
         // Contruction du recordId de la notice liée
         var recId = new RecordId(realVal);
         if ( ! recId.isValid() )
         {
	         recId.setSource(linkSource);
	         recId.setTable(linkTableName);
	         recId.setInternalId(realVal);
	      }   
         
         // Présence du ctrl link ou link=NOM_TABLE;
         // Valeur réelle == recordId
         if ( isLink == "true" )
         {
            realVal = recId.getRecordId();
         }   
         
         // pour un champ simple
         if ( (input_type == 'hidden') || (input_type == 'text') )
         {
            field.element.value = realVal;
             
            var input_disp = field.element.name + "_EVERDISP";
            if ( field.form.elements[input_disp] )
               field.form.elements[input_disp].value = dispVal;
            end_single_selection = true;
            
            // Heritage des données
            var key = field.getFormName() + "." + field.getElementName();
            var LinkedFieldArray = field.getFrame().LinkedFields;
            var linkedData=null;
            if(LinkedFieldArray!=null)
                linkedData= field.getFrame().LinkedFields[key];
            // Il y des champs qui héritent de données de la notice d'autorité 
            if ( linkedData != null )
            {
               // Recherche de l'enregistrement lié
               var xmlDoc = XMLUtil_LoadRecord(recId.getRecordId());
               
               // Héritage des données
               if ( xmlDoc != null)
               {
                  //var debug = XMLUtil_serialize(xmlDoc.documentElement);
                  //appendDebug(debug);

                  for (var fName in linkedData)
                  {
                     // Vérification de la présence du champ dans le formulaire de saisie
                     var fieldPath = field.getFrameName();
                     fieldPath    += ".";
                     fieldPath    += field.getFormName();
                     fieldPath    += ".";
                     fieldPath    += fName;
                     
                     var fieldLinkedData = new Field(fieldPath); 
                     if ( fieldLinkedData != null )
                     {
                        var fieldAutorityName = linkedData[fName];
                        fieldLinkedData.element.value = getRecordFieldValue(xmlDoc, fieldAutorityName);
                        // appendDebug(fieldPath + " " + getRecordFieldValue(xmlDoc, fieldAutorityName));                     
                        
                        // sau 05.05.2007 : Tente de positionner le focus sur l'élément
                        setFocus(fieldLinkedData.element);
                     }
                  }
               }
            }
         }
         // pour un champ multivalué
         else if ((input_type=='select-one') || (input_type=='select-multiple'))
         {
            // vérifie que la liste de destination ne contient pas déjà la valeur
            var already_exists = false;
            for( var k=0; (k<field.element.options.length) && (!already_exists) ; k++ )
            {
               already_exists = ( field.element.options[k].value == realVal );
            }
            if ( ! already_exists )
            {
               if ( field.element.options.length <= multimax)
               {
                  field.frame.listAppendOption(field.element, realVal, dispVal);
               }
               else
               {
                  alert( mess_control_liste_multi2 + " " + multimax);
                  return;
               }
            }
         }
      }
   }
   if ( ! hasSelections )
   {
      alert(mess_select_first);
      return;
   }
   // Ferme automatiquement si sélection réussie pour champ lié simple
   if ( ! isANumber( multimax) ||  ( multimax <= 1 ) )
   {
      window.close();
   }
}

// Renvoie la valeur réelle d'un champ de l'enregistrement 
// passé en paramètre
// Si champ présent plusieurs fois dans la notice on retourne 
//   la valeur du premier.
// Si champ non trouvé renvoie une chaîne vide
function getRecordFieldValue(recordDoc, fieldName)
{
   var ret = "";
   
   if (     recordDoc != null  
        &&  fieldName != null 
        &&  fieldName.length > 0 )
   {     
      // Si le nom réel du champ commence par un chiffre, on ajoute _
      if ( !isNaN(fieldName.charAt(0)) )
         fieldName = "_" + fieldName;
      
      var elements = recordDoc.getElementsByTagName(fieldName);
      if ( elements && (elements.length >= 1 ) )
      {
         var nodeText = XMLUtil_getElementText(elements[0]);
         if ( nodeText != null )
            ret = nodeText.nodeValue;
      }
      //else
      //   alert("Champ non trouvé dans le record courant :" +fieldame);
   }
   return ret;
}

// Privé
// Teste l'existence d'une valeur dans une liste déroulante 
function listIsOptionDefined(list, value)
{
   for(var i=0 ; i < list.options.length ; i++)
   {
      if(list.options[i].value == value){return true;}
   }
   return false;
}

// Privé
// Ajout d'une OPTION dans un élément SELECT si cette valeur n'est pas déjà définie.
// Cette fonction doit être appelée dans la frame où se situe le SELECT
// (sinon problème dans IE)
// - emptyValue = code de l'élément bidon à enlever, vaut "0" par défaut
// Renvoie l'Option ajouté ou null si aucun
function listAppendOption( list, val, disp, emptyValue,title)
{
   var len = list.options.length;

   if(! listIsOptionDefined(list, val))
   {
      // Ecrase l'option bidon si elle existe
      if( (len == 1) )
      {
         if ( emptyValue == null ) emptyValue = "0";
         if ( list.options[0].value == emptyValue)
         {
            list.options[0].value = val;
            list.options[0].text = disp;
            list.options[0].title = title;
            return list.options[0];
         }
      }
      // Nouvelle valeur
      var newOption = new Option(disp, val);
      newOption.title=title;
      list.options[len] = newOption;
      return newOption;
   }
   return null;
}
// Sélectionne toutes les valeurs sauf emptyValue (vaut "0" par défaut)
function listSelectAll(liste, emptyValue)
{
   if ( liste && liste.options )
   {
      if ( emptyValue == null ) emptyValue = "0";
      for (i=0; i<liste.options.length; i++)
      {
         if (liste.options[i].value != emptyValue)
         {
            liste.options[i].selected = true;
         }
      }
   }
}

//Mise à jour du schemaData à partir des elements de la liste
//frameName, nom de la frame appelante
//fieldName, nom du champ dans le schemaData
//fieldId, Id du champ dans le schemaData
function thesaurusListToSchemaData(frameName, fieldName, fieldId)
{
   //Récupération des éléments de la liste
   var frame = findFrameWithinApp(frameName);
   // tdn 29/06/2006 l'élément input est trouvé par son id unique
   var fieldList = new Field(frameName, fieldId + "_input");
   
   var inputValue = "";
   var inputDisplay = "";
   
   for (var j=0; j< fieldList.element.options.length; j++)
   {
      if (j == 0)
      {
         inputValue = fieldList.element.options[j].value;
         inputDisplay = fieldList.element.options[j].innerHTML;
      }
      else
      {
         inputValue = inputValue + MULTIPLE_VALUE_SEP + fieldList.element.options[j].value;
         inputDisplay = inputDisplay + MULTIPLE_VALUE_SEP + fieldList.element.options[j].innerHTML;
      }         
   }       
   
   //Mise à jour du schemaData
   var schemData = frame.INPUT_VIEW.schemaData;             
   var fieldData = schemData.getFieldByNameAndId(fieldName, fieldId); 
   
   // Mise à jour du schéma de données
   if (fieldData)
   {
      schemData.setFieldValue(fieldData, inputValue);
      schemData.setFieldDisplayValue(fieldData, inputDisplay);
      
   }                  
}

//Fonction qui recherche les NOMCHAMP_THESAURUS_LIST d'un document.
//Pour chaque élément correspondant :
//Positionne le champ NOMCHAMP avec les valeurs réélles de la liste séparées par un \n
function thesaurusListsToHidden(formName)
{
   var formElements = document.forms[formName].elements;
   for (var i=0; i< formElements.length; i++)
   {
      var fieldName = formElements[i].name;
      var parts = fieldName.split("_THESAURUS_LIST");
      if ( parts.length == 2 )
      {
         var hiddenFieldName = parts[0];
         var vhiddenFieldName = document.getElementById(hiddenFieldName);
         if (vhiddenFieldName)
         {
            var field = new Field("win_data." + formName + "." + fieldName);
            for( var k=0; k<field.element.options.length ; k++ )
            {
               if (k == 0)
                  vhiddenFieldName.value = field.element.options[k].value;
               else
                  vhiddenFieldName.value = vhiddenFieldName.value + "\n" + field.element.options[k].value;
            }
         }
         else
         {
            alert(hiddenFieldName+" introuvable !");         
            return(false);
         }
      }      
   }
   return(true);
}

// Pour un champ lié, d'un formulaire donnée, cette fonction contient 
// une liste de correspondances entre les champs de la notice courante 
// et le contenu du champ de la notice d'autorité à hériter
function addToLinkedField(formName, fieldName, linkFieldName, fieldAutorityName)
{
   var key = formName + "." + linkFieldName;
   var linkedData = LinkedFields[key];
   if ( linkedData == null )
   {
      linkedData = new Array();
      linkedData[fieldName] = fieldAutorityName;
      LinkedFields[key] = linkedData;
   }   
   else
      linkedData[fieldName] = fieldAutorityName;   
}

/**********************
 * Etend la classe primitive Date 
 *********************/
// Renvoie aaaammjj
Date.prototype.getISO = function () 
{
  var year = this.getCurrentYear();
  var month = this.getCurrentMonth();
  var day = this.getDate();
  if ( day < 10 )
     day = "0"+day;
  if (month < 10 )
     month = "0"+month;
  return year + "" + month + "" + day;
}
 
 // Renvoie l'année en cours
Date.prototype.getCurrentYear = function()
{
   return this.getFullYear();
}
// Renvoie l'année suivante
Date.prototype.getNextYear = function() 
{
   return this.getFullYear() + 1;
}
// Renvoie l'année précédente
Date.prototype.getPreviousYear = function() 
{
   return this.getFullYear()- 1;
}
// Renvoie le numéro du mois en cours
Date.prototype.getCurrentMonth = function()
{
   return this.getMonth() + 1;
}
// Renvoie le numéro du mois suivant
Date.prototype.getNextMonth = function()
{
   if (this.getMonth() < 11) 
      this.setMonth(this.getMonth() + 1);
   else 
   {
      this.setMonth(0);
      this.setFullYear(this.getFullYear() + 1);
   }
    return this.getMonth() + 1;
}
// Renvoie le numéro du mois précedent
Date.prototype.getPreviousMonth = function()
{
   if (this.getMonth()) this.setMonth(this.getMonth() - 1);
   else {
       this.setMonth(11);
       this.setFullYear(this.getFullYear() - 1);
   }
   return this.getMonth() + 1;
}
// Ajoute un nombre de jour, 1 par défaut
Date.prototype.addDays = function(increment)
{
   if ( ! increment) increment = 1;
   this.setDate(this.getDate() + increment);
   return this.getDate();
}
// Ajoute un nombre de mois, 1 par défaut
Date.prototype.addMonth = function(increment)
{
   if ( ! increment) increment = 1;
   for(var i = 1; i<= increment; i++)
      this.getNextMonth();
   return this.getCurrentMonth();
}
// Ajoute un nombre d'année, 1 par défaut
Date.prototype.addYear = function(increment)
{
   if ( ! increment) increment = 1;
   for(var i = 1; i<= increment; i++)
      this.getNextYear();
   return this.getCurrentYear();
}

// Ajoute soit un nombre de jour, un nombre de mois et un nombre d'années
Date.prototype.add = function(nb_years, nb_month, nb_days)
{ 
   this.addYear(nb_years);
   this.addMonth(nb_month);
   this.addDays(nb_days);
}
// Compare 2 dates
Date.prototype.equalsTo = function(d)
{ 
   if ((this.getDay() == d.getDay()) && (this.getMonth() == d.getMonth()) 
        && (this.getFullYear() == d.getFullYear()))
      return true;
   else 
      return false;  
}

// Définie isArray car sous IE sysInstanceOf ne marche pas
/* Provoque dysfonctionnement si on parcourt un tableau avec for .. in !
Array.prototype.isArray = function()
{
   return true;
}
*/

// Renvoie le format visible d'une date
// - dateVal : aux formats de DateUtil_guessDate
// Par défaut, renvoie jj/mm/aaaa
// tdn 07/07/2005
function DateUtil_getVisibleFormat(dateVal)
{
   var ret = "";
   var dateObj = DateUtil_guessDate(dateVal);
   if (dateObj)
   {
      var yy = dateObj.getCurrentYear();
      var mm = dateObj.getCurrentMonth();
      if ( mm < 10 ) mm = "0" + mm;
      var dd = dateObj.getDate();
      if ( dd < 10 ) dd = "0" + dd
      ret = dd + "/" + mm + "/" + yy;
   }
   return ret;
}
// Renvoie le format ISO aaaammjj d'une date
// - dateVal : aux formats de DateUtil_guessDate
// tdn 07/07/2005
function DateUtil_getISOFormat(dateVal)
{
   var ret = "";
   var dateObj = DateUtil_guessDate(dateVal);
   if (dateObj)
   {
      var yy = dateObj.getCurrentYear();
      var mm = dateObj.getCurrentMonth();
      if ( mm < 10 ) mm = "0" + mm;
      var dd = dateObj.getDate();
      if ( dd < 10 ) dd = "0" + dd
      ret = yy + "" + mm + "" + dd;
   }
   return ret;
}

// Renvoie un Date() à partir de l'objet spécifié, null si dateVal est null ou invalide
// - dateVal : peut être une Date(), une chaîne ISO aaaammjj, ou une chaîne visible
//    un tableau contenant jj,mm,aaaa
function DateUtil_guessDate(dateVal)
{
   var dd,mm,yy;
   if ( ! dateVal ) return null;
   // Date()
   if ( sysInstanceOf(dateVal, Date) ) return dateVal;
   // Array()
   var isArray = false;
   try
   { 
      isArray = sysInstanceOf(dateVal, Array); // marche par avec IE
   } 
   catch(e)  { }
   if ( !isArray )
   {
      try
      {
         //isArray = dateVal.isArray();
         isArray = (dateVal.length == 3);
      }
      catch(e){}
   }
   if (isArray)
   {
      if (dateVal.length == 3)
      {
         dd = dateVal[0];
         mm = dateVal[1];
         yy = dateVal[2];
      }
   }
   else // chaîne simple ou nombre
   {
      dateVal = "" + dateVal;
      if ( dateVal.length == 8 ) // aaaammjj ?
      {
         yy = dateVal.substring(0,4);
         mm = dateVal.substring(4,6);
         dd = dateVal.substring(6,8);
      }
      else if ( dateVal.length == 10 ) // jj/mm/aaaa ?
      {
         var parts = dateVal.split("/");
         yy = parts[2];
         mm = parts[1];
         dd = parts[0];
      }
   }
   
   var ret = null;
   var ok = 0;
   if ( yy && mm && dd )
   {
      var val = parseInt(dd, 10); 
      if ( isANumber(dd) && 0<val && val<32 )
      {
         dd = val;
         ok ++;
      }
      val = parseInt(mm,10);
      if ( isANumber(mm) && 0<val && val<13 )
      {
         mm = val - 1;
         ok ++;
      }
      val = parseInt(yy,10);
      if ( isANumber(yy) && 0<val  )
      {
         yy = val;
         ok ++;
      }
   }
   if ( ok == 3 )
   {
      ret = new Date();
      ret.setYear(yy);
      ret.setMonth(mm);
      ret.setDate(dd);
   }
   return ret;
}

// Vérifie si la date specifiée est valide : 
//   renvoie true si la date est valide false sinon
// - dateVal : peut être une Date(), une chaîne ISO aaaammjj, ou une chaîne visible
//    un tableau contenant jj,mm,aaaa
function DateUtil_checkDate(dateVal)
{
   var dd,mm,yy;
   if ( ! dateVal )
   {
      return false;
   }
   // Date()
   if ( sysInstanceOf(dateVal, Date) ) 
   {
      dd=dateVal.getDate();
      mm=dateVal.getMonth() + 1;
      yy=dateVal.getFullYear();
   }
   // Array()
   var isArray = false;
   try 
   { 
      isArray = sysInstanceOf(dateVal, Array); // marche par avec IE
   } catch(e)  { }
   if ( !isArray ) 
   {
      try {
         //isArray = dateVal.isArray();
         isArray = (dateVal.length == 3);
      } catch(e){}
   }
   if (isArray) 
   {
      if (dateVal.length == 3) 
      {
         dd = dateVal[0];
         mm = dateVal[1];
         yy = dateVal[2];
      }
   } 
   else 
   { // chaîne simple ou nombre
      dateVal = "" + dateVal;
      if ( dateVal.length == 8 ) // aaaammjj ?
      {
         yy = dateVal.substring(0,4);
         mm = dateVal.substring(4,6);
         dd = dateVal.substring(6,8);
      } 
      else if ( dateVal.length == 10 ) // jj/mm/aaaa ?
      {
         var parts = dateVal.split("/");
         yy = parts[2];
         mm = parts[1];
         dd = parts[0];
      } 
      else 
      {
         return false;
      }
   }
   
   if(mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10 || mm == 12)
   {
      if(dd > 31)
      {
         return false;
      }
   } 
   else if(mm == 4 || mm == 6 || mm == 9 || mm == 11)
   {
      if(dd > 30)
      {
         return false;
      }
   } 
   else if(mm == 2) 
   {
      if (!isLeapYear(yy) && dd > 28)
      {
         return false;
      } 
      else if(isLeapYear(yy) && dd > 29)
      {
         return false;
      }        
   }
   return true;
}


// Teste si une année est bisextile
function isLeapYear(yearVal)
{ 
   if (((yearVal % 4)==0) && ((yearVal % 100)!=0) || ((yearVal % 400)==0))
   {
      return true;
   } 
   else
   {
      return false;
   }
}

/**
 * retourne un tableau contenant l'index de toutes les
 * options selectionnées
 * @param listElement: element dom de type select
 **/
function getAllSelectedIndex(listElement)
{
   var arrayOfIndex = new Array;
   var len    = listElement.options.length;
   for (var i=0; i<len; i++)
   {
      if (listElement.options[i].selected)
      {
         arrayOfIndex.push(i);
      }
   }
   return arrayOfIndex;
}

/**
 * Cette methode permet d'intervertir les options aux index index1 et index2
 * de la liste selectElement.
 * @param selectElement htmldom representant un select
 * @param index1, index d'une option de selectElement
 * @param index2, index d'une option de selectElement
 **/
function revertOptions(selectElement,index1, index2)
{
     var Option1 = selectElement.options[index1];
     var Option2 = selectElement.options[index2];
     selectElement.options[index1]=new Option("", "");
     selectElement.options[index2]=Option1;
     selectElement.options[index1]=Option2;
}

//Fonction générique permettant le déplacement des éléments sélectionnés de la liste source vers la liste cible
function moveListElement(listSource, listDest)
{     
   //Vérifier que un élément est sélectionné dans la liste source
   //Recherche de l'élément sélectionné dans la liste source (ou des éléments sélectionnés)
   //Recopie dans la liste cible de la ou des sélections.
   var selectedIndex = listSource.options.selectedIndex;
   if (selectedIndex >= 0)
   {
      var option = new Option(listSource.options[selectedIndex].text,listSource.options[selectedIndex].value);
      option.title=listSource.options[selectedIndex].title;
      var lenDest = listDest.options.length;
      listDest.options[lenDest] = option;
      listSource.options[selectedIndex]=null;
      selectedIndex = listSource.options.selectedIndex;
      while (selectedIndex >= 0)
      {
         option = new Option(listSource.options[selectedIndex].text,listSource.options[selectedIndex].value);
         option.title=listSource.options[selectedIndex].title;
         lenDest = listDest.options.length;
         listDest.options[lenDest] = option;
         listSource.options[selectedIndex]=null;
         selectedIndex = listSource.options.selectedIndex;    
      }
   } 
}

/**
 * Cette method monte ou descende un element option dans une list
 * @param formName null
 * @param action null
 * @param p0 null
 * @param listName nom de la liste
 * @param moveUp si true l'option monte
 * 
 */
function moveOption(formName, action, p0, listName,moveUp)
{
   var step;
   if(moveUp)
   {
      step=-1;
   } else
   {
      step=1;
   }
   var listElement = document.getElementById(listName);
   var options = listElement.options;
   
   var arrayOfSelectedIndex = getAllSelectedIndex(listElement);
   var lastIndex = arrayOfSelectedIndex.length-1;
   for(var i=0;i<arrayOfSelectedIndex.length;i++)
   {
      //moveUp et la ligne si dessous permettent de gérér proprement le déplacement
      //d'une multi-sélection avec des vides lorsque l'on atteind les extrémiter.
      var indexSelected = (moveUp)?arrayOfSelectedIndex[i]:arrayOfSelectedIndex[lastIndex-i];
      if(indexSelected==(listElement.length-1) && !moveUp)
      {
          return;
      }
      if(indexSelected==0 && moveUp)
      {
          return;
      }
     
     revertOptions(listElement,indexSelected,indexSelected+step);
   }
}

// Ouvre l'assistant de saisie sur les dates exclues
function openExcludedDateAssistant(fieldId)
   {
      var excludedField = document.getElementById(fieldId);
      var excludedContent = excludedField.value;
      var baseUrl = sysGetAppBaseUrl();
      var action = baseUrl+"jsp/admin/excludeddate/assist_excluded_dates.jsp";
      action += "?fieldId="+fieldId+"&excludedContent="+excludedContent+
      			"&paramSubscription="+true;
      var winName = "excluded_dates";
      var options = "toolbar=0,location=0,directories=0,menuBar=0,scrollbars=yes,resizable=yes"
      var windowStyle = "height=300px, width=575px, top=200px, left=200px" + options;        
      // alert("actionAfter before openWindows = " + action);
      window.open(action ,winName,windowStyle);
   }
