/**
*   form.js
*   form validation purpose
*		@author Olaf Höft <olaf@edotz.de>
*/

/*==========================================================================
* script wide neede variables
* ==========================================================================*/
//debug flag
var debug = true;
if(debug) {
	window.onerror = throwError;
}
function throwError(message,file,row) {
	error = "Fehlermeldung:\n"+message+"\n"+file+"\n"+row;
	alert(window.error);
	return true;
}
//different regular expressions
//see regExpr();
var num = /(\d)/;
var alpha = /[a-z_üöä\s\.-]/i;
var noalpha = /[^a-z_üöä\s\.-]/i;
var email = /^([_a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+\.([a-zA-Z]{2,3})$/;

//assign here get parameter in order to mark validation by javascript
var strValidated = "validate=1"
//default string for no value in elements
var strNoValue = "Bitte ausfüllen";
//assign here different javascript tags
var jscriptWrap = "<script language=\"JavaScript\">\n<!--:jscript://-->\n</script>\n";
//config array will be filled dynamically
//se setFormularConfig();
var elements = new Array();
var errorMsg = new Array();
var errorType = new Array();
var noValue = new Array();
var userFunc = new Array();

//standard error messages for above defined regualr expressions
errorMsg['alpha']= 'Keine Zahlen + Sonderzeichen';
errorMsg['alphanum'] = 'Namen und Nr. bitte angeben';
errorMsg['num']= 'Nur Zahlen erlaubt';
errorMsg['email']= 'kein gültige email Adresse';
errorMsg['date']= 'tt.mm.jjjj';

/**
*   creates new config array for different config fields
*   @param	string	config field eg. elements,errorMsg
*		@param	string 	form element name
*		@retun 	void
*/
function setNewConfigArray(conf,formName){
  eval(''+conf+'["'+formName+'"] = new Array();');
}
/**
*   sets dynamically form config made in script
*   @param	string	form element name
*		@param	array 	containing different configurations
*   @return boolean true on success, false on failure
*/
function setFormularConfig(formName,arrConf){
  var conf, tmp, field, arrFields, arrSplit, strUserFunc;
  if(!arrConf["elements"]){
		throwDebugMessage("config array is not specified");
    return false;
  }
  for(conf in arrConf){
    setNewConfigArray(conf,formName);
    //string operation assures string var
    tmp = arrConf[conf]+"";
    arrFields = tmp.split("#");
    for(var i=0;i<arrFields.length;i++){
      //string operation assures string var
      tmp = arrFields[i]+"";
      arrSplit = tmp.split(":");
      if(arrSplit.length < 2) {
        throwDebugMessage("wrong config statement "+tmp);
        continue;
      }
      field = arrSplit[0];
      switch(conf){
     		case "elements":
          if(arrSplit.length <= 2){
            elements[formName][field] = arrSplit[1];
          }else {
          	arrSplit[0]="";
            var strConf = arrSplit.join(":");
          	elements[formName][field] = strConf.substr(1,strConf.length);
          }
        break;
        case "errorMsg":
          errorMsg[formName][field] = arrSplit[1];
        break;
        case "errorType":
        	errorType[formName][field] = arrSplit[1];
        break;
        case "noValue":
        	noValue[formName][field] = arrSplit[1];
        break;
        case "userFunc":
          userFunc[formName][field]= 1;
          strUserFunc = "function "+field+"() {\n";
          for(var j=1;j<arrSplit.length;j++){
             strUserFunc += arrSplit[j]+";\n";
          }
          strUserFunc += "}";
          arrSplit = jscriptWrap.split(":");
          arrSplit[1] = strUserFunc;
          document.write(arrSplit.join("\n"));
        break;
    	}//switch
    }//for
  }//for
  return true;
}

/**
*   process no value handling
*   @param	string  element type eg. input,radio
*		@param	string  form element name
*   @return mixed
*/
function throwErrorMessage(type,fieldObj,msg){
  if(!msg)return;
  switch(errorType[formName][type]){
		case "value":
      setValue(type,fieldObj,msg);
      setColor(type,fieldObj,"#FF0000");
		break;
    case "alert":
      alert(msg);
    break;
    default:
      if(debug){
      	throwDebugMessage('No Error type specified for '+field);
      }
    break;
  }
  return;
}

/**
*   Returns "no value" string assigned for form element
* 	if a "no value" string has been assigned than function takes default "no value" string
*   @param	string  form element name
*		@return string	"no value"
*/
function getNoValue(field) {
  if(!noValue.length && !noValue[formName]){
		return strNoValue;
  }
  return (!noValue[formName][field])?strNoValue:noValue[formName][field];
}

/**
*   Calls user defined function
*   @param	string  function name
*		@param	mixed 	form field value
*		@param	boolean
*/
function callUserFunc( func, value ){
  if(!userFunc.length && !userFunc[formName]){
    return false;
  }
  if(!userFunc[formName][func]){
   	throwDebugMessage("Userfunc "+func+" does not exists");
    return false;
  }
  return eval(''+func+'("'+value+'");');
}

/**
*   Applies global defined regular expression in different validation cases
*   @param	string  form element name
*		@param	mixed 	form element value
*   @return boolean true if validation is succesful, false if not
*/
function regExpr(field,value){
  var conf = elements[formName][field].split(":");
  if(!conf[1]) {
   	return true;
  }
  switch(conf[1]){
		case "alpha":
      if(!isNaN(value))
      	return false;
			if(num.exec(value) || noalpha.exec(value))
    		return false;
		break;
    case "alphanum":
			if(!isNaN(value))
				return false;
			if(!num.exec(value) || !alpha.exec(value) )
				return false;
    break;
    case "num":
			if(isNaN(value))
      	return false;
   	break;
    case "email":
      if(!email.test(value))
      	return false;
    break;
    default:
      return callUserFunc( conf[1], value );
    break;
	}
  return true;
}

/**
*   Returns error messag assign in config array errorMsg
*   @param	string  form element name
*   @return string 	error message
*/
function getErrorMsg(field){
  if(!errorMsg.length && !errorMsg[formName]){
    return false;
  }
  var conf = elements[formName][field].split(":");
  if(conf[1] && errorMsg[formName][conf[1]]){
		return errorMsg[formName][conf[1]];
  }
  if(errorMsg[formName][field]){
  	return errorMsg[formName][field];
  }
  return false;
}

/**
*   Checks whether one of a group of radio buttons has been clicked
*   @param	string  form radio element name
*   @return mixed 	value of form element radio if checked otherwise false
*/
function isChecked( group ){
  for(var i=0;i < group.length;i++){
    if(group[i].checked == true){
      return group[i].value;
    }
  }
  return false;
}

/**
*   Returns value according form element type
*   @param	string  form element type
*   @param	object  form element object
*   @return mixed 	value of form element radio if set otherwise false
*/
function value2Type(type,fieldObj){
  switch(type){
  	case "input":
    	value = fieldObj.value;
    break;
    case "checkbox":
    case "radio":
      value = fieldObj.value;
      if(!value){
      	value = isChecked(fieldObj);
      }
    break;
  }
  return value;
}

/**
*   Sets font color if method "getElementById" is available
*   @param	string  form element type
*   @param	object  form element object
*   @param	string  hex font color
*   @return boolean
*/
function setColor(type,fieldObj,color){
  if(!document.getElementById){
		return false;
  }

  switch(type){
    case "input":
      fieldObj.style.color = color;
    break;
	}
  return true;
}

/**
*   Sets form element value according element type
*   @param	string  form element type
*   @param	object  form element object
*   @param	mixed		form element value
*   @return void
*/
function setValue(type,fieldObj,value){
  if(!value)return false;
  switch(type){
  	case "input":
    	fieldObj.value = value;
    break;
    case "checkbox":
    case "radio":
    break;
  }
  return true;
}

/**
*   Returns form element type specified in config
*   @param	string  form element name
*   @return mixed 	form element type if specified otherwise false
*/
function getType(field) {
  var pos = elements[formName][field].indexOf(":");
  return (pos < 0)?elements[formName][field]:elements[formName][field].substr(0,pos);
}

/**
*   Returns form element object
*   @param	string  form element name
*   @return mixed 	form element object if specified otherwise false
*/
function getFieldObj(field) {
  var f = document.forms[formName];
  return (!f.elements[field])?false:f.elements[field];
}

/**
*   Check if form element value has been set taking into account possible error message
*   @param	string  form element name
*   @param	object  form element object
*   @return mixed 	form element value if set otherwise false
*/
function hasFilledOut(field,fieldObj){
  var type = getType(field);
  var value = value2Type(type,fieldObj);
  //set no value
  if(!value){
    throwErrorMessage(type,fieldObj,getNoValue(field));

    return false;
  }
  //if error type is value check error messages
  if( errorType[formName][type] == "value") {
  	if( ( value == getNoValue(field) ) || ( value == getErrorMsg(field) ) )return false;
  }
  setColor(type,fieldObj,"#000000");
  return value;
}

/**
*   main form validation function
*		iterates and validates specified form elements, calls form.submit() if validation was successful
*   @param	string  form name
*   @return boolean false
*/
function validate( fName ){
  var valid = true,value;
  if(!document.forms[fName]){
		throwDebugMessage("Formlar "+fName+" existiert nicht");
  }
  var f = document.forms[fName];
  formName = fName;
  var error = false;
  var fields = f.elements;
  for(var field in elements[formName]){
    //if field is not set continue
    if(!fields[field])continue;
    //get field value
    value = hasFilledOut(field,fields[field]);
    if(!value) {
      valid = false;
    } else if(!regExpr(field,value) ){
      var type = getType(field);
      if(errorType[formName][type] !== "value"){
        var msg = value;
      }else {
        var msg = getErrorMsg(field)
      	if(!msg) {
        	setColor(type,fields[field],"#FF0000");
        }
      }
      throwErrorMessage(type,fields[field],msg);
      valid = false;
    }
    if(!valid){
      var to = libObj("errMsg");
			to.style.visibility="visible";
      error = true;
    }
    valid = true;
  }
  if(error){
    return false;
  }
  if (fName !== 'win'){
   //	f.action += "&validate=1";
  }
  f.submit();
  return false;
}


/**
*   Resets form
*		@return void
*/
function formReset(){
	if(!arguments[0]){
  	document.forms[0].reset();
  }else {
    document.forms[arguments[0]].reset();
  }
}
/**
*   Alert debug message if flag has been set
*		@return void
*/
function throwDebugMessage(strMessage){
 	if(!debug)return false;
  alert(strMessage);
}

var l = 0;
isMacIE = ( (navigator.userAgent.indexOf("IE 5") > -1) && (navigator.userAgent.indexOf("Mac")  > -1) );
var error = false;

//Browsercheck (needed) ***************
function lib_bwcheck(){
  this.ver=navigator.appVersion
  this.agent=navigator.userAgent
  this.dom=document.getElementById?1:0
  this.opera5=this.agent.indexOf("Opera 5")>-1
  this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
  this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
  this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
  this.ie=this.ie4||this.ie5||this.ie6
  this.mac=this.agent.indexOf("Mac")>-1
  this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
  this.ns4=(document.layers && !this.dom)?1:0;
  this.bw=(this.ie6||this.ie5||this.ie4||this.ns4||this.ns6||this.opera5)
  return this
}

var bw = new lib_bwcheck() //Browsercheck object

/**
* Get Object
* @param
*/
function libObj( name ){
	obj = bw.dom?document.getElementById(name):bw.ie4?document.body.all[name]:0;
  return obj;
}

