
function formController(formId,settings) {
	this.formId=formId;	
	this.form=document.getElementById(formId);
	this.form.onsubmit=function() {
		return false;
	}
	if(this.form.getAttribute('_mode')=='rpc')
		this.mode='rpc';
	else
		this.mode='default';
	this.inputs=Array();
	this.radioGroups=Array();
	this.rpcObject='';
	this.rpcFunction='';
	this.rpcInputId='name';
	this.rpcFloodProtect=true;
	this.rpcFloodProtected=false;
	this.rpc=null;
	this.error=false;
	this.callback=false;
	this.submit=function() {
		errorDialog.reset();
		this.disableSubmit();	
		if(this.verifyInputs()) {

			if(this.mode=='default') {
				if(this.formId != this.form.id){
					this.form=document.getElementById(this.formId);	
				}
				this.form.submit();
			}
			else if(this.mode=='rpc') {
				if(!this.rpc) {
					this.rpc=RPC.New(this.rpcObject,this.rpcFunction);
					this.rpc.controller=this;
				}
				this.rpc.callBack=function(status,xml,text) {
					this.controller.submitted(status,xml,text);
				}
				for(cInputs=0;cInputs<this.inputs.length;cInputs++) {
					switch(this.inputs[cInputs].tagName) {
						case 'SELECT':
						case 'TEXTAREA':
						case 'INPUT':
							inputName=null;
							switch(this.rpcInputId) {
								case 'name':
									inputName=this.inputs[cInputs].name;
									break;
								case '_id':
								default:
									inputName=this.inputs[cInputs].getAttribute('_id');
									break;
							}
							if(inputName) {
								switch(this.inputs[cInputs].type) {
									case 'checkbox':
										this.rpc.setParameter(inputName,(this.inputs[cInputs].checked ? (this.inputs[cInputs].value ? this.inputs[cInputs].value : '1') : '' ));
										break;
									default:
										this.rpc.setParameter(inputName,this.inputs[cInputs].value);
										break;
								}
							}
					}
				}
				this.rpc.execute();
			}
		}
	}
	this.submitted=function(status,xml,text) {
		success=false;
		switch(status) {
			case 200:
				node=xml.firstChild;
				switch(node.nodeName) {
				case 'error':
					this.showError(this.form.getAttribute('_error')+node.firstChild.nodeValue);
					break;
				case 'method':
					node=node.firstChild;
					if(node!==null){
						switch(node.nodeName) {
							case 'submit':
							case 'reset':
								break;
							case 'error':
								this.showError(node.firstChild.nodeValue);
								break;
							case 'success':
								if(this.callback)
									this.callback(xml,text,node.firstChild.nodeValue);
								//this.showInfo(this.form.getAttribute('_success'));
								success=true;
							break;
						}
						break;
					}
				}
				break;
			default:
				this.showError(this.form.getAttribute('_error')+'RPC failed with statuscode '+status);
		}
		if(success==false || this.rpcFloodProtect==false)
			this.enableSubmit();
		else if(success==true)
			this.rpcFloodProtected=true;

	}
	
	this.disableSubmit=function() {
		for(i=0;i<this.inputs.length;i++) {
			if(this.inputs[i].type=='submit' || this.inputs[i].type=='image') {
				this.inputs[i].disabled=false;
			}
		}
	}
	
	this.enableSubmit=function() {
		for(i=0;i<this.inputs.length;i++) {
			if(this.inputs[i].type=='submit' || this.inputs[i].type=='image') {
				this.inputs[i].disabled=false;
			}
		}
	}

	this.setupInputs= function(settings) {
		var inputProperties=null;
		if(settings && settings['properties'])
			inputProperties=settings['properties'];
		var messageDivs=null;
		if(settings && settings['messages'])
			messageDivs=settings['messages'];	
		cInputs=this.form.getElementsByTagName('input');
		for(i=0;i<cInputs.length;i++) {
			oInput=this.setupInput(cInputs[i],inputProperties)
			if(oInput!==false)
				this.inputs.push(oInput);
		}
		cInputs=this.form.getElementsByTagName('textarea');
		for(i=0;i<cInputs.length;i++) {
			this.inputs.push(this.setupInput(cInputs[i],inputProperties));
		}
		cInputs=this.form.getElementsByTagName('select');
		for(i=0;i<cInputs.length;i++) {
			this.inputs.push(this.setupInput(cInputs[i],inputProperties));
		}
	}
	this.showError=function(message) {
		errorDialog.reset();
		errorDialog.set(message);
		errorDialog.show();	
	}

	this.showInvalid=function(message,addExisting) {
		errorDialog.reset();
		errorDialog.set(message);
		errorDialog.show();
	}	
	
	this.showInfo=function(message) {
		errorDialog.reset();
		errorDialog.set(message);
		errorDialog.show();	
	}
	
	this.setupInput=function(oInput,inputProperties) {
		if(inputProperties && (inputProperties[oInput.name] || inputProperties[oInput.id])) {
			var inputId= oInput.name;
			if(inputProperties[oInput.id]) 
				inputId=oInput.id;
			for(attribute in inputProperties[inputId]) {			
				oInput.setAttribute(attribute,inputProperties[inputId][attribute]);				
			}
		}
		if(oInput.type=='radio') {
			if(!oInput.name)
				return false;
			for(cGroups=0;cGroups<this.radioGroups.length;cGroups++) {
				if(this.radioGroups[cGroups].name==oInput.name) {
					this.radioGroups[cGroups].addRadio(oInput);
					return false;
				}
			}
			oRadioGroup=new Object();
			oRadioGroup.tagName='INPUT';
			oRadioGroup.id=null;
			oRadioGroup.type='radiogroup';
			oRadioGroup.name=oInput.name;
			oRadioGroup.value='';
			oRadioGroup.checked=false;
			oRadioGroup.required=false;
			oRadioGroup.inputs=Array();
			oRadioGroup.controller=this;
			oRadioGroup.className='default';
			oRadioGroup.error='Input invalid, no description specified!';
			oRadioGroup.onchange=function () {
				this.controller.verifyInput(this,true);
			}
			oRadioGroup.getAttribute=function(attribute) {
				switch(attribute) {
					case '_required':
						return this.required;
					case '_defaultClass':
						return 'default';
					case '_errorClass':
						return 'error';
					case '_error':
						return this.error;
					case '_id':
						return this.id;
					default:
						return null;
				}
			}
			oRadioGroup.apply=function() {
				for(cRadios=0;cRadios<this.inputs.length;cRadios++) {
					if(this.className=='default')
						this.inputs[cRadios].className=this.inputs[cRadios].getAttribute('_defaultClass');
					if(this.className=='error')
						this.inputs[cRadios].className=this.inputs[cRadios].getAttribute('_errorClass');
				}
			}
			oRadioGroup.addRadio=function(oRadio) {
				if(!oRadio.getAttribute('_defaultClass'))
					oRadio.setAttribute('_defaultClass',oRadio.className);
				if(!oRadio.getAttribute('_errorClass'))
					oRadio.setAttribute('_errorClass',oRadio.className);
				this.inputs.push(oRadio);
				oRadio.radioGroup=this;
				bRequired=oRadio.getAttribute('_required');
				if(bRequired!==null)
					this.required=bRequired;
				sError=oRadio.getAttribute('_error');
				if(sError!==null)
					this.error=sError;
				sId=oRadio.getAttribute('_id');
				if(sId!==null)
					this.id=sId;
				oRadio.onchange=function() {
					this.radioGroup.onchange();
				}
				oRadio.onclick=oRadio.onchange;
			}
			oRadioGroup.validate=function() {
				this.value='';
				this.checked=false;
				for(cRadios=0;cRadios<this.inputs.length;cRadios++) {
					if(this.inputs[cRadios].checked) {
						this.value=this.inputs[cRadios].value;
						this.checked=true;
						return;
					}
				}
			}
			oRadioGroup.addRadio(oInput);
			this.radioGroups.push(oRadioGroup);
			return oRadioGroup;
		}
		else {
			if(!oInput.getAttribute('_defaultClass'))
				oInput.setAttribute('_defaultClass',oInput.className);
			if(!oInput.getAttribute('_errorClass'))
				oInput.setAttribute('_errorClass',oInput.className);
			if(!oInput.getAttribute('_error'))
				oInput.setAttribute('_error',"Input invalid, no description specified!");
			if(oInput.type=='submit' || oInput.type=='image' ) {
				if(!oInput.getAttribute('_submit') && oInput.getAttribute('_submit')!='disabled'){
					oInput.onclick=function() {
						this.controller.submit();
					}
				}
			}
			oInput.controller=this;
			oInput.onchange=function() {				
				this.controller.verifyInput(this,true);
				return true;
			}
			return oInput;
		}
	}
	this.verifyInputs=function() {	
		var i=0;
		var errors="";
		var valid2=true;
		this.error=false;
		errorDialog.reset();
		for(i=0;i<this.inputs.length;i++) {
			if(!this.verifyInput(this.inputs[i],false)) {
				errorDialog.set(this.inputs[i].getAttribute('_error'));
				valid2=false;
			}
		}
		if(valid2==false) {
			errorDialog.show();
			this.error=true;
		}
		
		return valid2;
	}
	
	this.verifyInput=function(oInput,onchange) {
		valid=true;
		if(this.rpcFloodProtected==true) {
			this.enableSubmit();
			this.rpcFloodProtected=false;
		}
		switch(oInput.tagName) {
			case 'TEXTAREA':
			case 'INPUT':
				switch(oInput.type) {
					case 'submit':
					case 'reset':
						break;
					case 'checkbox':
						if(oInput.getAttribute('_required')!==null && !oInput.checked) {
							valid=false;
						}
						break;
					case 'radio':
						alert('Radio slipped through!')
						break;
					case 'radiogroup':
						oInput.validate();
						if(oInput.getAttribute('_required')!==null && !oInput.checked) {
							valid=false;
						}
						break;
					default:
						// Process as default textfield						
						if(oInput.getAttribute('_required')!==null && !oInput.value) {
							valid=false;
						}
						if(oInput.getAttribute('_maxlen')!==null && oInput.value.length>oInput.getAttribute('_maxlen')) {
							valid=false;
						}
						if(oInput.getAttribute('_minlen')!==null && oInput.value.length<oInput.getAttribute('_minlen')) {
							valid=false;
						}
						// This input is our captcha only check if its valid anyway
						// and when we arent checking already.
						if(oInput.getAttribute('_validator')!==null) {
							var validator=null;
							try {
								validator =eval(""+oInput.getAttribute('_validator')+"");
							}
							catch(e){}
							if(typeof(validator) =='function') {								
								if(!validator(oInput)) { 
									valid=false;																
								}								
							}
						}
						if(oInput.getAttribute('_mask')!==null) {
							switch(oInput.getAttribute('_mask')) {
								case 'hh:mm':
									mask=new RegExp('[0-2][0-9]:[0-5][0-9]','gm');
									break;
								case 'dd/mm/yy':
									mask=new RegExp('[0-3][0-9]/[0-1][0-9]/[0-9][0-9]','gm');
									break;
								case 'dd-mm-yy':
									mask=new RegExp('[0-3][0-9]-[0-1][0-9]-[0-9][0-9]','gm');
									break;
								case 'dd/mm/yyyy':
									mask=new RegExp('[0-3][0-9]/[0-1][0-9]/[1-2][089][0-9][0-9]','gm');
									break;
								case 'dd-mm-yyyy':
									mask=new RegExp('[0-3][0-9]-[0-1][0-9]-[1-2][089][0-9][0-9]','gm');
									break;
								case 'mm/dd/yy':
									mask=new RegExp('[0-1][0-9]/[0-3][0-9]/[0-9][0-9]','gm');
									break;
								case 'mm-dd-yy':
									mask=new RegExp('[0-1][0-9]-[0-3][0-9]-[0-9][0-9]','gm');
									break;
								case 'mm/dd/yyyy':
									mask=new RegExp('[0-1][0-9]/[0-3][0-9]/[1-2][089][0-9][0-9]','gm');
									break;
								case 'mm-mm-yyyy':
									mask=new RegExp('[0-1][0-9]-[0-3][0-9]-[1-2][089][0-9][0-9]','gm');
									break;
								case 'email':
									mask=new RegExp('[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}','gm');
									break;
								case 'postal_nl':
									mask=new RegExp('[0-9]{4}[ ]{0,1}[A-Za-z]{2}','gm');
									break;
								case 'phone_nl':
									mask=new RegExp('(0[0-9]{9})|(0[0-9]{1}[ -]{1}[0-9]{8})|(0[0-9]{2}[ -]{1}[0-9]{7})|(0[0-9]{3}[ -]{1}[0-9]{6})','gm');
									break;
								default:
									mask=new RegExp(oInput.getAttribute('_mask'),'gm');
									break;
							}
							if(oInput.value.replace(mask,'')!='')
								valid=false;
						}
						break;
				}
				break;
			case 'SELECT':
				if(oInput.getAttribute('_required')!==false && !oInput.value) {
					valid=false;
				}
				break;
		}
		
		if(valid==true) {
			oInput.className=oInput.getAttribute('_defaultClass');
			if(oInput.type=='radiogroup')
				oInput.apply();
			return true;
		}
		else {
			oInput.className=oInput.getAttribute('_errorClass');
			if(oInput.type=='radiogroup')
				oInput.apply();
			return false;
		}
	}
	this.setupInputs();
}
