/*
	This note must stay intact.
	
	Author:
		Mattias Rundqvist, Webparts (www.webparts.se)
	License:
		Creative Commons Attribution-Share Alike 3.0 License
		http://creativecommons.org/licenses/by-sa/3.0/
*/

var wp_FormValidator = function( mcfg ) {
	
	// -- deklarera variabler
	var self = this;
	var conditions = new Array();
	var events = new Array();
	this.form = null;
	this.initWatchInterval = null;
	var cfg = mcfg;
	// --
	
	// -- debug
	try{var debug = new wp_Log();}catch(e){var debug = new Object();debug.log = function(){};};
	this._function = "wp_FormValidator";
	this.debug = debug;
	// --
	
	
	var check = new this.validator( mcfg.id, self );
	
	function getForm() {
		
		if( cfg.id ) {
			var forms = document.getElementsByTagName("form");
			var count = 0;
			while( count < forms.length ) {
				if( forms[count] == document.getElementById(cfg.id) ) {
					return forms[count];
				}
				count++;
			}
		}
		return document[cfg.name];
	}
	
	// -- privata funktioner
	function attachEvent( obj, e, func ) {
		if( document.addEventListener ) {
			obj.addEventListener( e, func, true );
		} else if( document.attachEvent ) {
			obj.attachEvent( "on"+e, func );
		} else {
			obj["on"+e] = func;
		}
	}
	
	function detachEvent( obj, e, func ) {
		if( document.removeEventListener ) {
			obj.removeEventListener( e, func, true );
		} else if( document.detachEvent ) {
			obj.detachEvent( "on"+e, func );
		} else {
			obj["on"+e] = null;
		}
	}
	
	function getEventData( name, type ) {
		debug.log(self,"find event: "+name+", "+type);
		var current = null;
		var count = 0;
		
		do {
			if( events[count]["event"] == type && events[count]["field"] == name ) {
				current = events[count];
			}	
			count++;
		} while( !current && count < events.length );
		current.element = getForm()[current.field];
		
		return current;
	}
	// --
	
	// -- publika funktioner (som ej anropas manuellt)
	this.execEvent = function( e ) {
	
		e = e ? e : window.event;
		var obj = e.srcElement ? e.srcElement : e.target;
		var data = getEventData( obj.name, e.type );
		var doExec = true;
		
		if( data["condition"] && check[data["condition"]["type"]] ) {
			doExec = check[data["condition"]["type"]]( data["condition"] );
		}
		
		if( doExec ) {
			data["func"]( data );
		}
	}
	// --
	
	// -- publika funktioner
	this.addCondition = function( ccfg ) {
		if( check[ccfg["type"]] && ccfg["field"]) {
			conditions[conditions.length] = ccfg;
		} else {
			debug.log(self,"addCondition(), missing or invalid argument ('field' or 'type').");
		}
	}
	
	this.registerCustomValidation = function( ccfg ) {
		check[ccfg["type"]] = ccfg["func"];
	}
	
	this.registerEvent = function( ccfg ) {
		if( ccfg["event"] && ccfg["func"]) {
			events[events.length] = ccfg;
		} else {
			debug.log(self,"registerEvent(), missing or invalid argument ('event' or 'func').");
		}
	}
	
	function bool( isbool, value ) {
		if( typeof isbool != "undefined" ) {
			value = isbool ? value : !value;
		}
		return value;
	} 
	
	this.validate = function() {
		debug.log(self,"validating...");
		var result = true;
		var doValidate = true;
		var count = 0;
		
		while( result && count < conditions.length ) {
			debug.log(self,"condition: '"+conditions[count]["type"]+"' on field: '"+conditions[count]["field"]+"'");
			doValidate = true;
			if( conditions[count]["condition"] ) {
			    debug.log(self,"checking conditions...");
				doValidate = check[conditions[count]["condition"]["type"]]( conditions[count]["condition"] ) ? true : false;
				doValidate = bool( conditions[count]["condition"]["boolean"], doValidate );
			}
			
			if( doValidate ) {
				if( check[conditions[count]["type"]] ) {
					result = check[conditions[count]["type"]]( conditions[count] ) ? true : false;
					result = bool( conditions[count]["boolean"], result );
				} else {
					debug.log(self,"unknown condition: '"+conditions[count]["type"]+"'");
				}
			}
			count++;
		}
		
		debug.log(self,"validating result: " + result );
		if( !result && mcfg["onerror"] ) {
			conditions[(count-1)].element = getForm()[conditions[(count-1)].field];
			return mcfg["onerror"]( conditions[(count-1)] );
		}
		
		if( result && mcfg.onsuccess ) {
			return mcfg.onsuccess();
		}
		
		return result;
	}
	// --
	
	
	
	// -- initiera
	this.init = function() {
		debug.log(self,"initializing form: " + cfg.id);
		self.form = getForm();
		
		if( self.form ) {
		
			if( mcfg.autovalidate != false ) {
				self.form.onsubmit = self.validate;
			}
					
			// -- attach events
			for( var count = 0; count < events.length; count++ ) {
				var field = self.form[events[count]["field"]];
				
				if( parseInt( events[count]["index"] ) == events[count]["index"] && field[events[count]["index"]] ) {
					field = field[events[count]["index"]];
				}
				
				attachEvent( field, events[count]["event"], self.execEvent );
			}
			// --
			
		} else {
			debug.log(self,"form: '" + cfg.id+ "' does not exist.");
		}
	}
	
	this.initWatch = function() {
		if( document.getElementById( cfg.id ) && !self.form ) {
			self.init();
			clearInterval(initWatchInterval);
			detachEvent( window, "load", self.init );
		}
	}
	
	if( document.getElementById( cfg.id ) ) {
		this.init();
	} else {
		attachEvent( window, "load", self.init );
		
		// -- lita inte på onload, ibland kan sidan ta lång tid att ladda...
		initWatchInterval = setInterval( self.initWatch, 10 );
	}
	// --
}

