function FormHandler() {
  this.alertText = "";
  this.elements = {};
  this.forms = {};
}

FormHandler.prototype.isAlpha = function(charCode) {
  return ((charCode>64 && charCode<91) || (charCode>96 && charCode<123));
}

FormHandler.prototype.isAlphaNumeric = function(str) {
  if(this.isEmpty(str)) return false;
  for(var i=0; i<str.length; i++) {
    var charCode = str.charCodeAt(i);
    if(!this.isAlpha(charCode) && !this.isDigit(charCode)) return false;
  }
  return true;
}

FormHandler.prototype.isAlphaNumericExtended = function(str) {
  if(this.isEmpty(str)) return false;
  for(var i=0; i<str.length; i++) {
    var charCode = str.charCodeAt(i);
    if(!this.isAlpha(charCode) && !this.isDigit(charCode) && !this.isControlChar(charCode) && !this.isUnderscore(charCode) && !this.isDot(charCode) && !this.isTab(charCode)) return false;
  }
  return true;
}

FormHandler.prototype.isComma = function(charCode) {
  return (charCode==44);
}

FormHandler.prototype.isControlChar = function(charCode) {
  return (charCode==8 || (charCode>16 && charCode<21));
}

FormHandler.prototype.isDigit = function(charCode) {
  return (charCode>=48 && charCode<=57);
}

FormHandler.prototype.isDot = function(charCode) {
  return (charCode==46);
}

FormHandler.prototype.isEmail = function(str) {
  for(var i=0; i<str.length; i++) {
    if(str.charAt(i)=="@") return true;
  }
  return false;
}

FormHandler.prototype.isEmpty = function(str) {
  return (str==null || str.length==0);
}

FormHandler.prototype.isEnter = function(charCode) {
  return (charCode==13);
}

FormHandler.prototype.isHetu = function(str) {
  var checkArr = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y");
  var beginVal = str.substr(0,6);
  var endVal = str.substr(7,3);
  var checkVal = str.substr(10,1).toUpperCase();
  var value = ((beginVal+endVal)%31);
  var plusa = beginVal+endVal;
  if(checkArr[value]==checkVal) return true;
  else return false;
}

FormHandler.prototype.isInteger = function(str) {
  if(this.isEmpty(str)) return false;
  for(var i=0; i<str.length; i++) {
    if(!this.isDigit(str.charCodeAt(i))) return false;
  }
  return true;
}

FormHandler.prototype.isNewSitename = function(str) {
  return true;
}

FormHandler.prototype.isNewUsername = function(str) {
  return true;
}

FormHandler.prototype.isNumeric = function(str) {
  if(this.isEmpty(str)) return false;
  var decimalSeparatorCount = 0;
  for(var i=0; i<str.length; i++) {
    if(!this.isDigit(str.charCodeAt(i))) {
      if(this.isDot(str.charCodeAt(i)) || this.isComma(str.charCodeAt(i))) {
        decimalSeparatorCount++;
        if(decimalSeparatorCount>1) return false;
      } else {
        return false;
      }
    }
  }
  return true;
}

FormHandler.prototype.isSpace = function(charCode) {
  return (charCode==32);
}

FormHandler.prototype.isTab = function(charCode) {
  return (charCode==9);
}

FormHandler.prototype.isUnderscore = function(charCode) {
  return (charCode==95);
}

FormHandler.prototype.registerForm = function(formId,formArr) {
  this.forms[formId] = formArr;
  this.forms[formId].elements = new Array();

  return true;
}

FormHandler.prototype.registerInputElement = function(elementArr) {
  var id = "";
  if(elementArr.id && elementArr.id!="") {
    id = elementArr.id;
  } else if(elementArr.formId && elementArr.name && elementArr.formId!="" && elementArr.name!="") {
    id = elementArr.formId+"_"+elementArr.name;
  }
  if(id=="") return false;

  if(elementArr.formId!="") {
    if(typeof(this.forms[elementArr.formId])=="undefined") {
      this.forms[elementArr.formId] = {elements: new Array()};
    }
    this.forms[elementArr.formId].elements.push(id);
  }
  this.elements[id] = elementArr;

  return true;
}

