/*************************************************************************

Name:	form.js
Desc:	Form actions
		
Todo:
		CLEAN & COMMENT
		

*************************************************************************/

function FormJS(config) {
	//-------------------------------create classes required
	//this.account = 	new AccountJS();	//these do the actual ajax work
	this.human =	new HumanJS();
	
	//-------------------------------var to store all elements
	this.formname =		config['name'];
	this.submitfunc =	config['submitfunc'];
	//this.humanfunc = 	config['humanfunc'];
	this.ent = 			new Array();
	this.ent_help = 	getElement(config['help']);
	this.childList = 	config['children'];
	var meterList = 	config['meter'];
	var placeholderList = 	config['placeholder'];
	this.submitList = 	config['submit'];
	this.humanCheck = 	false;
	this.humanTarget =	null;
	this.humanImage = 	null;
	//-------------------------------setup help for inputs
	this.help = new HelpJS();
	this.help.target(this.ent_help);
	
	
	//-------------------------------find all elements and add help
	var name;
	var key;
	var element;
	var value;
	var placeholder;
	var validateList = new Array();
	
	this.children = new Object();
	
	for (var i=0; i<this.childList.length; i++) {
		key = this.childList[i]['name'];
		name = this.formname + key;
		validation = this.childList[i]['validate'];
		placeholder = this.childList[i]['placeholder'];
		element = getElement(name);
		
		//store in list
		this.children[key] = element;
		
		//add help for fields that require validation only
		this.help.add(element);
		this.ent[name] = element;
		
		//setup validation (should never be null... but we return this childlist so I spose it has to be sometimes)
		if (validation != null) {
			
			for (var v=0; v<validation.length; v++) {
				var type =		validation[v]['type'];
				var args =		validation[v]['args'];
				var target =	validation[v]['target'];
				var targetId =	this.formname + target;
				
				switch (type) {
					case 'V_HUMAN':
						this.humanCheck = true;
						this.humanImage = getElement(targetId);
						this.humanTarget = name;
						break;
						
					default:
						if (target != null) {
							args = getElement(targetId);
						}
						
						validateList.push({	element:		element,
											type:			type,
											args:			args,
											placeholder:	placeholder});	//<-- *** placeholder gets added to every validation item, inefficient...
						break;
				}
			}
		}
	}
	
	//generate first human image (only one per form allowed)
	if (this.humanImage != null) {
		this.humanChange();
	}
	
	//add validation for entire form
	this.valid =	new ValidateJS({	items:	validateList, 
										target:	this, 
										func:	'validate'});
											
	
	
	//add the meters
	var parent = this;
	var element;
	var target;
	var meter;
	var type;
	var i;
	
	for (i=0; i<this.submitList.length; i++) {
		name = 			this.submitList[i]['name'];
		type = 			String(this.submitList[i]['type']).toUpperCase();
		element = 		getElement(this.formname + name);
		element.name =	name;
		
		switch (type) {
			case 'BUTTON':
				EventListener.add(	element, 
									'onclick', 
									function() {parent.submit(this.name);}
								);
				break;
			case 'TEXT':
			case 'PASSWORD':
				EventListener.add(	element, 
									'onkeyup', 
									function(e) {if (keyCodeEnter(e)) {parent.submit(this.name);}}
								);
				break;
		}
	}
	
	
	for (i=0; i<meterList.length; i++) {
		key = 		meterList[i]['name'];
		name = 		this.formname + key;
		element = 	getElement(name);
	
		//element =	getElement(meterList[i]['element']);
		target =	getElement(meterList[i]['target']);
		meter =		getElement(meterList[i]['meter']);
		//alert(element + ', ' + target + ', ' + meter);
		
		element.old_keyup = element.onkeyup;
		EventListener.add(	element, 
							'onkeyup', 
							function() {
								if (element.old_keyup != null) {
									element.old_keyup();
								}
								var strength =	getPasswordStrength(element.value, target.value);
								meter.className = 'strength_' + (Math.floor((strength-0.01) * 5) + 1);
							}
						);
	}
	
	
	/*
	for (i=0; i<placeholderList.length; i++) {
		key = 		placeholderList[i]['name'];
		name = 		this.formname + key;
		element = 	getElement(name);
		value =		placeholderList[i]['placeholder'];
		
		element.placeholder = value;
		element.oldFocus = element.onfocus;
		element.oldBlur = element.onblur;
		
		EventListener.add(	element, 
							'onfocus', 
							function(e) {
								//if (this.oldFocus != null) {this.oldFocus();}
								//if default text is in the field
								if (this.value == this.placeholder) {
									//clear it
									this.value = '';
									if (this.className == 'text_disabled') {
										this.className = 'text';
									}
								//if other text in the field
								} else {
									//select ALL text
									this.select();
								}
							}
						);
		EventListener.add(	element, 
							'onblur', 
							function(e) {
								//if (this.oldBlur != null) {this.oldBlur();} 
								if ((this.value == '') || (this.value == this.placeholder)) {
									this.value = this.placeholder;
									setStateSuffix(this, {disabled:true});
								} else {
									setStateSuffix(this);
								}
							}
						);
	}
	/**/
	
	
	
	
	/*
	
	
	//add the human classes
	for (var i=0; i<humanList.length; i++) {
		element =	getElement(humanList[i]);
		//alert(element + ', ' + target + ', ' + meter);
		
		element.old_keyup = element.onkeyup;
		EventListener.add(	element, 
							'onkeyup', 
							function() {
								if (element.old_keyup != null) {
									element.old_keyup();
								}
								var strength =	getPasswordStrength(element.value, target.value);
								meter.className = 'strength_' + (Math.floor((strength-0.01) * 5) + 1);
							}
						);
	}
	/**/
	
	/*
	//-------------------------------add events to all buttons
	var parent = this;
	
	/**/
}


