
// 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 = 50;

// Nom du controle permettant gérer une action sur champ
var CTRL_INPUT_TRIGGER = "input_trigger";

// Repertoire de stockage des images
var IMG_PATH = "icons/css/";
if ( sysGetSystemFrame() )
   IMG_PATH += sysGetAttribute("CssPathName")+"/";
else
   IMG_PATH += "default";
  	 
// 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 sourceName = schemaManager.getCurrentSource();
   var tableName =  schemaManager.getCurrentTable();
   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";
   
   //pru lecture d'un nouveau contrôle permettant l'ajout d'action définit par
   // le jsp
   var input_trigger =  fieldDesc.getAttribute(CTRL_INPUT_TRIGGER);
   var input_trigger_param =null;
   if( input_trigger!=null )
   {
      input_trigger_param = readInputTriggerParam(fieldDesc);
   }
   
   
   // attribut permettant de définir un élément graphique pour afficher les données
   var ui_component = fieldDesc.getAttribute("ui_component");
   //PRU: Code pour rétro compatibilité!
   if(ui_component==null)
   {
      ui_component = fieldDesc.getAttribute("ui_compoment");
   }
   //paramètre spécifique. paramName1=paramValue1||paramName2=paramValue2...
   var ui_param = fieldDesc.getAttribute("ui_param");
   //si aucun ui_component n'est fixé, on vérifie s'il n'en existe pas un
   if(ui_component==null)
   {
      var defaultValue = getDefaultUIComponent(fieldDesc);
      if(defaultValue!=null)
      {
         ui_component=defaultValue[0];
         ui_param=defaultValue[1];
      }
   }
   // 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");
   // sau 06.006.2006 : prise en compte de la syntaxe link=NOM_TABLE;
   var is_link = ( fieldDesc.getAttribute("link") != null );
   var listeName = 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 is_datation = ( fieldDesc.getAttribute("datation") == "true" );
   var is_rich_editor = ( fieldDesc.getAttribute("rich_editor") == "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" );
   
  var is_attach_dcm= ( fieldDesc.getAttribute("attach_dcm") == "true" );
  var userHasRightToAttachGed=false;
  if(is_attach_dcm){
   // Droit d'attacher des documents de l'utilisiateur connecté
 	userHasRightToAttachGed=schemaManager.checkUserAttachGed(linkSource,linkTable);
  }
  
   // texte multiligne ?
   var is_multiline_text = false;
   if ( is_multiple && listeName==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
   // tdn 15/09/2006 ATTENTION : dans le cas d'un champ texte pur, la
   // valeur visible peut être tronquée par rapport à la valeur réelle
   // donc quand on repasse en modif, la valeur positionnée n'est pas la
   // valeur stockée (cf. champ GROUPE.ROLES en ASN)
   if ( (initValue == null) || listeName || is_marc || 
        ( !is_date && !is_thesaurus && !linkTable && !is_link && !is_datation) ) // texte pur
   {
      // 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 MULTIPLE_VALUE_SEP par separ0
      initValue = initValue.replace(new RegExp(MULTIPLE_VALUE_SEP, "g"), separ0);
   }   
   
   //si ui_class existe on utilise cet objet pour générer le code HTML
   if(ui_component!=null)
   { 
      var params = new Array();
      
      if(listeName!=null)
      {
         var list = schemaDesc.getList(listeName);
         if ( ! list )
         {
            alert(listeName + ": list not found in schema");
            list = new Array();
         }
         params["liste"]=list;
      }
      if(initValue)
         params["initValue"]=initValue;
         
      if( ui_param !=null)
      {
          var paramsTmp = ui_param.split("||");
          for(var i=0;i<paramsTmp.length;i++)
          {
             var param = paramsTmp[i];
             var nameValue = param.split("=");
             params[nameValue[0]]=nameValue[1];
          }
      }
      var component = getComponentFactoryInstance().getComponent(ui_component,sourceName, tableName, fieldName, params, elemId)
      var widget = component.getWidget();
      return widget.text();
   }
   
                    
   
   // 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().checkControls('"+fieldName + "','" + elemId+"');getView().updateData('"+fieldName + "','" + elemId+"', true);getView().showInputFieldDisplayValue('" + elemId +"',false);")
          .att("onKeyUp", "getView().showInputFieldDisplayValue('" + elemId +"')")
          .att("onMouseOver", "getView().showInputFieldDisplayValue('" + elemId +"',false);")
          .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);
   }
	
   //ABE : 18/01/05 si select-list activé on positionne les attributs onfocus et onblur et accesskey
   if( listeName == null)
   {       
         widget .att("onfocus", "getView().initializeSelectList('" + elemId +"')");
         widget .att("onblur", "getView().hideSelectList()");
         widget .att("onkeypress", "getView().completeSelectList()");
   }

   // 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
   var readonly = 
	is_composite || (concat_ctrl != null)  || is_no_input || is_link || is_datation
       || (linkTable != null) 
       || (   is_no_modif  &&  initValue != "" 
           && (schemaManager.getCurrentRecordAction() == "updateRecord") );
   if ( readonly )
   {
      // 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", "readonly");
      widget.att("class", "marcReadOnly");
      widget.att("tabindex", "-1"); // tdn 23/08/2006 pas de focus avec touche TAB
   }
   
  	// 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", 3).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  &&  listeName == 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);
      if ( ! readonly )
	      widget.att("class", "DateInput");
	  else
	      widget.att("class", "DateInputReadOnly");
	  
   }
   
   // Ctrl liste=NomListe
   if ( listeName != null)
   {
      // Contenu de la liste
      var list = schemaDesc.getList(listeName);
      if ( ! list )
      {
         alert(listeName + ": list not found in schema");
         return;
      }
   
      // 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;
      var listLength = getHashLength(list);
      if ( (listLength <= 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", "disabled");
      }
      else
      {
         widget.att("readonly", "readonly"); // désactivé
         widget.att("class", "marcReadOnly");
         widget.att("tabindex", "-1");// tdn 23/08/2006 pas de focus avec touche TAB
         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 ( listLength <= 5 )  
            widget.att("multiple", "true").att("size", listLength);
         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();
         
         // Cas 136 tdn : bouton ajouter sur une liste courte
         var listAppendable = (fieldDesc.getAttribute("list_appendable")=="true");
         if ( listAppendable )
         {
            if ( fieldDesc.getAttribute("modify")=="true" )
            {
               var listSource = fieldDesc.getAttribute("source");
               if ( ! listSource || listeSource=="" )
               {
                   listSource = sourceName;//par défaut
               }
               var img2 = new Tag("img").att("src", IMG_PATH+"input/list_append_item.gif");
               img2.att("class", "ImgInput").att("border", "0")
                  .att("title", sysGetMessage("input.list.append.item.tip"));
               var btn2 = 
                  new Tag("a").setBody(img2.text())
                   .att("href", "javascript:getView().listAppendItem('"
                     +listSource+"','"+listeName+"','"+tableName +"','"+fieldName + "','"+elemId+"','"+inputId+"')");
               btn2.att("tabindex", "-1"); // pour ne pas avoir focus avec touche TAB
               ret += btn2.text();
            
               /* Cas 142 Ce debug permet de vérifier qu'on ne passe par 2 fois par le
               refresh de la grille en saisie sur table MUS_BIEN
               if ( fieldName == "STATUT_BIEN")
               {
                  alert("Refresh de la grille de saisie");
               }
               */
            }
         }
      }
      else // on utilise l'assistant
      {

         var visibleValue = "";
         var inputValue = "";
         if ( list ) for (var key in list)
         {
         //23/04/07 ABE : bug sur le code map qui est un nom reservé JS
         if(key != "map")
            // 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", IMG_PATH+"input/input_list.gif");
         img.att("class", "ImgInput").att("border", "0").att("title", mess_input_list_search);
         var btn = 
            new Tag("a").setBody(img.text())
             .att("href", "javascript:getView().listEdit('"+fieldName + "','" + elemId+"')");
         btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         // 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 = widget.text()+btn.text();
         
         var img1 = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
         img1.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
         var btn1 = 
            new Tag("a").setBody(img1.text())
             .att("href", "javascript:getView().eraseValue('"+fieldName + "','" + elemId+"')");
         btn1.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         ret += btn1.text();
         
         }
      }
      
   }
   // COMPOSITE
   else if ( is_composite  &&  !is_no_input)
   {
      // Ajoute un bouton éditer
      var img = new Tag("img").att("src", IMG_PATH+"input/input_composite.gif");
      img.att("class", "ImgInput").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+"')");
      btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
      ret = widget.text()+btn.text();
      
      var img1 = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
         img1.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
         var btn1 = 
            new Tag("a").setBody(img1.text())
             .att("href", "javascript:getView().eraseValue('"+fieldName + "','" + elemId+"')");
         btn1.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
             
         ret += btn1.text();
         
   }
   // CHAMP LIE
   else if ( linkTable != null  &&  !is_no_input)
   {
      ret = widget.text();
      // Recherche des autorités
      var img = new Tag("img").att("src", IMG_PATH+"input/input_link.gif");
      img.att("class", "ImgInput").att("border", "0").att("title", mess_input_authority_search);
      var btn = 
         new Tag("a").setBody(img.text())
          .att("href", "javascript:getView().linkEdit('"+linkSource+"','"+linkTable+"','"+fieldName + "','" + elemId+"')");
      btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
          
      ret += btn.text(); 
      
      var img1 = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
         img1.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
         var btn1 = 
            new Tag("a").setBody(img1.text())
             .att("href", "javascript:getView().eraseValue('"+fieldName + "','" + elemId+"')");
         btn1.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
             
         ret += btn1.text();
      
      // Ajout direct d'autorité    
      if ( userHasRightToCreateAutority && getDIRECT_INPUT()=="true")
      {
         var img2 = new Tag("img").att("src", IMG_PATH+"input/add_authority.gif");
         img2.att("class", "ImgInput").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+"')");
         btn2.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
             
         ret += btn2.text();
      }   
      
            // Attache un document GED  
      if (userHasRightToAttachGed)
      {
          
         var img3 = new Tag("img").att("src", IMG_PATH+"input/attach_dcm.gif");
         img3.att("class", "ImgInput").att("border", "0").att("title", mess_input_attach_dcm);
         var btn3 = 
            new Tag("a").setBody(img3.text())
             .att("href", "javascript:getView().showAttachGed('"+linkSource+"','"+linkTable+"','"+fieldName + "','" + elemId+"')");
         btn3.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
             
         ret += btn3.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(MULTIPLE_VALUE_SEP);
        var thesIdValues = thesIdValue.split(MULTIPLE_VALUE_SEP);
        //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
      // tdn 29/06/2006 : la liste ne doit pas être tout le temps multiple, il faut
      // tenir compte des controles
      var thesList = new Tag("select");
      var listSize = 2;
      if ( mult_maxi > 1 ) 
      {
         thesList.att("multiple", "true");
         listSize = 5;
         if ( mult_maxi < listSize )
         	listSize = mult_maxi;
      }
      thesList.att("name", localFieldName).att("size", listSize).att("id", inputId).att("class","marcSelect");
      if (optionsHTML.length > 0)
         thesList.setBody(optionsHTML);
      else
         thesList.setBody("\n");
      
      //Bouton d'assistant sur thésaurus
      var imgAssist = new Tag("img").att("src", IMG_PATH+"tools/assist_thes.gif");
      imgAssist.att("class", "ImgInput").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";
      //thesaurus éditable
      var thesAction = sysGetAppBaseUrl() + "jsp/thesaurus/thesaurus_assist_editable.jsp";
      var thesTarget = "win_input." + localformName + "." + localFieldName;
      var thesActionType = "thesaurus-input-generic";
      var thesCritNotOblig = "1";

      var btnAssist = new Tag("a").setBody(imgAssist.text());
      btnAssist.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
      var formCall = "javascript:frmShowThesaurusAssist('" + localformName + "','" +
                          thesAction + "','','" + thesTable + "','','" +
                          thesId + "','','" + thesAssist + "','','" + 
                          thesTarget + "','','" + thesActionType + "','','" +
                          thesCritNotOblig + "'"  ;
      if ( thesTypeFilter )
      {
         formCall += ", '', '" + thesTypeFilter + "'";
      }
      formCall +=",'','','','','','','', true";
      formCall += ")";
      btnAssist.att("href", formCall);
      
      //Bouton suppression d'une ligne dans la liste
      var frameName = "win_input";
      
      var imgDelete = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
      imgDelete.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
      // tdn 29/06/2006 passer l'id du champ et de l'élément html pour
      // pouvoir avoir des champs répétables 
      var btnDelete = 
           new Tag("a").setBody(imgDelete.text())
             .att("href", "javascript:inputRemoveSelectedOptions('"+localformName+"','"+localFieldName+"','" + inputId +
             "');javascript:thesaurusListToSchemaData('" + frameName + "','" + fieldName + "','" + elemId + "')");
      btnDelete.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
                 
      // 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 = thesList.text() +  btnAssist.text() + btnDelete.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", IMG_PATH+"tools/assist_calendar.gif");
         img.att("class", "ImgInput").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')");
         btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         ret += btn.text();
         
          var img1 = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
         img1.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
         var btn1 = 
            new Tag("a").setBody(img1.text())
             .att("href", "javascript:getView().eraseValue('"+fieldName + "','" + elemId+"')");
         btn1.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         ret += btn1.text();
         
      }
   }
    // DATATION
   else if ( is_datation )
   {
      ret = widget.text();
        var datationAction = sysGetAppBaseUrl() + "jsp/tools/assist_datation.jsp";
     
         var img = new Tag("img").att("src", IMG_PATH+"tools/assist_calendar_datation.gif");
         img.att("class", "ImgInput").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:getView().datationEdit('"+fieldName + "','" + elemId+"')");

         btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         if(!isFieldNameEndDatation(fieldName)) ret += btn.text();
          
          var img1 = new Tag("img").att("src", IMG_PATH+"action/input_delete.gif");
         img1.att("class", "ImgInput").att("border", "0").att("title", mess_input_delete);
         var btn1 = 
            new Tag("a").setBody(img1.text())
             .att("href", "javascript:getView().eraseValue('"+fieldName + "','" + elemId+"')");
         btn1.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         ret += btn1.text();
   }
   
  else if ( is_rich_editor )
   {
      ret = widget.text();
        var rich_editorAction = sysGetAppBaseUrl() + "jsp/tools/assist_rich_editor.jsp";
     
         var img = new Tag("img").att("src", IMG_PATH+"tools/assist_rich_editor_off.gif");
         img.att("class", "ImgInput").att("border", "0").att("title", sysGetMessage("input.html.wysiwyg"));
         // 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:getView().rich_editorEdit('"+fieldName + "','" + elemId+"')");

         btn.att("tabindex", "-1"); // tdn 23/08/2006 tabindex=-1 pour ne pas avoir focus avec touche TAB
         ret += btn.text();

   }
   
   else
   {
      ret = widget.text();
   }
   
      /*
   //Modif abe 08/02
   //ajout d'une image pour les input templates
   */
   /*   if(   listeName == null)
   { 
   */
   var is_caching=false;
   //récupère la valeur du champ is_cahing -> si il est en cache on affiche star_on sinon star_off
   if(InputTemplateManagerUse)
   {
      if(getInputTemplateManagervar().isActivate()) is_caching=getInputTemplateManagervar().getCurrentInputTemplate().getInputTemplate(fieldName+"-"+elemId);
      
             var imgActiveField = new Tag("img").att("src", IMG_PATH+"action/star_on.gif");
         imgActiveField.att("class", "ImgInput").att("border", "0").att("title", sysGetMessage("input.template.delete"))
         .att("style","display:none;").att("id","staron_"+fieldName+"-"+elemId).att("name","staron")
         .att("onclick", "getView().desactivateFieldInputTemplate('" +fieldName+"-"+elemId + "')");
         if(is_caching && getInputTemplateManagervar().isActivate()) imgActiveField.att("style","display:inline;");
         ret+=imgActiveField.text();
         
         imgActiveField = new Tag("img").att("src", IMG_PATH+"action/star_off.gif");
         imgActiveField.att("class", "ImgInput").att("border", "0").att("title", sysGetMessage("input.template.add"))
         .att("style","display:none;").att("id","staroff_"+fieldName+"-"+elemId).att("name","staroff")
          .att("onclick", "getView().activateFieldInputTemplate('" +fieldName+"-"+elemId+ "')");
          if(!is_caching && getInputTemplateManagervar().isActivate()) imgActiveField.att("style","display:inline;");
           ret+=imgActiveField.text();
   }
   
   
   //pru ajout d'un nouveau contrôle permettant la gestion de script déclencher sur
   //action de l'utilisateur
   if( input_trigger!=null )
   {
      var name = input_trigger_param["name"];
      var paramLength = input_trigger_param["length"];
      var method = ".execute(";
      for(var i=0;i<paramLength;i++)
      {
         if(i>0)
           method+=",";
         var pName="p"+i;
         method+="'"+input_trigger_param[pName]+"'";
         
      }
      method+=")";
      var trig = eval("new " + name + "()");
      var trKey = trig.getTranslationKey();
      var img = new Tag("img").att("src", IMG_PATH+"input/btn_run.gif");
         img.att("class", "ImgInput").att("border", "0").att("title", sysGetMessage(trKey));
      var btn = 
            new Tag("a").setBody(img.text())
             .att("href", "javascript:getTrigger('"+name+"','"+fieldName+"','"+elemId+"')"+method);
         btn.att("tabindex", "-1"); // pour ne pas avoir focus avec touche TAB
      ret+=btn.text();   
   }
   return ret;
}