FormHandler.prototype.validateAndSubmitForm = function(formId) {
  if(this.validateForm(formId)) {
    document.getElementById(formId).submit();
  }
  return true;
}

FormHandler.prototype.validateInputObject = function(inputObj, eventType) {
  var pass = false;
  var inputArr;
  if(this.elements[inputObj.id]) {
    inputArr = this.elements[inputObj.id];
  } else if(this.elements[inputObj.form.id+"_"+inputObj.name]) {
    inputArr = this.elements[inputObj.form.id+"_"+inputObj.name];
  } else {
    //the input element is not registered so no validation is done => pass
    return true;
  }
  if(inputArr.alertText) {
    inputObj.alertText = inputArr.alertText;
  }

  //check if empty value is allowed and if it is empty
  if(inputArr.requiredType!="checked" && inputArr.emptyAllowed && this.isEmpty(inputObj.value)) {
    pass = true;
  } else {
    switch(inputArr.requiredType) {
      case "checked":
        pass = inputObj.checked;
        break;
      case "email":
        pass = this.isEmail(inputObj.value);
        break;
      case "hetu":
        pass = this.isHetu(inputObj.value);
        break;
      case "integer":
        pass = this.isInteger(inputObj.value);
        break;
      case "int":
        pass = this.isNumeric(inputObj.value);
        break;
      case "newsitename":
        pass = this.isNewSitename(inputObj.value);
        break;
      case "newusername":
        pass = this.isNewUsername(inputObj.value);
        break;
      case "string":
        pass = !this.isEmpty(inputObj.value);
        break;
    }
  }

  if(pass) {
    if(eventType=="change") {
      if(typeof(inputArr.onChangeValidatePass)=="function") {
        inputObj.onChangeValidatePass = inputArr.onChangeValidatePass;
        inputObj.onChangeValidatePass();
      }
    } else if(eventType=="submit") {
      if(typeof(inputArr.onSubmitValidatePass)=="function") {
        inputObj.onSubmitValidatePass = inputArr.onSubmitValidatePass;
        inputObj.onSubmitValidatePass();
      }
    }
  } else {
    if(eventType=="change") {
      if(typeof(inputArr.onChangeValidateFail)=="function") {
        inputObj.onChangeValidateFail = inputArr.onChangeValidateFail;
        inputObj.onChangeValidateFail();
      }
    } else if(eventType=="submit") {
      if(inputArr.noDefaultAlert==false && inputObj.alertText) {
        this.alertText += inputObj.alertText + "\n";
      }
      if(typeof(inputArr.onSubmitValidateFail)=="function") {
        inputObj.onSubmitValidateFail = inputArr.onSubmitValidateFail;
        inputObj.onSubmitValidateFail();
      }
    }
  }
  return pass;
}

FormHandler.prototype.validateForm = function(formId) {
  var formArr = this.forms[formId];
  if(!formArr) {
    //the form is not registered so no validation is done => pass
    return true;
  }
  var formObj = document.getElementById(formId);
  var emptyValues = false;
  var pass = true;
  this.failedElements = new Array();
  this.alertText = "";
  if(formArr.alertText) {
    formObj.alertText = formArr.alertText;
  }

  if(this.forms[formId].elements) {
    for(var i=0; i<this.forms[formId].elements.length; i++) {
      var inputArr = this.elements[this.forms[formId].elements[i]];
      var inputObj = inputArr.getObject();
      if(!this.validateInputObject(inputObj,"submit")) {
        this.failedElements.push(inputObj);
        if(pass) pass = false;
      }
      //for backwards comaptibility add default alert text for empty values
      if(inputArr.requiredType!="checked" && inputArr.emptyAllowed==false && this.isEmpty(inputObj.value)) {
        if(emptyValues==false) emptyValues = true;
      }
    }

  }
  if(emptyValues && formArr.noDefaultAlert==false) {
    this.alertText = formObj.alertText + "\n" + this.alertText;
  }

  if(!pass) {
    if(typeof(formArr.onSubmitValidateFail)=="function") {
      formObj.onSubmitValidateFail = formArr.onSubmitValidateFail;
      formObj.onSubmitValidateFail();
    }
    if(this.alertText!="") {
      alert(this.alertText);
    }
  }

  return pass;
}

var FormHandler = new FormHandler();

