/* ****************************************************************************
Copyright 2007,
Todos los derechos Reservados
CM.COM E.U.
cmhenao@epm.met.co

El uso sin solicitud espresa a la compañia de esta libreria es una clara
violación a la propiedad intelectual y los derechos de autor.
Prohibida su distribucion y/o uso sin el permiso explicito de cm.com
**************************************************************************** */

/* ****************************************************************************
Autor: Jhon Alejandro Ramirez Velez
       Desarrollador
       Progress - WebSpeed
       jhalrave@epm.net.co
**************************************************************************** */

function cForm(){
  var self = this;
  
  this.checked    = false;
  this.messages   = "";

  this.serialize           = _FormSerialize;
  this.disable             = _disable;
  this.enable              = _enable;
  this.fieldHide           = _FieldHide;
  this.fieldShow           = _FieldShow;      
  this.validate            = _FormValidate;
  this.FieldKeyPress       = _FieldKeyPress;
  this.FieldChange         = _FieldChange;
  this.activate            = _activate; 
  this.deactivate          = _deactivate;
  this.clear               = _clear;
  this.isEmpty             = _isEmpty;
  this.isFull              = _isFull;
  this.get                 = _get;
  this.showHelp            = _showHelp;
  this.hideHelp            = _hideHelp;
  this.setProperty         = _setProperty;
  
  this.objects             = {};
  
  var oField = null;
 
  debugStartGroup("cForm: Initializating " + this.name);
  if(self.elements){
    for(var j = 0; j < self.elements.length; j++){
      oField = self.elements[j];
      self.failed = false;
      oField.validationEvent = null;         
      if(oField.object != undefined && oField.object != null){
        if(self.objects[oField.object] == undefined)
          self.objects[oField.object] = [];
        self.objects[oField.object].push(oField);
      }
      if(oField.groups != undefined && oField.groups != null){
        aGroups = oField.groups.split(","); 
        for(var h = 0; h < aGroups.length; h++){
          if(self.objects[aGroups[h]] == undefined){
            debugMessage("Creando Grupo " + aGroups[h]);
            self.objects[aGroups[h]] = [];
          }            
          debugMessage("Agregando " + oField.name + " al Grupo " + aGroups[h]);
          self.objects[aGroups[h]].push(oField);
        }      
      }
            
      if(oField.extend){
        var oFnc = eval(oField.extend);
        oField[oField.extend] = oFnc;
        oField[oField.extend]();
        oField.attachEvent("onfocus", self.FieldChange);
        oField.attachEvent("onblur", self.FieldChange);            
        //oField.attachEvent("onfocus", oField.applyMask);
        //oField.attachEvent("onblur", oField.applyMask);            
        oField.failed = false;
        oField.validationEvent = self.FieldChange;
        debugMessage("cForm: Binding: " + oField.name);
      }else{
        switch(oField.type){
          case "text":
          case "textarea":
          case "hidden":
          case "password":      
            if(oField.attachEvent){
              oField.attachEvent("onkeypress", self.FieldKeyPress);
              oField.attachEvent("onfocus", self.FieldChange);
              oField.attachEvent("onblur", self.FieldChange);            
            }else{
              if(oField.addEventListener){
                oField.addEventListener("onkeypress", self.FieldKeyPress, true);
                oField.addEventListener("onfocus", self.FieldChange, true);
                oField.addEventListener("onblur", self.FieldChange, true);              
              }          
            }
            oField.failed = false;
            oField.validationEvent = self.FieldChange;
            debugMessage("cForm: Binding: " + oField.name);
          break;
          
          case "button":
          case "submit":
          break;
          
          case "select-one":
          default:
            //if(oField.validate != undefined && oField.validate != "false" && oField.validate != "no"){
              oField.attachEvent("onchange", self.FieldChange);
              oField.failed = false;
              oField.validationEvent = self.FieldChange;
              debugMessage("cForm: Binding: " + oField.name);
            //}
          break;          
        }
      
      }
      
      if(oField.help){
        var oHelp = document.getElementById(oField.help);
        if(oHelp){
          oField.ayuda = oHelp;
          if(oField.helpos == undefined){
            oField.helpos = oHelp.helpos;
          }
          oHelp.style.display = "none";
          oField.attachEvent('onfocus', self.showHelp);
          oField.attachEvent('onblur', self.hideHelp);
        }
      }else{
        if(oField.name != undefined && oField.name != ""){
          var oHelp = document.getElementById("Ayuda." + self.name + "." + oField.name);
          if(oHelp){
            if(oField.helpos == undefined){
              oField.helpos = oHelp.helpos;
            }
            oField.ayuda = oHelp;
            oHelp.style.display = "none";
            oField.attachEvent('onfocus', self.showHelp);
            oField.attachEvent('onblur', self.hideHelp);
          }
        }
      }      
    }
  }
  debugStopGroup();
  
  function _FormValidate(){
    self.messages = "";
    self.failed = false;  
    for(var i = 0; i < self.elements.length; i++){
      var oField = self.elements[i];
      if(oField.validationEvent){
        window.status = "Validando " + oField.caption + " ...";    
        oField.validationEvent(self.elements[i]);             
        window.status = oField.caption + " validado";    
      }      
      if(oField.ayuda){
        oField.ayuda.style.display = "none";
      }
    }
  }

  function _FieldKeyPress(oInput){
    if(window.event.srcElement){
      var oInput = window.event.srcElement;
    }
   
    cChar = window.event.keyCode;
    if (cChar == 13) {
      window.event.returnValue = true;
      return true;
    } 
  
    if (oInput.filter){      
      sFilters = oInput.filter;
      if(String.fromCharCode(cChar).search(sFilters)){
        window.event.returnValue = false;
        return false;
      }
    }  
    window.event.returnValue = true;
    return true;
  }

  function _FieldChange(oInput){
    if(oInput != undefined && oInput != null){
      if(oInput.srcElement)
        oInput = oInput.srcElement; 
    }else
      if(window.event.srcElement)
        var oInput = window.event.srcElement;
      
    if(oInput == undefined || oInput == null){
      return;
    }
          
    if(oInput.getValue)
      var sValue = oInput.getValue();
    else
      var sValue = oInput.value;
        
    var sClassName = oInput.className.replace(/_wrong/g,'');
    
    oInput.mandatory = oInput.getAttribute('mandatory');
    if (oInput.mandatory == "yes" && sValue.replace(/\s/g,"") == ""){
      oInput.className = sClassName + "_wrong";
      oInput.failed = true;
      oInput.title = "Es Obligatorio";
      if(oInput.form){
        oInput.form.failed = true || oInput.form.failed;
        oInput.caption = oInput.getAttribute('caption'); 
        oInput.form.messages += oInput.caption + " es obligatorio\n";
      }
      return;  
    }
      
    if (oInput.validation && sValue != ""){
      if(sValue.search(oInput.validation)){
        oInput.className = sClassName + "_wrong";
        oInput.failed = true;
        oInput.title = "Es Incorrecto";
        if(oInput.form){
          oInput.form.failed = true || oInput.form.failed;
          oInput.form.messages += oInput.caption + " es incorrecto\n";
        }
        return;
      }
    }
    if (oInput.type != 'submit'){ 
      oInput.className = sClassName;      
    }
    oInput.failed = false;
    oInput.title = "";
    if(oInput.form){
      oInput.form.failed = false || oInput.form.failed;
    }
  }  
  
  function _enable(){
    for(var i = 0; i < self.elements.length; i++){
      self.elements[i].disabled = false;
    }
  }
  
  function _disable(){
    for(var i = 0; i < self.elements.length; i++){
      if (self.elements[i].disableStatus == undefined) {
        self.elements[i].disableStatus = true;
      }
      self.elements[i].disabled = self.elements[i].disableStatus;
    }
  }
  
  function _activate(sObject){
    if(sObject == undefined || sObject == null){
      var sObject = "";
    }
    if(sObject != ""){
      if(self.objects[sObject] == undefined || self.objects[sObject] == null){
        return;
      }
      for(var i = 0; i < self.objects[sObject].length; i++){
        self.objects[sObject][i].readOnly = false;
      }      
    }else{
      for(var i = 0; i < self.elements.length; i++){
        self.elements[i].readOnly = false;
      }
    }    
  }
  
  function _deactivate(sObject){
    if(sObject == undefined || sObject == null){
      var sObject = "";
    }
    if(sObject != ""){
      if(self.objects[sObject] == undefined || self.objects[sObject] == null){
        return;
      }
      for(var i = 0; i < self.objects[sObject].length; i++){
        self.objects[sObject][i].readOnly = true;
      }      
    }else{
      for(var i = 0; i < self.elements.length; i++){
        self.elements[i].readOnly = true;
      }
    }    
  }
  
  function _clear(){
    for(var i = 0; i < self.elements.length; i++){
      var oField = self.elements[i];
      switch(oField.type){
        case "text":
        case "textarea":
        case "hidden":
        case "password":      
          oField.className = 'input';
          oField.failed = false;
          oField.value = "";
        break;
        
        case "button":
        break;
        
        case "select-one":        
          oField.failed = false;
          oField.className = 'select';
          oField.value = "";          
        break;          
      }
    }
  }
  
  function _isEmpty(sFields){
    var lResult = true;
    var aFields = sFields.split(',');
    for(var iFields = 0; iFields < aFields.length; iFields++){
      var sField = aFields[iFields]; 
      var oField = self.elements[sField];
      if(oField){
        if(oField.value.replace(/\s/g,"") != ""){
          lResult = false;
          return;  
        }
      }
    }
    return lResult;
  }
  
  function _isFull(sFields){
    var lResult = true;
    var aFields = sFields.split(',');
    for(var iFields = 0; iFields < aFields.length; iFields++){
      var sField = aFields[iFields]; 
      var oField = self.elements[sField];
      if(oField){
        if(oField.value.replace(/\s/g,"") == ""){
          lResult = false;  
          return;
        }
      }
    }
    return lResult;
  }
  
  function _get(oObject, lExpando){
    if(lExpando == undefined || lExpando == null){
      var lExpando = false;
    }
    if(oObject == undefined || oObject == null){
      var oObject = {};
      lExpando = true;
    }
    
    for(var iElement = 0; iElement < self.elements.length; iElement++){
      var oElement = self.elements[iElement];
      
      var sObject = "";
      var sName = oElement.name;
      if(sName == undefined || sName == null || sName == "") continue;
      if(oElement.type == "button" || oElement.type == "submit") continue;
      debugMessage("Getting " + sName + ":" + oElement.value);
      if(oElement.object){
        sObject = oElement.object; 
        debugMessage("Getting " + sObject + "." + sName + ":" + oElement.value);
        window.status = (oObject[sObject] == undefined || oObject[sObject] == null);
        if(oObject[sObject] == undefined || oObject[sObject] == null){
          if(!lExpando) continue;
          oObject[sObject] = {};
        }
      }
      if(sObject == ""){
        if(oObject[sName] == undefined || oObject[sName] == null){
          if(!lExpando) continue;
        }
      }else{
        if(oObject[sObject][sName] == undefined || oObject[sObject][sName] == null){
          if(!lExpando) continue;
        }
      }
      
      switch(oElement.type){
        case "checkbox":
          if(sObject == "")
            oObject[sName] = oElement.checked;
          else
            oObject[sObject][sName] = oElement.checked;
        break;
        case "radio":
          if(oElement.checked){
            if(sObject == "")
              oObject[sName] = oElement.value;
            else
              oObject[sObject][sName] = oElement.value;
          }
        break;
        default:
          if(sObject == "")
            if(oElement.getValue)
              oObject[sName] = oElement.getValue();
            else
              oObject[sName] = oElement.value;
          else
            if(oElement.getValue)
              oObject[sObject][sName] = oElement.getValue();
            else          
              oObject[sObject][sName] = oElement.value;
        break;
      }       
    }
    return oObject;
  }
  
  function _showHelp(){
    var oField = window.event.srcElement;
    var oHelp = oField.ayuda;
    var oPos = oField.helpos;
    if(oPos == undefined || oPos == null){
      var oPos = "bottom";
    }
    if(oHelp){
      var iPosV = getOffSetTop(oField) + oField.offsetHeight + 4;
      var iPosH = getOffSetLeft(oField) + 2;
      oHelp.style.display = "";
      window.status = oHelp.offsetWidth;
      switch(oPos){
        case "top":
          iPosV = getOffSetTop(oField) - oHelp.offsetHeight;
        break;        
        case "left":
          iPosV = getOffSetTop(oField);
          iPosH = getOffSetLeft(oField) - oHelp.offsetWidth - 2;
        break;
        case "right":
          iPosV = getOffSetTop(oField);
          iPosH = getOffSetLeft(oField) + oField.offsetWidth + 2;
        break;
      }
      oHelp.style.top = iPosV;
      oHelp.style.left = iPosH;
      
    }
    oHelp = null;
    oField = null; 
  }
  
  function _hideHelp(){
    var oField = window.event.srcElement;
    var oHelp = oField.ayuda;
    if(oHelp){
      oHelp.style.display = "none";
    }
    oHelp = null;
    oField = null; 
  }
  
  function _setProperty(sObject, sProperty, sValue){
    if(sObject == undefined || sObject == null){
      var sObject = "";
    }
    if(sObject != ""){
      if(self.objects[sObject] == undefined || self.objects[sObject] == null){
        return;
      }
      for(var i = 0; i < self.objects[sObject].length; i++){
        debugMessage("Setting " + self.objects[sObject][i].name + " Property " + sProperty + " value " + sValue);
        self.objects[sObject][i][sProperty] = sValue;
      }      
    }else{
      for(var i = 0; i < self.elements.length; i++){
        self.elements[i][sProperty] = sValue;
      }
    }    
  }
}