// -- valideringsfunktioner
wp_FormValidator.prototype.validator = function( id, callback ) {
	
	// -- returnerar värdet av ett fält eller det kombinerade värdet av en en fältserie
	var form = new wp_Form({
		id : id
	});
	
	var self = this;
	this._function = "wp_FormValidator";
	var debug = callback.debug;
	this.debug = debug;
	
	
	// -- valideringsfunktioner
	this.email = function( cfg ) {
	
		var value = form.get( cfg["field"] );
		var result = false;
		
		if( value.isEmail() || !value.length ) {
			result = true;
		}
		
		return result;
	}
	
	this.empty = function( cfg ) {
	
		var value = form.get( cfg["field"] );
		var result = false;
		
		if( value.length == 0 ) {
			result = true;
		}
		
		return result;
	}
	
	this.equal = function( cfg ) {
	
		var value = form.get( cfg["field"] );
		var result = false;
		
		if( value == cfg["value"] || !value.length ) {
			result = true;
		}
		
		return result;
	}
	
	this.mandatory = function( cfg ) {
		
		var result = false;
		var value = form.get( cfg["field"] );
				
		if( typeof value == "string" && value != "" ) {
		    result = true;
		    self.debug.log(self,"Validating field: "+cfg["field"]+", value: "+value+", result: "+result);
		} else if( value.length ) {
		    if( value.length == 1 && value[0] == "" ) {
		        result = false;
		    } else {
    			result = true;
    		}
		    self.debug.log(self,"Validating field: "+cfg["field"]+", value length: "+value.length+", result: "+result);
		}
				
		return result;
	}
	
	this.match = function( cfg ) {
	
		var value = form.get( cfg["field"] );
		var result = false;
		
		if( value.isMatch( cfg["value"] ) || !value.length ) {
			result = true;
		}
		
		return result;
	}
	
	this.pattern = function( cfg ) {
	
		var value = form.get( cfg["field"] );
		var result = false;
		
		if( value.isPattern( cfg["value"] ) || !value.length ) {
			result = true;
		}
		
		return result;
	}
	// --
}
// --
