
var formValidator = function(opts) {
	this.formId = null;
	this.submitId = null;
	this.errorMsg = "You must complete all the fields to continue...";
	this.msgContainer = null;
	
	this.target = null;
	this.validators = {};
	
	if (typeof(opts.formId) == 'string')
		this.formId = opts.formId;
	if (typeof(opts.submitId) == 'string')
		this.submitId = opts.submitId;
	if (typeof(opts.errorMsg) == 'string')
		this.errorMsg = opts.errorMsg;
	if (typeof(opts.msgContainer) == 'string')
		this.msgContainer = opts.msgContainer;
	
};

formValidator.prototype = {
	init : function() {
		this.target = document.getElementById(this.formId);
		this.target.onsubmit = bind(this.submit, this);
		
		var madeFocus = false;
		for (var f in this.validators) {
			if (document.getElementById(this.validators[f].field)) {
				if (!madeFocus) {
					document.getElementById(this.validators[f].field).focus();
					madeFocus = true;
				}
				document.getElementById(this.validators[f].field).onblur = bind(this.validate, this, this.validators[f].field, true);
				document.getElementById(this.validators[f].field).onkeyup = bind(this.validate, this, this.validators[f].field, false);
			}
		}
		
		if (document.getElementById(this.msgContainer)) {
			document.getElementById(this.msgContainer).style.display = 'none';
			if (typeof(this.errorMsg) == 'string')
				document.getElementById(this.msgContainer).innerHTML = this.errorMsg;
		}
	},
	
	addValidator : function(opts) {
		var theOpt = {field : null,
			validator : null,
			container : null,
			successClass : 'success',
			errorClass : 'error',
			func : function(val) { return true; },
			status : true };
		
		if (typeof(opts.field) == 'string')
			theOpt.field = opts.field;
		if (typeof(opts.validator) == 'string')
			theOpt.validator = opts.validator;
		if (typeof(opts.container) == 'string')
			theOpt.container = opts.container;
		if (typeof(opts.successClass) == 'string')
			theOpt.successClass = opts.successClass;
		if (typeof(opts.errorClass) == 'string')
			theOpt.errorClass = opts.errorClass;
		if (opts.func && typeof(opts.func) == 'function')
			theOpt.func = opts.func;
		
		this.validators[theOpt.field] = theOpt;
	},
	
	setMessage : function(field, msg) {
		if (this.validators[field]) {
			document.getElementById(this.validators[field].validator).innerHTML = msg;
		}
	},
	
	validate : function(field, validateAlways) {
		if (this.validators[field]) {
			var v = this.validators[field];
			
			if (validateAlways || (!validateAlways && document.getElementById(v.field).value)) {
				if (v.func(document.getElementById(v.field))) {
					v.status = true;
					if (typeof(v.successClass) == 'string') {
						if (v.container)
							document.getElementById(v.container).className = v.successClass;
						if (v.validator)
							document.getElementById(v.validator).className = v.successClass;
					}
				}
				else {
					v.status = false;
					if (typeof(v.errorClass) == 'string') {
						if (v.container)
							document.getElementById(v.container).className = v.errorClass;
						if (v.validator)
							document.getElementById(v.validator).className = v.errorClass;
					}
				}
			}
			this.checkSubmitAvailable();
		}
	},
	
	submit : function() {
		var submittable = this.checkSubmitAvailable();
		
		if (!submittable) {
			if (document.getElementById(this.msgContainer))
				document.getElementById(this.msgContainer).style.display = 'block';
				
			return false;
		}
		
		if (document.getElementById(this.msgContainer))
				document.getElementById(this.msgContainer).style.display = 'none';
				
		return true;
	},
	
	checkSubmitAvailable : function() {
		var submittable = true;
		for (var f in this.validators) {
			if (!this.validators[f].status)
				submittable = false;
		}
		
		if (!submittable) {
			if (document.getElementById(this.submitId)) 
				document.getElementById(this.submitId).setAttribute('disabled', 'disabled');
			
			
		}
		else {
			if (document.getElementById(this.submitId)) 
				document.getElementById(this.submitId).removeAttribute('disabled');
			
			if (document.getElementById(this.msgContainer))
				document.getElementById(this.msgContainer).style.display = 'none';
		}
		
		return submittable;
	},
	
	// some usefull validation functions
	isValidUsername : function(val) {
		return val.match(/^[a-zA-Z0-9\-\_]+$/);
	},
	
	isValidDate : function(val) {
		return val.match(/^[0-9]{1,4}[\/\-]{1}[0-9]{1,2}[\/\-]{1}[0-9]{1,4}$/);
	},
	
	isValidEmail : function(val) {
		return val.match(/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/);
	}
};

if (!window.bind) {
	window.bind = function(func, obj/*, staticArg1, staticArg2... */) {
		if (arguments.length > 2)
		{
			var staticArguments = [];
			for (var n=2; n < arguments.length; n++)
				staticArguments.push(arguments[n]);
			
			return function()
			{
				for (var i = 0; i < arguments.length; i++)
					staticArguments[staticArguments.length] = arguments[i];
				return func.apply(obj, staticArguments);
			};
		}
		else
		{
			return function()
			{
				return func.apply(obj, arguments);
			};
		}
	};
}
