/*licence/ 

Module écrit, supporté par la société Alkante SAS <alkante@alkante.com>

Nom du module : Alkanet::Library
Librairie js et php globale à Alkanet.
Ce module appartient au framework Alkanet.

Ce logiciel est régi par la licence CeCILL-C soumise au droit français et
respectant les principes de diffusion des logiciels libres. Vous pouvez
utiliser, modifier et/ou redistribuer ce programme sous les conditions
de la licence CeCILL-C telle que diffusée par le CEA, le CNRS et l'INRIA
sur le site http://www.cecill.info.

En contrepartie de l'accessibilité au code source et des droits de copie,
de modification et de redistribution accordés par cette licence, il n'est
offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
seule une responsabilité restreinte pèse sur l'auteur du programme, le
titulaire des droits patrimoniaux et les concédants successifs.

A cet égard l'attention de l'utilisateur est attirée sur les risques
associés au chargement, à l'utilisation, à la modification et/ou au
développement et à la reproduction du logiciel par l'utilisateur étant
donné sa spécificité de logiciel libre, qui peut le rendre complexe à
manipuler et qui le réserve donc à des développeurs et des professionnels
avertis possédant des connaissances informatiques approfondies. Les
utilisateurs sont donc invités à charger et tester l'adéquation du
logiciel à leurs besoins dans des conditions permettant d'assurer la
sécurité de leurs systèmes et ou de leurs données et, plus généralement,
à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.

Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
pris connaissance de la licence CeCILL-C, et que vous en avez accepté les
termes.

/licence*/

/**
 * @brief ajout d'un élément à la fin de la liste d'un combobox
 *        Retourne true si l'élément est ajouté, faux sinon
 * @param objSelect          Référence sur l'objet combo
 * @param val                valeur de l'élément ajouté
 * @param txt                texte de l'élément ajouté
 * @param bMoveDefaultToEnd  true si le dernier élément est vide, nécessaire pour les combo à sélection multiple
 * @param bVerifExist        true pour vérifier si la valeur existe déjà. la fonction retourne false si la valeur est trouvée.
 *                           false pas de vérif.
 * @return boolean 
 */
function AddOptionToSelect(objSelect, val, txt, bMoveDefaultToEnd, bVerifExist)
{
  if( bVerifExist ) {
    var i = 0;
    var bFound = false;
    while( !bFound && i<objSelect.length ) {
      if( objSelect.options[i].value.toLowerCase().replace(/(^\s+)|(\s+$)/g, "") != val.toLowerCase().replace(/(^\s+)|(\s+$)/g, "") ) {
        i++;
      } else { 
        bFound = true;
      }
    }
    if( bFound ) return false;
  }

  if( bMoveDefaultToEnd ) {
    // déplace l'élément vide, puis place l'élément en avant dernière position
    objSelect.length=objSelect.length+1;
	  var nbElt = objSelect.length;
	  objSelect.options[nbElt-2].value = val;
	  objSelect.options[nbElt-2].text = txt;
	  objSelect.options[nbElt-1].value = "-1";
	  objSelect.options[nbElt-1].text = "";
    if( objSelect.selectedIndex == (nbElt-2) )
      objSelect.selectedIndex = nbElt-1;
  } else {
    // place l'élément en dernière position
  	objSelect.length=objSelect.length+1;
	  var nbElt = objSelect.length;
	  objSelect.options[nbElt-1].value = val;
	  objSelect.options[nbElt-1].text = txt;
    objSelect.selectedIndex = nbElt-1;
  }
  return true;
}

/**
 * @brief ajout par insertion d'un élément dans un combobox
 *        Retourne true si l'élément est ajouté, faux sinon
 * @param objSelect          Référence sur l'objet combo
 * @param val                valeur de l'élément ajouté
 * @param txt                texte de l'élément ajouté
 * @param bMoveDefaultToEnd  true si le dernier élément est vide, nécessaire pour les combo à sélection multiple
 * @param bVerifExist        true pour vérifier si la valeur existe déjà. la fonction retourne false si la valeur est trouvée.
 *                           false pas de vérif.
 * @return boolean 
 */
function AddBySortOptionToSelect(objSelect, val, txt, bMoveDefaultToEnd, bVerifExist)
{
  var i = 0;
  var iInsert = -1;
  var bFound = false;
  var bInsert = false
  var nbItems = ( bMoveDefaultToEnd ? objSelect.length-1 : objSelect.length );
  while( ((!bVerifExist && !bInsert) || (bVerifExist && !(bInsert && bFound))) && i<nbItems ) {
    if( !bInsert && objSelect.options[i].text > txt ) {
      iInsert = i;
      bInsert = true;
    }
    if( bVerifExist && !bFound ) {
      bFound = (objSelect.options[i].value == val);
    }
    i++;
  }
  if( bVerifExist && bFound ) return false;

  if( iInsert == -1 ) {
    // insertion à la fin
    iInsert = nbItems;
  }

  objSelect.length=objSelect.length+1;
  nbItems = objSelect.length;
  for($i=nbItems-1; $i>iInsert; $i--) {
    objSelect.options[$i].value = objSelect.options[$i-1].value;
    objSelect.options[$i].text  = objSelect.options[$i-1].text;
  }
  objSelect.options[iInsert].value = val;
	objSelect.options[iInsert].text = txt;
  objSelect.selectedIndex = iInsert;
  return true;
}