//form submitted
FormJS.prototype.submit = function(caller) {
	//disable form while submitting
	this.submitDisabled = this.getDisabled();
	this.disable();
	
	//dont try sending unless all fields valid
	if (this.valid.validate()) {
		this.submitCaller = caller;
		this.enableSend(false);
		
		if (this.humanTarget != null) {
			this.human.validate(getElement(this.humanTarget).value, this, 'submitReturn');
		} else {
			this.submitReturn({success:true});
		}
	} else {
		if (!this.submitDisabled) {
			this.enable();
		}
	}
}

FormJS.prototype.submitReturn = function(data) {
	this.enableSend(true);
	
	//re-enable form after submit (if it wasnt already disabled...)
	if (!this.submitDisabled) {
		this.enable();
	}
	
	if (data['success']) {
		var valueList = new Object();
		var caller = this.submitCaller;
		for (var key in this.children) {
			var child = this.children[key];
			var value = child.value;
			
			//if the input is a BUTTON then return value as true/false depending if it's the submit button
			if (String(child.type).toUpperCase() == 'BUTTON') {
				value = false;
				if (key == caller) {
					value = true;
				}
			}			
			valueList[key] = value;
		}
		
		callFunc(null, this.submitfunc, valueList);
	} else {
		//callFunc(null, this.humanfunc, this);
		alert('Human Test Failed - Please try again');
		this.humanChange();
	}
}

//changes human image
FormJS.prototype.humanChange = function() {
	this.human.generateImage(this.humanImage);
}

//called on field validation - use to colour invalid fields, disable buttons
FormJS.prototype.validate = function(data) {
	var validList = data[0];
	var invalidList = data[1];
	
	var valid = (invalidList.length == 0);
	this.enableSend(valid);
	validateStyle(validList, invalidList);
	return valid;
}


FormJS.prototype.enable = function() {
	getElement(this.formname + 'mask').style.display = 'none';
}
FormJS.prototype.disable = function() {
	getElement(this.formname + 'mask').style.display = 'block';
}
FormJS.prototype.getDisabled = function() {
	return (getElement(this.formname + 'mask').style.display == 'none');
}



FormJS.prototype.enableSend = function(enable) {
	var form = getElement(this.formname);
	
	for (i=0; i<this.submitList.length; i++) {
		element = 	getElement(this.formname + this.submitList[i]['name']);
		type = 		String(this.submitList[i]['type']).toUpperCase();
		
		if (isset(element)) { //element gets unset after form is send sometimes (like contact form - it's removed!)
			switch (type) {
				case 'BUTTON':
					element.disabled = (enable) ? '' : 'disabled';
					break;
			}
		}
	}
	/**/
}