/**
 * @return un tableau de longueur 2 contenant:
 * 0 : le nom de la classe du composant par défaut
 * 1 : ces paramètres au format param1=val1||param2=val2
 * ou null s'il n'existe pas de composant par défaut
 */
function getDefaultUIComponent(fieldDesc)
{
   if(fieldDesc.getAttribute("source_choice")!=null)
   {
      var result = new Array();
      result[0]="SourceComponent";
      result[1]="";
      return result;
   }
   else if(fieldDesc.getAttribute("table_choice"))
   {
      var source = fieldDesc.getAttribute("table_choice");
      var result = new Array();
      result[0]="TableComponent";
      result[1]="source="+source;
      return result;
   }
   return null;
}

/*********************************************************
 * 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;
   //@pru ajout d'un objet listener implementant valueChanged(value)
   this.listener=null;
}

// 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*1000);
      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);

      //test si la fonctino getView existe
      //si c'est le cas on est saisie d'une date dans un formulaire de saisie marc
      //le treitement à appliquer est différent
      if ( window.getView )
      {
         this.updateForMarcInput();
      }
      if(this.listener!=null)
        this.listener.valueChanged(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;
   
   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;
}

//Met à jour l'xml en mémoire pour les saisies de dates passant par
//marc_input
CalendarWidget.prototype.updateForMarcInput = function()
{
   var name = null;
   var id = null;
   
   //Récupération de l'id sans l'ajout de _input pour l'appel de la mise à jour
   //C'est l'id de la div que l'on récupère
   var parts = this.inputDestElem.id.split("_input");
   if ( ( parts ) && ( parts.length > 0) )
   {
      id = parts[0];
   }
   
   if (id)
   {
      //Récupération du nom de la div contenant l'input
      var input = document.getElementById(id);
      if (input)
      {
         name = input.getAttribute("name");
         //Mise à jour de l'arbre de donnée
         getView().updateData(name, id, true);
      }
   }
   
}

CalendarWidget.prototype.setListener = function(listener)
{
   if(typeof(listener)=='object')
    this.listener=listener;
}



/*
* Réalisation des fonctions de Templates de saisie
* abe 18/01/2006
**/
  /**
 * Appel de l'assistant de saisie selectList dans une DIV par un scriptAction
 *
 */


