Ext.apply(Ext.form.VTypes, {
  complicated_password: function(value, field) {
    var validEntry = value.match(/[0-9!@#\$%\^&\*\(\)\-_=\+]+/i);
    var hasLength = (value.length >= 5);
    return (validEntry && hasLength);
  },
  complicated_passwordText: 'Must be at least 5 characters, containing either a number, or a valid special character (!@#$%^&*()-_=+)',
  phonenumber: function (value, field) {
    //var validEntry = value.match(/^\+?[0-9 ]+$/i);
    var validEntry = value.match(/^\(?\+?\d?\d?\s?[) -]?\s?\b6\+?[0-9 ]+$/i);
    
    if (field.country != undefined && field.country != "sg"){
      validEntry = value.match(/^\(?\+?\d?\d?\s?[) -]?\s?\+?[0-9 ]+$/i);
      this.phonenumberText = 'Phone number should be in this format: 12345678 / (+65) 1234 5678 / +65-12345678';
    }
    
    var hasLength = ((field.minLength == 0 && value.length >= 8) || (field.minLength != 0 && value.length >= field.minLength));
    return (validEntry && hasLength);
  },
  //phonenumberText: 'Must be at least 8 numbers, without containing any special character.'
  phonenumberText: 'Phone number should be started by 6 and in this format: 61234567 / (+65) 6123 4567 / +65-61234567',
  nricformat: function (value, field) {
    var validEntry = value.match(/^(S|F|T|G)\d{7}[A-Z]+$/i);
    return (validEntry);
  },
  nricformatText: 'Must be in valid NRIC format : S1234567A.',  
  hpnumber: function (value, field){
    var validEntry = value.match(/^\(?\+?\d?\d?\s?[) -]?\s?\b[8-9]\+?[0-9 ]+$/i);
    
    if (field.country != undefined && field.country != "sg"){
      validEntry = value.match(/^\(?\+?\d?\d?\s?[) -]?\s?\+?[0-9 ]+$/i);
      this.phonenumberText = 'Phone number should be in this format: 12345678 / (+65) 1234 5678 / +65-12345678';
    }
    
    var hasLength = ((field.minLength == 0 && value.length >= 8) || (field.minLength != 0 && value.length >= field.minLength));
    return (validEntry && hasLength);
  },
  hpnumberText: 'HP number should be started by 8/9 and should be in this format: 91234567 / (+65) 91234567 / +65-91234567'
});

//Customized Ext Js Core overhere: add 1 function to Ext.FormPanel Class and modified Ext.form.Field.markInvalid()
Ext.form.BasicForm.prototype.isValidElseAlert = function () {
  //var oForm = this.getForm();
  var oMsg = {required: '', invalid: ((this.gridMsg)?this.gridMsg:''), count: 0};
  var bReturn = true;
  this.items.each(
    function (B) {
      if (!B.validate()) {
        bReturn = false;
        oMsg.count++;
        if ((B.validMsg == 'This field is required') || (B.validMsg == 'You must select one item in this group') || (B.validMsg == 'You must select at least one item in this group')) {
          var lbl = B.errorLabel||B.fieldLabel;
          if (lbl.length>25) lbl=lbl.substring(0, 25) + '...'
          oMsg.required += '<u>' + lbl + '</u>, '; 
        } else {
          var lbl = B.errorLabel||B.fieldLabel;
          if (lbl.length>25) lbl=lbl.substring(0, 25) + '...'
          oMsg.invalid += ((oMsg.invalid=='')?'<tr><td>':'') + '<u>' + lbl + '</u> -> ' + B.validMsg + '</td></tr><tr><td>';
        }
      }
    }
  );
  var sMsgDisplay = '';
  if (oMsg.required != '' || oMsg.invalid != '') 
    sMsgDisplay = '<table border="0" cellpadding="0" cellspacing="0">';
  if (oMsg.required != '') {
    oMsg.required=oMsg.required.substring(0, oMsg.required.length - 2);
    sMsgDisplay += '<tr><td><b>The following field(s) are required</b></td></tr><tr><td>' + oMsg.required + '</td></tr>';
    sMsgDisplay += '<tr><td>&nbsp;</td></tr>';
  }
  if (oMsg.invalid != '') 
    sMsgDisplay += '<tr><td><b>The following field(s) are invalid</b></td></tr><tr><td>' + oMsg.invalid + '</td></tr>';
  if (sMsgDisplay != '') {
    sMsgDisplay += '</table>';
    ww.msgbox.show('Form Validation', sMsgDisplay, Ext.Msg.WARNING, Ext.Msg.OK);
    if (this.gridMsg) this.gridMsg = '';
    bReturn = false;
  }
  return bReturn;
}

Ext.override(Ext.form.Field, {
  markInvalid: function(C) {
    if(!this.rendered||this.preventMark){return}
    this.el.addClass(this.invalidClass);
    C=C||this.invalidText;
    //Customize core Begin
    this.validMsg=C;
    if (this.specialGroup == 'radio') {
      var tEl = this.el.dom; //Ext.DomQuery.selectNode(" > div", this.el.dom);
      tEl.style.border = '1px solid #dd7870';
      if (this.gtip) {
        this.gtip.html = C;
        this.gtip.enable();
      } else this.gtip = new Ext.ToolTip({target: tEl.id, html: C, cls:'x-form-invalid-tip'});
    } else {
      switch(this.msgTarget){
        case "qtip":
          this.el.dom.qtip=C;
          this.el.dom.qclass="x-form-invalid-tip";
          if(Ext.QuickTips){Ext.QuickTips.enable()}
          break;
        case"title":
          this.el.dom.title=C;
          break;
        case"under":
          if(!this.errorEl) {
            var B=this.getErrorCt();
            if(!B){this.el.dom.title=C;break}
            this.errorEl=B.createChild({cls:"x-form-invalid-msg"});
            this.errorEl.setWidth(B.getWidth(true)-20);
          }
          this.errorEl.update(C);
          Ext.form.Field.msgFx[this.msgFx].show(this.errorEl,this);
          break;
        case"side":
          if(!this.errorIcon) {
            var B=this.getErrorCt();
            if(!B){this.el.dom.title=C;break}
            this.errorIcon=B.createChild({cls:"x-form-invalid-icon"});
          }
          this.alignErrorIcon();
          this.errorIcon.dom.qtip=C;
          this.errorIcon.dom.qclass="x-form-invalid-tip";
          this.errorIcon.show();
          this.on("resize",this.alignErrorIcon,this);
          break;
        default:
          var A=Ext.getDom(this.msgTarget);
          A.innerHTML=C;
          A.style.display=this.msgDisplay;
          break;
      }
    }
    //Customize core End
    this.fireEvent("invalid",this,C);
  },
  clearInvalid: function () {
    if (!this.rendered || this.preventMark) {return;}
    this.el.removeClass(this.invalidClass);
    if (this.specialGroup == 'radio') {
      var tEl = this.el.dom; //Ext.DomQuery.selectNode(" > div", this.el.dom);
      tEl.style.border = '';
      if (this.gtip) this.gtip.disable();
    } else {
      switch (this.msgTarget) {
        case "qtip":
          this.el.dom.qtip = "";
          break;
        case "title":
          this.el.dom.title = "";
          break;
        case "under":
          if (this.errorEl) {Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);}
          break;
        case "side":
          if (this.errorIcon) {
            this.errorIcon.dom.qtip = "";
            this.errorIcon.hide();
            this.un("resize", this.alignErrorIcon, this);
          }
          break;
        default:
          var A = Ext.getDom(this.msgTarget);
          A.innerHTML = "";
          A.style.display = "none";
          break;
      }
    }
    this.fireEvent("valid", this);
  }
});
Ext.override(Ext.form.Checkbox, {
  onClick: function(A) {
    if (!this.disabled && !this.readOnly) {
      this.toggleValue();
      Ext.getCmp(this.parentid).clearInvalid();
    }
    A.stopEvent();
  }
});
Ext.form.RadioGroup = Ext.extend(Ext.form.RadioGroup, {specialGroup: 'radio'});Ext.reg("radiogroup",Ext.form.RadioGroup);