function cField(){
   var self =       this;
   
   this.props = {};
   /* input chars, empty for all chars, default all chars */
   this.props['ic'] = "";
   /* input mask, default no mask */
   this.props['im'] = "";
   /* hide mask characters*/
   this.props['hmc'] = "";
   /* mask char, default space */
   this.props['mc'] = " ";
   /* default position in mask */
   this.props['dp'] = "1";
   /* validation string, default none */
   this.props['vs'] = "";
   /* Mandatory field */
   this.props['mf'] = "no";
   /* Field Caption */
   this.props['fc'] = "";
   /* Read Only */
   this.props['ro'] = "no";
   
   this.init          = _init;
   this.getValue      = _getValue;
   this.setValue      = _setValue;
   this.applyMask     = _applyMask;
   this.capture       = _capture;
   this.keydown       = _keydown;
   this.keypress      = _keypress; 
   
   self.init();
   function _init(){
     if(self['fp'])
       self.props = cProps(self['fp'], self.props);
     else 
       return;
     var cMask        = self.props['im'];
     self.mandatory   = self.props['mf'];
     self.validation  = self.props['vs'];
     self.caption     = self.props['fc'];
     self.readOnly    = self.props['ro'];
     self.FirstEditablePosition = cMask.length - 1;
     self.LastEditablePosition = 0;
     self.mask = [];
     for(var iChar = 0; iChar < cMask.length; iChar++){
       var sChar = cMask.charAt(iChar);
       var oChar = new cInputMaskChar();
       oChar.character = sChar;
       oChar.position = iChar;
       if(sChar == self.props['mc']){
         oChar.editable = true;
         if(self.FirstEditablePosition > iChar)
           self.FirstEditablePosition = iChar;    
         if(self.LastEditablePosition < iChar)
           self.LastEditablePosition = iChar;    
       }
       self.mask.push(oChar); 
     }
     self.setValue(self.value);
     self.capture('last');
     self.attachEvent('onkeydown', self.keydown);
     self.attachEvent('onkeypress', self.keypress);
   }
   
   function _getValue(){
     var sValue = "";
     for(var iPos = 0; iPos < self.mask.length; iPos++){
       var oChar = self.mask[iPos];
       if(oChar.editable){
         if(oChar.character != self.props['mc'])
           sValue += oChar.character;
       } 
     }
     return sValue;
   }
   
   function _setValue(sValue){
     sValue = sValue.toString();
     var itChar = sValue.length;
     for(var iChar = self.mask.length; iChar > 0; iChar--){
       var oChar = self.mask[iChar - 1];
       if(oChar.editable){
         if (itChar > 0){
           oChar.character = sValue.charAt(--itChar);
         }               
         else
           oChar.character = self.props['mc']; 
       }
     }
     self.applyMask();
   }
   
   function _applyMask(){
     var sValue = self.getValue();
     var s1 = "";
     var itChar = sValue.length;
     for(var iChar = self.mask.length; iChar > 0; iChar--){
       var oChar = self.mask[iChar - 1];
       if(oChar.editable){
         if (itChar > 0){
           oChar.character = sValue.charAt(--itChar);
         }               
         else
           oChar.character = self.props['mc'];
         cChar = oChar.character; 
       }else{
         if (itChar > 0){
           cChar = oChar.character;
         }else{
           if (self.props['hmc'].indexOf(oChar.character) > -1){
             cChar = " ";
           }else{
             cChar = oChar.character;
           }
         }
       }            
       s1 = cChar + s1;
     }
     self.value = s1;
   }
   
   function _capture(sCapture){
     if(sCapture == undefined || sCapture == null){
       sCapture = "";
     }
     switch(sCapture.toString().toLowerCase()){
       case "first":
         for(iPos = self.mask.length; iPos > 0; iPos--){
           var oChar = self.mask[iPos - 1];
           if(oChar.editable && oChar.character == self.props['mc']) break; 
         }
         _setCapture(iPos - 1);
       break;
       case "last":
         _setCapture(self.LastEditablePosition + 1);
       break;
       case "next":
         _setCapture(self.currentpos + 1);
       break;
       case "prev":
         if(self.currentpos > self.FirstEditablePosition){
           _setCapture(self.currentpos - 1);
         }
       break;
       case "current":
         _setCapture(self.currentpos);
       break;
       case "":
        _setCapture(self.props['dp']);
       break;
       default:
         _setCapture(sCapture)
       break;
     }
   }
   
  function _setCapture(iPos){
    if (iPos <= self.FirstEditablePosition) iPos = self.FirstEditablePosition;
    if (iPos > self.LastEditablePosition) iPos = self.LastEditablePosition;
    var oRange = self.createTextRange();
    oRange.collapse();
    oRange.moveStart("character", iPos);
    oRange.moveEnd("character", 1);
    oRange.select();       
    oRange = null;
    self.currentpos = iPos;
  }
   
  function _getCapture(){
    return document.selection.createRange().text;         
  }
   
  function _keydown(){
    var iChar   = window.event.keyCode;
    if(self.props['ro'] == "yes"){
      return;
    }
    switch(iChar){
      case 38:
      case 37:
        self.capture('prev');
        window.event.returnValue = false;          
      break;
      case 39:
      case 40:
        self.capture('next');
        window.event.returnValue = false;
      break;
      case 36:
      case 33:
        self.capture('first');
        window.event.returnValue = false;
      break;
      case 35:
      case 34:
        self.capture('last');
        window.event.returnValue = false;
      break;
      case 8:
        var oChar = self.mask[self.currentpos];
        if(oChar.editable)
          oChar.character = self.props['mc'];
        self.applyMask();
        self.fireEvent('onchange');
        self.capture('current');
        window.event.returnValue = false;
      break;
      case 46:
        var oChar = self.mask[self.currentpos];
        if(oChar.editable)
          oChar.character = self.props['mc'];
        self.applyMask();
        self.fireEvent('onchange');
        self.capture(self.currentpos + 1);
        window.event.returnValue = false;
      break;
    }      
  }
  
  function _keypress(){
    var iChar   = window.event.keyCode;
    if(self.props['ro'] == "yes"){
      return;
    }
    if(self.props['ic'] != ""){
      if(String.fromCharCode(iChar).search(self.props['ic'])){
        window.event.returnValue = false;
        return false;
      }
    }
    cChar = String.fromCharCode(iChar);

    for(var i = self.currentpos + 1; i > 0; i--){
      var oChar = self.mask[i - 1];
      if(oChar.editable){
        var tChar = oChar.character;
        oChar.character = cChar;
        cChar = tChar;
      }
    }
    self.applyMask();
    self.fireEvent('onchange');
    self.capture('current');    
    window.event.returnValue = false;
  }
   
}

function cProps(sProps, aProps){
  if(aProps == undefined || aProps == null){
    var aProps = {};
  }      
  var sTemp = "";
  for(var iChar = 0; iChar < sProps.length; iChar++){
    var sChar = sProps.charAt(iChar);
    switch(sChar){
      /* scape char */
      case "\\":
        sChar = sProps.charAt(++iChar);
        sTemp += sChar;
      break;
      /* prop delimiter */
      case "=":
        sValue = sTemp;
        aProps[sValue] = "";
        sTemp = "";
      break;
      /* props delimiter */
      case ";":
        aProps[sValue] = sTemp;
        sTemp = "";
      break;
      default:
        sTemp += sChar;
      break;
    }
  }
  return aProps;
}

function cInputMaskChar(){
  this.editable     = false;
  this.position     = 0;
  this.character    = "";
  this.hidden       = false;
  this.IsFirst      = false;
  this.IsLast       = false;
              
}