/*********************************************************
 * Objet select-list générique
 * @author abe
 *********************************************************/
 // divContainer : <div> contenant le select-list
 // values : valeurs à afficher
 //inputDestElem : <div> englobant le champ destinataire
 //inputDestElemInput : input de destination de la valeur
 //isHidable : le <div> peut être chaché ou non

function SelectListWidget(divContainer, values, inputDestElem,name,autoHideDelay)
{
   this.name = name;
   this.divContainer=divContainer;
   this.values = values;
   this.inputDestElem = inputDestElem;
   this.inputDestElemInput=document.getElementById(this.inputDestElem.id+"_input");
   this.isHidable=1;
   this.divContainer.style.width=MAX_INPUT_SIZE/2.1+"em";
   this.autoHideDelay=autoHideDelay;
   this.hideTimer=0;
}

/*********************************************************
 * 
 * Active le selectlist visuellement
 *
 *********************************************************/
 
SelectListWidget.prototype.show = function() 
{
 if (!this.values) return;
   this.divContainer.innerHTML = this.getHTML();
   this.setPosition();   
  sysShow(this.divContainer.id);
     if ( this.autoHideDelay > 0 )
      this.checkAutoHideDelay(this.autoHideDelay, true);
}   

 
SelectListWidget.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*1000);
      return;
   }
   this.hide();
}