/**
 * @brief Sélectionne tous les éléments de la liste sauf le dernier
 * @param objSelect       Référence sur l'objet combo
 * @param bNotSelectLast  true pour ne pas sélectionner le dernier élément, 
 *                        false pour tout sélectionner
 */
function SelectAllValues(objSelect, bNotSelectLast) 
{
  if( !objSelect.multiple ) return;
  bNotSelectLast = ( typeof(bNotSelectLast)=="undefined" ? true : bNotSelectLast );

  // selectionne tous les elements de liste
  for(var i=0; i<objSelect.length; i++)
    objSelect.options[i].selected = true;

  // retire le dernier element vide de la selection
  if( objSelect.length > 0 && bNotSelectLast )
    objSelect.options[objSelect.length-1].selected = false;
}

/** obsolete */
function DelOptionFromSelect(objSelect)
{
	objSelect.selectedIndex = 0;
	objSelect.length = 1;
}

/** obsolete */
function SupprVal(objSelect, bReturn) 
{
  // supprime de la liste, l'element de la liste d'indice idSuppr
  var idSuppr = objSelect.selectedIndex;
  var nbElt = objSelect.length;
  if( idSuppr==-1 || idSuppr==nbElt-1 || nbElt<2 )
    return "-1";

  var strValSuppr = objSelect.options[idSuppr].value;

  if( idSuppr >= nbElt - 2 )
     objSelect.selectedIndex = nbElt - 1;
  else
    objSelect.selectedIndex = idSuppr;

  objSelect.options[nbElt-1].value = "";
  objSelect.options[nbElt-1].text = "";

  for(var i=idSuppr; i<objSelect.length-1; i++) {
    objSelect.options[i].value = objSelect.options[i+1].value;
    objSelect.options[i].text = objSelect.options[i+1].text;
   }
  objSelect.length = nbElt - 1;

 if( bReturn )  return strValSuppr;
}

/**
 * @brief Sélectionne l'élément d'un combo ayant la valeur strValue
 * @param objSelect  Référence sur l'objet combo
 * @param strValue   Valeur à sélectionner
 */
function SetSelectValue(objSelect, strValue)
{
  var nbElt = objSelect.length;
  var i = 0;
  while( i < objSelect.options.length && objSelect.options[i].value != strValue ) i++;
  if( i < objSelect.options.length )
    objSelect.options[i].selected = true;
}

/**
 * @brief Supprime l'élément sélectionné, sauf le dernier si bDefaultToEnd est à true
 * @param objSelect      Référence sur l'objet combo
 * @return string : la valeur de l'élément supprimé
 */
function RemoveSelectedFromSelect(objSelect)
{
  bDefaultToEnd = ( objSelect.options.length > 0 && 
                    objSelect.options[objSelect.options.length-1].value == "-1" 
                    ? true 
                    : false );

  var idSuppr = objSelect.selectedIndex;
  var nbElt = ( bDefaultToEnd ? objSelect.length-1 : objSelect.length );
  if( idSuppr==-1 || idSuppr>nbElt-1 )
    return "-1";

  var strValSuppr = objSelect.options[idSuppr].value;

  objSelect.selectedIndex = ( idSuppr > nbElt - 2 ? nbElt - 2 : idSuppr );

  for(var i=idSuppr; i<objSelect.length-1; i++) {
    objSelect.options[i].value = objSelect.options[i+1].value;
    objSelect.options[i].text = objSelect.options[i+1].text;
  }
  objSelect.length = objSelect.length - 1;

  return strValSuppr;  
}

/**
 * @brief Supprime tous les éléments d'un combo, sauf le premier si bRemoveFirst est à false
 * @param objSelect     Référence sur l'objet combo
 * @param bRemoveFirst  true pour tout supprimer, false pour préserver le premier
 * @paramopt bChangeFirst  true changer le texte du premier élément en '' et sa valeur en -1
 */
function RemoveAllFromSelect(objSelect, bRemoveFirst)
{
  objSelect.selectedIndex = -1;
  if( bRemoveFirst ) 
    objSelect.options.length = 0;
  else {
    objSelect.options.length = 1;
    var bChangeFirst = (arguments.length>2 ? arguments[2] : true);
    if ( bChangeFirst ){
  	  objSelect.options[0].value = "-1";
  	  objSelect.options[0].text = "";
    }
  }
}

