/**
* Utilitats javascript. Per compatibilitat amb el codi existent no he volgut modificar
* les funcions existents i he creat un nou namespace utils.
* @classDescription Funcions de javascript d'utilitats de validació i tractaments de cadenes.
* @author msalla
* @id utils
* @namespace utils
*/

/**
* @classDescription Utilitats varies en javascript.
* @author msalla
*/

/* extern ff-src.js */
//var ff;

var utils =
{
   /**
   * Constants de tecles.
   * @namespace utils.KEYS
   */
   KEYS:
   {
      KEY_DOT: 46,
      KEY_COMMA: 44,
      KEY_BACK: 8
   },
   /**
   * Funcions de processament d'elements dins el DOM.
   * @namespace utils.dom
   */
   dom:
   {
      /**
      * Retorna el text d'una label segons el seu ID.
      * @param {Object} AObj: Objecte label
      * @param {string} [AOnEmptyText] ="" String opcional per si el label és buit.
      * @return {string} El text del label o AOnEmptyText si és buit.
      * alias utils.dom.getTextFromLabelByElem
      * alias getTextFromLabelByElem
      */
      getTextFromLabelByElem:
      function (AObj/*: Object */, AOnEmptyText /*: string*/)/*:string*/
      {
         var lResult /*: string*/ = "";
         try
         {
            if ((AObj !== undefined) && (AObj !== null) && (!AObj.disabled))
            {
               if (navigator.userAgent.indexOf("MSIE") === -1)
               {
                  lResult = AObj.textContent;
                  window.console.info(AObj.id);
               }
               else
               {
                  lResult = AObj.innerText;
                  window.console.info(AObj.id);
               }
               // En cas de que el label contingui la classe "Requerit" eliminem " (*)"
               var lregex= /\bRequerit\b/i;
               var lValorClasse /*:string*/ ="class";
               if (navigator.userAgent.indexOf("MSIE") !== -1)
               {
                  lValorClasse += "Name";
               }
               if ((lregex.test(AObj.getAttribute(lValorClasse))) && (lResult !== undefined) && (lResult !== null))
               {
                  lResult = lResult.slice(0,-4);
               }
               // Si el resultat és buit utilitzem AOnEmptyText si aquest no és buit
               if ((lResult === undefined) || (lResult === null) || (lResult === ""))
               {
                  if ((AOnEmptyText !== undefined) && (AOnEmptyText !== null))
                  {
                     lResult = AOnEmptyText;
                  }
                  else
                  {
                     lResult = "";
                  }
               }
            }
         }
         catch (e /*:exception*/)
         {
            window.console.error("getTextFromLabelByElem" + e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
      * Retorna el text d'una label segons el seu ID.
      * @param {string} AObjId: Object id
      * @param {string} [AOnEmptyText] ="" String opcional per si el label és buit.
      * @return {string} El text del label o AOnEmptyText si és buit.
      * alias utils.dom.getTextFromLabelById
      * alias getTextFromLabelById
      */
      getTextFromLabelById:
      function (AObjId/*: string */, AOnEmptyText /*: string*/)/*:string*/
      {
         var lResult /*: string*/ = "";
         try
         {
            var lObj = document.getElementById(AObjId);
            lResult = utils.dom.getTextFromLabelByElem(lObj,AOnEmptyText);
         }
         catch (e /*:exception*/)
         {
            window.console.error("getTextFromLabelById:" + e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
       * Busca els span (labels) en el document que han de ser marcats com a requerits i afegeix l'(*) de 
       * requerit en el seu text. Es determina que un label és requerit basant-se en que l'atribut class 
       * contingui el nom de classe 'requerit'. 
       */
	  establirLabelsRequerits:
      function ()/* void */
      {
         // Labels camps requerit
         var lInputArray = document.getElementsByTagName("span");
         var lregex= /\bRequerit\b/i;
         var lInput /*: object*/;
         var i /*:integer*/;
         
         for (i = 0; (i<lInputArray.length); i++)
         {
            lInput = lInputArray[i];
            // Compatibilitat no IE
            if (navigator.userAgent.indexOf("MSIE") === -1)
            {
               if (lregex.test(lInput.getAttribute("class")))
               {
                  lInput.innerHTML = lInput.innerHTML + " (*)";
               }
            }
            else
            {
               if (lregex.test(lInput.getAttribute("className")))
               {
                  lInput.setAttribute("innerText",lInput.innerText + " (*)");
               }
            }
            
         }
      },
      checkExclusiu:
      function (AObjId /*string*/, ACheckArray /*checkbox[]*/)
      {
         for (var i /*:integer*/ = 0; i< ACheckArray.length; i++)
         {
            if ((ACheckArray[i].id !== AObjId) && (ACheckArray[i].checked))
            {
               ACheckArray[i].checked = false;
            }
         }
      },
	  /**
	   * Fa que la selecció dels checks que continguin una classe indicada a AClassGroup al l'atribut class
	   * sigui exclusiva. 
	   * @param {Object} AObj:checkbox
	   * @param {Object} AClassGroup:string
	   */
      exclusiveCheckboxGroup:
      function (AObj /*:checkbox*/, AClassGroup /*:string*/)
      {
         var lClasseGrup /*:string*/;
		 var lLlistaClasses /*[]*/;
		 var lNomClasses /*:string*/;
         if (arguments.length <2)
         {
            lLlistaClasses = ff.style.getClass(AObj.parentNode).split(" ");
            lClasseGrup = lLlistaClasses[0];
         }
         else
         {
            lClasseGrup = AClassGroup;
         }
         var lCheckArray = [];
         var i /*:integer*/ = 0;
         var j /*:integer*/ = 0;
         var lSpanArray /*object[]*/= document.getElementsByTagName("span");
         for (i /*:integer*/ = 0; i< lSpanArray.length; i++)
         {
            lNomClasses = ff.style.getClass(lSpanArray[i]);
			if ((lNomClasses !== undefined) && (lNomClasses !== null) && 
			    (lNomClasses.indexOf(lClasseGrup) !== -1) && 
			    (lSpanArray[i].childNodes[0].type == "checkbox"))
            {
               lCheckArray[j] = lSpanArray[i].childNodes[0];
			   j++;
            }
         }
		 for (i /*:integer*/ = 0; i< lCheckArray.length; i++)
         {
			ff.event.add(lCheckArray[i],"click",
			   function (event /*:event*/)
               {
                  utils.dom.checkExclusiu(this.id,lCheckArray);
               }  
			);
         }
      }
   },
   /**
   * Funcions de tractament de cadenes
   * @namespace utils.str
   */
   str:
   {
      /**
      * Formateja la cadena rebuda com a primer paràmetre amb la resta de paràmetres.
      * @param {String[]} arguments Arguments de la funció.
      * alias utils.str.format
      * alias format
      */
      format:
      function ( /*: String[]*/)
      {
         var lMsg /*: String*/=arguments[0];
         var lPos /*: int*/=1;
         while (lPos < arguments.length)
         {
            lMsg = lMsg.replace(/\%[0-9\.a-zA-Z]/, arguments[lPos++]);
         }
         return String(lMsg);
      },
      /**
      * Funció per formatar/deformatar una cadena corresponent a un float amb separators.
      * @param {string} AStrNum - The number to be formatted.
      * @param {char} [AInDec] = "." The decimal point character. If skipped, "." is used
      * @param {char} [AInThousandSep] = "," The separator character. if skipped, "," is used
      * @param {char} [AOutDec] = "." The decimal point character. If skipped, "." is used
      * @param {char} [AOutThousandSep] = "," The separator character. if skipped, "," is used
      * @return {string} returns El string float deformatat.
      */
      formatFloat:
      function (AStrNum /*:string*/, AInDec/*:char*/, AInThousandSep/*:char*/,
      AOutDec/*:char*/, AOutThousandSep/*:char*/)/*: string */
      {
         // Check for missing parameters and use defaults if so
         if (arguments.length < 5)
         {
            AOutThousandSep = ",";
         }
         if (arguments.length < 4)
         {
            AOutDec = ".";
         }
         if (arguments.length < 3)
         {
            AInThousandSep = ",";
         }
         if (arguments.length < 2)
         {
            AInDec = ".";
         }
         
         AStrNum += '';
         var ldecpos = AStrNum.indexOf(AInDec);
         var lStrNumDecPart = '';
         if (ldecpos != -1)
         {
            lStrNumDecPart = AOutDec + AStrNum.substring(ldecpos + 1, AStrNum.length);
            AStrNum = AStrNum.substring(0, ldecpos);
         }
         
         // Netejem els separadors de miler del format d'entrada si n'hi ha
         var lStrNumIntPart = AStrNum;
         if (lStrNumIntPart.indexOf(AInThousandSep) != -1)
         {
            var lRgx = new RegExp("\\"+AInThousandSep);
            while (lRgx.test(lStrNumIntPart))
            {
               lStrNumIntPart = lStrNumIntPart.replace(lRgx, '');
            }
         }
         if (AOutThousandSep !== "")
         {
            // Cada tres digits de la part entera afegim el separador de milers de sortida
            lRgx = /(\d+)(\d{3})/;
            while (lRgx.test(lStrNumIntPart))
            {
               lStrNumIntPart = lStrNumIntPart.replace(lRgx, '$1' + AOutThousandSep + '$2');
            }
         }
         return lStrNumIntPart + lStrNumDecPart;
      },
      /**
      * Extreu la part vàlida del nombre decimal introduït.
      * Probablement podriem usar també parseFloat.
      * @param {string} AString string
      * @param {integer} ALongitud integer Longitud màxima de caràcters de la part entera.
      * @param {integer} APrecission Nombre de decimals permesos.
      * @param {char} [ADecPoint] = "." The decimal point character. If skipped, "." is used.
      * @param {char} [AThousandSep] = "," The separator character. if skipped, "," is used.
      * @return {string} returns El string float formatat amb separadors de milers i decimal.
      */
      extreuNumDecimalValid:
      function (AString/*: string*/,ALongitud /*: integer*/, APrecission/*: integer*/,
      ADecSeparator/*:char*/, AThousandSep/*:char*/) /*: string */
      {
         // check for missing parameters and use defaults if so
         if (arguments.length == 4)
         {
            AThousandSep = ",";
         }
         if (arguments.length == 3)
         {
            AThousandSep = ",";
            ADecSeparator = ".";
         }
         
         var lResult /*: string */ = "";
         var lMyRegExp /*: regExp */ = new RegExp("\\b^(?:\\d{1,"+ String(ALongitud) + "})\\"+ ADecSeparator + "(?:\\d{1,"+ String(APrecission) + "})|\\b^(?:\\d{1,"+ String(ALongitud) + "})$\\b");
         var lString /*: string */ = AString;
         
         // Si la cadena comença amb un punt afegim un 0 davant i si acaba en un punt l'eliminem
         if ((AString !== undefined) && (AString.length>0))
         {
            if (String(AString).charAt(0) == ADecSeparator)
            {
               lString = '0'+lString;
            }
            if (String(AString).charAt(String(AString).length -1) == ADecSeparator)
            {
               lString = lString.substring(0,String(AString).length -1);
            }
            lString = utils.str.formatFloat(lString,ADecSeparator,AThousandSep,ADecSeparator,"");
            
            var lMatch = lMyRegExp.exec(lString);
            if (lMatch !== null)
            {
               lResult = utils.str.formatFloat(String(lMatch[0]),ADecSeparator,AThousandSep,ADecSeparator,AThousandSep);
            }
         }
         return lResult;
      },
      /**
      * Compta el nombre de punts existents a la cadena amb nombres i punts.
      * @param {Object} AString: string.
      * @param {char} ADecSep: char.
      */
      numDecSep:
      function (AString /*: string*/,ADecSep/*:char*/) /*: integer */
      {
         var lNumDecCount /*: integer */ = 0;
         if ((AString !== undefined ) && (AString.length>0))
         {
            for (var i=0; i<AString.length; i++)
            {
               if (AString.charAt(i) == ADecSep)
               {
                  lNumDecCount ++;
               }
            }
         }
         return lNumDecCount;
      }
   },
   /**
   * Funcions de validació de dades.
   * @namespace utils.vf
   */
   vf :
   {
      /**
      * Valida si un nombre decimal és totalment vàlid o no.
      * @param {Object} AString: string
      */
      IsNumDecimalValid:
      function (AString /*: string*/,ALongitud /*: integer*/, APrecission/*: integer*/,
      ADecPoint/*:char*/, AThousandSep/*:char*/) /*: boolean */
      {
         var lResult /*: boolean */ = false;
         var lRegExpDecimalValid /*: regExp */ = new RegExp("\\b^(?:\\d{1,"+ String(ALongitud) + "})\\"+ADecPoint+"(?:\\d{1,"+ String(APrecission) + "})|\\b^(?:\\d{1,"+ String(ALongitud) + "})$\\b");
         if ((AString !== undefined ) && (AString.length>0))
         {
            // Eliminem els separadors de milers
            var lString = utils.str.formatFloat(AString,ADecPoint,AThousandSep,ADecPoint,"");
            // Validem
            var lArray = lRegExpDecimalValid.exec(lString);
            lResult = ((lArray !== undefined) && (lArray !== null) && (lArray.length > 0) && (lArray[0]!==""));
         }
         return lResult;
      },
      /**
      * Indica si el text d'un textbox està buit o no.
      * @param {Object} AObj Textbox a validar.
      * @param {Boolean} [ACheckTrimmedText] = true Indica si cal comprovar el text fent-li trim.
      * @return {boolean} Si està buit o no.
      * @alias utils.vf.isTextEmpty
      * @alias isTextEmpty
      */
      isTextEmpty:
      function (AObj/*: Object */, ACheckTrimmedText /*: boolean = true*/) /*:boolean*/
      {
         var lVType /*: String []*/ = "text textarea".split(" ");
         var lRegex /*: */ = /\s+/;
         var lResult /*: boolean*/ = false;
         if (utils.vf.isTypeOf(AObj,lVType))
         {
            if ((ACheckTrimmedText === undefined) || ACheckTrimmedText)
            {
               lResult = !((String(AObj.value).replace(lRegex,"")).length > 0);
            }
            else
            {
               lResult = !(String(AObj.value).length > 0);
            }
         }
         return lResult;
      },
      /**
      * Indica si el text d'un textbox està buit o no.
      * @param {string} AObjId Id del Textbox a validar.
      * @param {Boolean} [ACheckTrimmedText] = true Indica si cal comprovar el text fent-li trim.
      * @return {boolean} Si està buit o no.
      * @alias utils.vf.isTextEmptyById
      * @alias isTextEmptyById
      */
      isTextEmptyById:
      function (AObjId/*: string */, ACheckTrimmedText /*: boolean = true*/) /*:boolean*/
      {
         return utils.vf.isTextEmpty(document.getElementById(AObjId), ACheckTrimmedText);
      },
      /**
      * Valida el control indicat per si és buit i en cas de ser-ho mostra un missatge i dona el focus al
      * control.
      * @param {Object} AObjId Id de l'objecte.
      * @param {string} AOnEmptyText Text a visualitzar en cas de buit.
      * @return {boolean} Si està buit o no.
      * @alias utils.vf.checkTextEmptyByElem
      * @alias checkTextEmptyByElem
      */
      checkTextEmptyByElem:
      function (AObj/*: Object */, AOnEmptyText /*: string*/)/*:boolean*/
      {
         var lResult /*: boolean*/ = true;
         if ((AObj !== undefined) && (AObj !== null))
         {
            try
            {
               lResult = utils.vf.isTextEmpty(AObj);
               if (lResult)
               {
                  if (!AObj.disabled)
                  {
                     alert(AOnEmptyText);
                     AObj.focus();
                  }
               }
            }
            catch (e /*:exception*/)
            {
               window.console.error("checkTextEmptyByElem" + e.name + ":" + e.message);
            }
         }
         return lResult;
      },
      /**
      * Valida el control indicat per si és buit i en cas de ser-ho mostra un missatge i dona el focus al
      * control.
      * @param {string} AObjId  Object id.
      * @param {string} AOnEmptyText  string
      * @return {boolean} Si està buit o no.
      * @alias utils.vf.checkTextEmptyById
      * @alias checkTextEmptyById
      */
      checkTextEmptyById:
      function (AObjId/*: string */, AOnEmptyText /*: string*/)/*:boolean*/
      {
         var lResult /*: boolean*/ = true;
         try
         {
            var lObj = document.getElementById(AObjId);
            lResult = utils.vf.checkTextEmptyByElem(lObj,AOnEmptyText);
         }
         catch (e /*:exception*/)
         {
            window.console.error("checkTextEmptyById:" + e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
      * Valida el control indicat per si és buit i en cas de ser-ho mostra un missatge i dona el focus al
      * control.
      * @param {string} AObjId: Object id
      * @param {string} ALabelId: string
      * @return {boolean} Si està buit o no.
      * @alias utils.vf.checkTextEmptyByIdAndLabel
      * @alias checkTextEmptyByIdAndLabel
      */
      checkTextEmptyByIdAndLabel:
      function (AObjId/*: string */, ALabelId /*: string*/)/*:boolean*/
      {
         var lResult /*: boolean*/ = true;
         try
         {
            var lObj /*:object*/= document.getElementById(AObjId);
            var lLabelText /*:string*/= utils.dom.getTextFromLabelById(ALabelId);
            var VALOR_REQUERIT = "S\'ha d\'informar un valor per a \%0";
            
            var lRequiredText = utils.str.format(VALOR_REQUERIT,lLabelText);
            lResult = utils.vf.checkTextEmptyByElem(lObj,lRequiredText);
         }
         catch (e /*:exception*/)
         {
            window.console.error("checkTextEmptyByIdAndLabel:" + e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
      * Comprova que la longitud del valor d'un element sigui vàlida.
      * @param {object} AField
      * @param {integer} ALongitud
      * @return {boolean} Si la longitud del valor de l'element és vàlida o no
      * @alias utils.vf.isValidLength
      * @alias isValidLength
      */
      isValidLength:
      function (AField/*: object*/, ALongitud /*: integer*/, ACheckTrimmedText /*: boolean = true*/) /*:boolean*/
      {
         var lResult /*:boolean */= false;
         var lText /*:string*/="";
         if (AField !== undefined)
         {
            if ((ACheckTrimmedText === undefined) || ACheckTrimmedText)
            {
               var lRegex /*: */ = /\s+/;
               lText = String(AField.value).replace(lRegex,"");
            }
            else
            {
               lText = String(AField.value);
            }
            
            if (Number(lText.length) >= Number(ALongitud))
            {
               lResult = true;
            }
         }
         if (!lResult && !AField.disabled)
         {
            AField.focus();
         }
         return lResult;
      },
      /**
      * Valida si un objecte es d'un determinat tipus.
      * @param {Object} AObj Objecte.
      * @param {String[]} AType Array de tipus a validar.
      * @alias utils.vf.isTypeOf
      * @alias isTypeOf
      */
      isTypeOf:
      function (AObj /*: Object */,AVType /*: String []*/)
      {
         if ((AObj !== undefined) && (AVType !== undefined))
         {
            var lObjType /*: String */ = AObj.type;
            if (lObjType !== "undefined")
            {
               var i /*: number*/;
               var lResult /*: boolean */= false;
               var lType /*: String */;
               
               for (i = 0; ((i<AVType.length) && (!lResult));i++)
               {
                  lType = AVType[i];
                  if (lObjType == lType)
                  {
                     lResult = true;
                  }
               }
               return lResult;
            }
            else
            {
               return false;
            }
         }
         else
         {
            return false;
         }
      },
      /**
      * Valida el format del correu electrònic amb una regular expression.
      * @param {string} email
      * @return {boolean}
      */
      isValidEmail :
      function (AEmail /*:string*/) /*:boolean*/
      {
         var lResult /*:boolean*/ = false;
         try
         {
            lResult =(AEmail === null) || (AEmail === undefined) ||(AEmail === "") || AEmail.match(/\b(^(\S+@).+((\.cat)|(\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\..{2,2}))$)\b/gi);
         }
         catch (e /*:exception*/)
         {
            window.console.error(e.name + ":" + e.message);
         }
         return lResult;
      },
      
      /**
      * Valida el format del correu electrònic amb una regular expression.
      * @param {string} email
      * @return {boolean}
      */
      checkValidEmailById :
      function (AObjId /*:string*/, AErrorText /*:string*/) /*:boolean*/
      {
         var lResult /*:boolean*/ = false;
         try
         {
            var lObj = document.getElementById(AObjId);
            lResult = !utils.vf.isValidEmail(lObj.value);
            if (lResult)
            {
               alert (AErrorText);
               if (!lObj.disabled)
               {
                  lObj.focus();
               }
            }
         }
         catch (e /*:exception*/)
         {
            window.console.error(e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
      * Formata el valor del camp indicat amb la part vàlida del nombre que conté.
      * @param {Object} ASource: Object.
      * @param {char}ADecSeparator:char.
      * @param {char}AThousandSep:char.
      * @alias utils.vf.money_onfocus
      * @alias money_onfocus
      */
      money_onfocus:
      function (ASource /*: Object*/, ADecSeparator /*:char*/, AThousandSep/*:char*/)
      {
         var lVTypes /*: String[]*/ = 'text textarea'.split(' ');
         
         // Validació del tipus
         if (utils.vf.isTypeOf(ASource,lVTypes))
         {
            var lText /*: string */ = String(ASource.value);
            ASource.value = utils.str.formatFloat(lText,ADecSeparator,AThousandSep,ADecSeparator,"");
            ASource.select();
         }
      },
      /**
      * Formata el valor del camp indicat amb la part vàlida del nombre que conté.
      * @param {Object} ASource: Object.
      * @param {integer} ALongitud: integer.
      * @param {integer} APrecission: integer.
      * @param {char} ADecSeparator: char.
      * @param {char} AThousandSep: char.
      * @alias utils.vf.money_onblur
      * @alias money_onblur
      */
      money_onblur:
      function (ASource /*: Object*/,ALongitud /*: integer*/, APrecission/*: integer*/,
      ADecSeparator /*:char*/, AThousandSep/*:char*/)
      {
         var lVTypes /*: String[]*/ = 'text textarea'.split(' ');
         
         // Validació del tipus
         if (utils.vf.isTypeOf(ASource,lVTypes))
         {
            var lText /*: string */ = String(ASource.value);
            ASource.value = utils.str.extreuNumDecimalValid(lText,ALongitud,APrecission,ADecSeparator,AThousandSep);
         }
      },
      /**
      * Comprova que no s'escriguin caràcters no numèrics, màxim nº de decimals i la longitud màxima
      * del nº escrit.
      * @param {Object} ASource Origen per evitar usar target o source.
      * @param {window.event} AEvt Event de keypress.
      * @param {integer} ALongitud Longitud màxima del nº introduït.
      * @param {integer} APrecission Nombre de decimals a permetre.
      * @param {char} ADecSeparator Separador de decimals a permetre.
      * @alias utils.vf.money_onkeypress
      * @alias money_onkeypress
      */
      money_onkeypress:
      function (ASource /*: Object*/,AEvt /*: Event*/,ALongitud /*: integer*/, APrecission/*: integer*/,
      ADecSeparator /*:char*/) /*:boolean*/
      {
         var lVTypes /*: String[]*/ = 'text textarea'.split(' ');
         var lResult /*:boolean*/ = true;
         
         // Validació del tipus
         if (utils.vf.isTypeOf(ASource,lVTypes))
         {
            // Per compatibilitzar events navegadors
            var lEvt = (window.event) ? window.event : AEvt;
            
            var lKeyCode;
            
            // Per compatibilitzar keycodes de navegadors
            if (document.all)
            {
               lKeyCode = lEvt.keyCode;
            }
            else if (document.getElementById)
            {
               lKeyCode = lEvt.which ;
            }
            //Debugger;
            if ( (lKeyCode > 0) && (lKeyCode !== utils.KEYS.KEY_BACK) )
            {
               var lText /*: string */ = String(ASource.value);
               var lNumPunts /*: integer */= utils.str.numDecSep(lText,ADecSeparator);
               var lNumDecimals /*: integer */ = 0;
               if (lNumPunts>0)
               {
                  lNumDecimals = APrecission;
               }
               
               // Validem entrada de dades
               if ((lNumPunts >0) && (lKeyCode == ADecSeparator.charCodeAt(0) ))
               {
                  // Evitem gestió predeterminada
                  if (lEvt && lEvt.preventDefault)
                  {
                     lEvt.preventDefault();
                     lEvt.returnValue = false;
                  }
                  else
                  {
                     lEvt.returnValue = false ;
                  }
                  lResult =  false;
               }
               else
               {
                  // Només acceptem nombres i la longitud ha de ser com a molt la màxima indicada
                  if ( (lKeyCode !== ADecSeparator.charCodeAt(0)) &&
                     ((!((lKeyCode >=48) && (lKeyCode <=57))) ||
                  (((lText.length - lNumPunts) - lNumDecimals) >= ALongitud)) )
                  {
                     // Evitem gestió predeterminada
                     if (lEvt && lEvt.preventDefault)
                     {
                        lEvt.preventDefault();
                        lEvt.returnValue = false;
                     }
                     else
                     {
                        lEvt.returnValue = false ;
                     }
                     lResult =  false;
                  }
               }
            }
         }
         return lResult;
      },
      /**
      * Comprova que no s'escriguin caràcters no numèrics i la longitud màxima del nº escrit.
      * @param {Object} ASource Origen per evitar usar target o source.
      * @param {window.event} AEvt Event de keypress.
      * @param {Number} ALongitud Longitud màxima del nº introduït.
      * @alias utils.vf.number_onkeypress
      * @alias number_onkeypress
      */
      number_onkeypress:
      function (ASource /*: Object*/,AEvt /*: Event*/,ALongitud /*: Number*/)
      {
         var lVTypes /*: String[]*/ = 'text textarea'.split(' ');
         
         // Validació del tipus
         if (utils.vf.isTypeOf(ASource,lVTypes))
         {
            // Per compatibilitzar events navegadors
            var lEvt = (window.event) ? window.event : AEvt;
            
            var lKeyCode;
            
            // Per compatibilitzar keycodes de navegadors
            if (document.all)
            {
               lKeyCode = lEvt.keyCode;
            }
            else if (document.getElementById)
            {
               lKeyCode = lEvt.which ;
            }
            
            // Només acceptem nombres i la longitud ha de ser com a molt la màxima indicada
            if ( ( (lKeyCode > 0) && (lKeyCode !== 8) ) &&
               ( (!((lKeyCode >=48) && (lKeyCode <=57))) ||
            (String(ASource.value).length >= ALongitud) ) )
            {
               // Evitem gestió predeterminada
               if (lEvt && lEvt.preventDefault)
               {
                  lEvt.preventDefault();
                  lEvt.returnValue = false;
               }
               else
               {
                  lEvt.returnValue = false ;
               }
               return false ;
            }
            else
            {
               return true ;
            }
         }
         else
         {
            return false;
         }
      },
      
      /**
      * Comprova el rang de valors dels objectes indicats.
      * @param {Object} AObj1: object
      * @param {Object} AObj2: object
      * @param {char} [ADecSeparator]= "." char
      * @param {char} [AThousandSep] = "," char
      * @param {number} [ADefaultObj1]=0 number
      * @param {number} [ADefaultObj2]=Infinity number
      */
      comprovarRangFloat :
      function (AObj1/*: object */, AObj2 /*: object*/,
         ADecSeparator/*:char="."*/, AThousandSep/*:char=","*/,
      ADefaultObj1/*:number*/,ADefaultObj2/*:number*/)/*:boolean*/
      {
         var lResult /*:boolean*/ = false;
         try
         {
            if (arguments.length < 6)
            {
               ADefaultObj2 = Infinity;
            }
            if (arguments.length < 5)
            {
               ADefaultObj1 = 0;
            }
            if (arguments.length < 4)
            {
               AThousandSep = ",";
            }
            if (arguments.length < 3)
            {
               ADecSeparator = ".";
            }
            var lText /*: string */ = String(AObj1.value);
            var lValor1 /*:float*/ = utils.str.formatFloat(lText,ADecSeparator,AThousandSep,".","");
            lValor1 = parseFloat(lValor1);
            if (isNaN(lValor1))
            {
               lValor1 = ADefaultObj1;
            }
            lText /*: string */ = String(AObj2.value);
            var lValor2 /*:float*/ = utils.str.formatFloat(lText,ADecSeparator,AThousandSep,".","");
            lValor2 = parseFloat(lValor2);
            if (isNaN(lValor2))
            {
               lValor2 = ADefaultObj2;
            }
            lResult =(lValor1 <= lValor2);
            
         }
         catch (e /*:exception*/)
         {
            window.console.error(e.name + ":" + e.message);
         }
         return lResult;
      },
      /**
      * Comprova que no s'escriguin caràcters no numèrics i la longitud màxima del nº escrit.
      * @param {Object} ASource Origen per evitar usar target o source.
      * @param {window.event} AEvt Event de keypress.
      * @param {Number} ALongitud Longitud màxima del nº introduït.
      * @alias utils.vf.text_onkeypress
      * @alias text_onkeypress
      */
      text_onkeypress:
      function (ASource /*: Object*/,AEvt /*: Event*/,ALongitud /*: Number*/)
      {
         var lVTypes /*: String[]*/ = 'text,textarea'.split(',');
         if (utils.vf.isTypeOf(ASource,lVTypes))
         {
            var lEvt = (window.event) ? window.event : AEvt;
            var lKeyCode;
            // Per compatibilitzar navegadors
            if (document.all)
            {
               lKeyCode = lEvt.keyCode;
            }
            else if (document.getElementById)
            {
               lKeyCode = lEvt.which;
            }
            
            // Només acceptem que la longitud ha de ser com a molt la màxima indicada
            if (String(ASource.value).length >= ALongitud)
            {
               // Evitem gestió predeterminada
               if (lEvt && lEvt.preventDefault)
               {
                  lEvt.preventDefault();
                  lEvt.returnValue = false;
               }
               else
               {
                  lEvt.returnValue = false ;
               }
               return false ;
            }
            else
            {
               return true ;
            }
         }
         else
         {
            return false;
         }
      }
   }
   
};