SelectListWidget.prototype.onMouseMove = function ()
{
   this.curMouseX = sysMouseX;
   this.curMouseY = sysMouseY;
}
SelectListWidget.prototype.restartTimer = function()
{
   // Remet à zéro l'état du timer
   this.curMouseX = 0;
   this.curMouseY = 0;
   this.hideTimer=0;
}

/*********************************************************
 * 
 * construit le select list en html
 *
 *********************************************************/
SelectListWidget.prototype.getHTML = function(isCompleted)
{
   if (!this.values) return;
   else {  
   var m_values=this.values;           
   var htmlTable = '';
    htmlTable += "<ul>";
      for (var i=0;i<m_values.length;i++)
      {
         var Display=m_values[i]['display'];
         var Value=m_values[i]['value'];
         if(Display==null) Display=Value;
         
         if(isCompleted)
         {
        var Pattern=this.inputDestElemInput.value;
            if(Display.indexOf(Pattern,0)==0)
            {
               htmlTable += "<li><a href='javascript:mySelectList.retrieveValue(\""+this.divContainer.id+i+"\");' id='"+this.divContainer.id+i+"' onmouseover=\"javascript:mySelectList.setIsHidable(0)\" onmouseout=\"javascript:mySelectList.setIsHidable(1)\" value=\""+Value+"\" displayvalue=\""+Display+"\" class='SelectListLnk'>";
               htmlTable +=Display;
               htmlTable += "</a></li>";
            }
         }
         else
         {
               htmlTable += "<li><a href='javascript:mySelectList.retrieveValue(\""+this.divContainer.id+i+"\");' id='"+this.divContainer.id+i+"' onmouseover=\"javascript:mySelectList.setIsHidable(0)\" onmouseout=\"javascript:mySelectList.setIsHidable(1)\" value=\""+Value+"\" displayvalue=\""+Display+"\" class='SelectListLnk'>";
               htmlTable +=Display;
               htmlTable += "</a></li>";
         }
      }
      htmlTable += "</ul>";
   }
   return htmlTable;
}