/**
 * @brief Supprime tous les éléments d'un combo, sauf le premier si bRemoveFirst est à false
 * @param formName      Nom du formulaire contenant le combo
 * @param objSelect     Référence sur l'objet combo
 * @param strForbidden  liste de valeur séparée par une virgule non permise dans la sélection d'un combo
 */
function isSelectRequire(formName, objSelect, strForbidden)
{
  var tabForbidden = strForbidden.split(',');
  var bOk = true;
  if( objSelect && objSelect.selectedIndex<0 ) return false;
  if (objSelect.multiple){
    for (var opt=0; opt<objSelect.options.length; opt++){
      if (objSelect.options[opt].selected){
        var value = objSelect.options[opt].value;
        for (var i=0; i<tabForbidden.length; i++){
          bOk &= ( value != tabForbidden[i] );
        }
      }
    }
  }
  else {
    var value = objSelect.options[objSelect.selectedIndex].value;
    for (var i=0; i<tabForbidden.length; i++){
      bOk &= ( value != tabForbidden[i] );
    }
  }
  return bOk;
}

/**
 * @brief Ajoute un element d'un combo simple vers un combo multiple
 *        L'élément du combo simple est désactivé
 *        une commande ajax enregistre la manip sur le serveur
 *        la méthode ajax appelle la fonction nommmée par fnCallBack
 * @param strUrlSave             Url complète utilisée par la requete ajax, chaine vide pour ne pas requeter
 * @param oCtrlSrc               Référence sur l'objet combo source
 * @param oCtrlDest              Référence sur l'objet combo destination
 * @param fnCallBack             fonction appelée en retour d'ajax. 
 *                               Contient un paramètre, celui du code html retourné par la requete ajax
 * @param bDestMoveDefaultToEnd  true si le combo destination contient un élément null en fin de liste, false sinon
 * @param bAddBySort             true pour ajouter l'élément déplacer en ajout par insertion. 
 *                               false pour un ajout en fin de liste
 *                               Nécessaire que la liste de comboDest soit triée au préalable.
 */ 
function flipDataComboToCombo(strUrlSave, oCtrlSrc, oCtrlDest, fnCallBack, bDestMoveDefaultToEnd, bAddBySort)
{
  bAddBySort = ( typeof(bAddBySort)=="undefined" ? false : bAddBySort );
  var data_id = -1;
  if( oCtrlSrc.selectedIndex > -1 ) {
    data_id  = oCtrlSrc.options[oCtrlSrc.selectedIndex].value;
    data_txt = oCtrlSrc.options[oCtrlSrc.selectedIndex].text;
  }

  if( data_id != "-1" && data_id != "" ) {
    if( bAddBySort ) {
      // insertion par tri alphanum
      AddBySortOptionToSelect(oCtrlDest, data_id, data_txt, bDestMoveDefaultToEnd, true);
    } else {
      // insertion à la fin
      AddOptionToSelect(oCtrlDest, data_id, data_txt, bDestMoveDefaultToEnd, true);
    }
    RemoveSelectedFromSelect(oCtrlSrc);
  
    if( strUrlSave != "" ) {
      strUrlSave += "&idd="+data_id;
      var oAjax = new AlkAjax('name'+fnCallBack, fnCallBack, ALK_FORM_METHOD_GET, strUrlSave, null);
    }
  }
}

/**
 * @brief Mise à jour de combo à partir d'un tableau de type [0..n-1][0..1]
 *        [0..n-1][0] => value et [0..n-1][1] => texte
 * @param objSelect        Référence sur l'objet combo
 * @param tabData          Données à importer
 * @param bRemoveAllBefore true pour effectuer un nettoyage avant insertion, false pour une concaténation
 * @param bDefaultToEnd    true pour la présence d'un élément neutre en fin de liste, false sinon
 * @paramopt bRemoveFirst  true pour supprimer le premier élément
 * @paramopt bChangeFirst  true changer le texte du premier élément en '' et sa valeur en -1
 */
function updateComboFromTabAlkAjax(objSelect, tabData, bRemoveAllBefore, bDefaultToEnd)
{
  var bRemoveFirst = true;
  if ( arguments.length>4 )
    bRemoveFirst = arguments[4];
    
  var bChangeFirst = true;
  if ( arguments.length>5 )
    bChangeFirst = arguments[5];
    
  if( bRemoveAllBefore ) {
    RemoveAllFromSelect(objSelect, bRemoveFirst, bRemoveFirst);
  }

  for(i=0; i<tabData.length; i++) {
    AddOptionToSelect(objSelect, tabData[i][0], tabData[i][1], bDefaultToEnd, false);
  } 
  
  objSelect.selectedIndex = ( objSelect.options.length > 0 ? 0 : -1 );
}