/*********************************************************
 * 
 * // Rapatrie la valeur spécifiée dans la zone
 *
 *********************************************************/

SelectListWidget.prototype.retrieveValue = function(lineId) 
{
   if ( ! this.inputDestElem )
   {
      alert("retrieveDate impossible, membre inputDestElem non initialisé");
   }
   else
   {      
      //test si la fonction getView existe
      // dans ce cas on fait le traitement relatif à marc_input
      if(this.inputDestElemInput.getAttribute("inputValue")) this.inputDestElemInput.setAttribute("inputValue", document.getElementById(lineId).getAttribute('value'));
      this.inputDestElemInput.value= document.getElementById(lineId).getAttribute('displayvalue');
      
      
      if ( window.getView() )
      {
        this.updateForMarcInput();
      }
   }
      
   // Fermeture auto
      this.isHidable=1;
      this.inputDestElemInput.onchange();
      this.hide();
}

//Met à jour l'xml en mémoire pour les saisies de dernières valeurs passant par
//marc_input
SelectListWidget.prototype.updateForMarcInput = function()
{
var  name = this.inputDestElem.getAttribute("name");
var id= this.inputDestElem.id;
getView().updateData(name, id, true);  
getView().showInputFieldDisplayValue(id) ;
}

//initailise l'attribut masquable ou non
SelectListWidget.prototype.setIsHidable=function(isHidable)
{
   this.isHidable= isHidable;
}

// Masque le menu contextuel
SelectListWidget.prototype.hide=function()
{
   if(this.isHidable==1)  
   {
      sysHide( this.divContainer.id);
      this.restartTimer();
   }
}

// fonction de complétion
SelectListWidget.prototype.complete=function()
{

   this.divContainer.innerHTML = this.getHTML(true);
}

//positionne l'élément sou l'éléement de destination
SelectListWidget.prototype.setPosition=function()
{
	   // si internet explorer
      if(document.all) this.divContainer.style.left = this.findPosX() -10+ 'px';
      else this.divContainer.style.left = this.findPosX() + 'px';
}

//trouve la position x de l'élément de destination
SelectListWidget.prototype.findPosX=function()
{
	var curleft = 0;
   var obj=this.inputDestElemInput;
   
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}




/*********************************************************
 * Objet assistant div générique d'afficahge en title
 * @author abe
 *********************************************************/
function TitleWidget(name, divDest)
{
   this.name = name; // nom de la variable
   this.divContainer = divDest;
   //@pru ajout d'un objet listener implementant valueChanged(value)
   this.listener=null;
}


// 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


TitleWidget.prototype.show = function(autoHideDelay) 
{

   sysShow(this.divContainer.id, sysMouseX, sysMouseY);      
   if ( autoHideDelay > 0 )
      this.checkAutoHideDelay(autoHideDelay, true);
}   
// initialCall = true si premier appel pour déclencher uniquement le timer
TitleWidget.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*1000);
      return;
   }
   this.hide();
}
TitleWidget.prototype.onMouseMove = function ()
{
   this.curMouseX = sysMouseX;
   this.curMouseY = sysMouseY;
}
TitleWidget.prototype.restartTimer = function()
{
   // Remet à zéro l'état du timer
   this.curMouseX = 0;
   this.curMouseY = 0;   
}
TitleWidget.prototype.hide = function()
{
   clearTimeout(this.hideTimer);
   sysHide(this.divContainer.id);
   this.restartTimer();
}

/**
 * Méthode permettant le chargement des paramètres lié au contrôle input_trigger
 * @param field {SchemaField}: Champ contenant le contrôle
 * @return une hashMap key=nom du param, value=valeur de param 
 * @author pru
 */
function readInputTriggerParam(fieldDesc)
{
   var result = new Array();
   var name = fieldDesc.getAttribute(CTRL_INPUT_TRIGGER+".name");
   if(name!=null)
      result["name"]=name;
   var length = fieldDesc.getAttribute(CTRL_INPUT_TRIGGER+".param_length");
   if(length!=null)
   {
      result["length"]=length;
      for(var i=0;i<length;i++)
      {
         var pName = "p"+i;
         var pValue = fieldDesc.getAttribute(CTRL_INPUT_TRIGGER+"."+pName);
         if(pValue!=null)
            result[pName]=pValue;
      }
   }
   return result;
}

/**
 * Fonction retournant le trigger défine dans le class javascript jsClassName
 * Ce trigger doit implémenter les méthodes:
 * setSchemaData(SchemaData)
 * setRecord(Record)
 * setSchemaField(elementDom)
 * getTranslationKey() <-- retourne un clef de traduction (messages_xx.js)pour le tip du trigger 
 * execute(p0,p1,....,pn) 
 *
 * Les trigger doivent être déclaré dans trigger.js (cf duplicateTrigger)
 */
function getTrigger(jsClassName,FieldName,elementID)
{
   var component = eval("new "+jsClassName+"()");
   var view = getView();
   
   if(component.setSchemaData && view!=null)
      component.setSchemaData(view.schemaData);
   if(component.setRecord)
      component.setRecord(new Record(view.schemaData));
   if(component.setSchemaField && FieldName!=null  && elementID!=null)
   {
      var field = view.schemaData.getFieldByNameAndId(FieldName,elementID);
      if(field!=null)
         component.setSchemaField(field);
   }
   return component;
}


