	var form = {
		errors: '',
		errorMessages: {
			required: 'Required',
			matching: 'Not Matching',
			email: 'Not a valid Email address'
			
		},
		
		registerError: function(input,rule) {
			if(typeof(this.errors) != 'object'){
				this.errors = {};
			}
			if(typeof(rule.errorMessage) != 'undefined'){
				var error = rule.errorMessage;
			} else {
				var error = this.errorMessages[i];
			}
			this.errors[input.name] = error;
		},
		
		validateInput: function(input,rule,param){
			 if (typeof(rule) == 'object'){
				for(var i in rule){
					if(this.validateInput(input,i,rule[i]) === false){
						this.registerError(input,rule,i);
						break;
					}
				}
			} else if(typeof(rule) == 'string'){
				if(rule == 'errorMessage'){
					return true;
				}
				if(typeof(this.methods[rule]) != 'undefined'){
					return this.methods[rule](this.value(input),input,param);
				} else {
					alert('rule does not exist');
				}
			}
		},
		
		value: function(element) {
			switch( element.nodeName.toLowerCase() ) {
				case 'select':
					return jQuery("option:selected", element).text();
				case 'input':
					return element.value;
				default:
					return element.value;
			}
		},
		
		clean: function(form){
			$('input,textarea,select,button,submit', form).each(function() {
				if(this.type != 'button' && this.type != 'submit'){
					this.value = this.defaultValue;
				} else {
					$(this).attr('disabled','');
				}
			});
		},
		
		validate: function(form,rules) {
			this.cleanErrors();
			this.form = form;
			var params = this.serialize(form,rules);
			if(this.errors == ''){
				return params;
			} else {
				this.showErrors();
				this.errors = '';
				return false;
			}
		},
		
		showErrors: function() {
			for(i in this.errors){
				this.attachError(i,this.errors[i]);
			}
		},
		
		attachError: function(inputName,message,form) {
			if(typeof(form) == 'undefined'){
				var form = this.form;
			}
			var input = $("input[name='" + inputName + "'],textarea[name='" + inputName + "'],select[name='" + inputName + "']",form);
			this.attachErrorDirect(input,message);
		},
		
		attachErrorDirect:function(element,message) {
			var self = this;
			var offset = $(element).offset();
			if($(element).parents('div.modal:first').length == 1) {
				var className = 'modalErrorMessage';
			} else if($(element).parents('div.popup:first').length == 1) {
				var className = 'popupErrorMessage';
			} else {
				var className = 'errorMessage';
			}
			var div = $('<div class="' + className + '"></div>').appendTo('body').css({left:offset.left + 15,top:offset.top + 5,width:$(element).width()});
			
			div.html('<span>' + message + '<img class="icons notice" src="public/images/mybox/icons/icons.png" style="top:2px; left:-46px;"/></span>');
			element.addClass('inputError');
			var clean = function(){
				$(div).fadeOut(300,function(){$(this).remove();});
				$(element).removeClass('inputError');
			}
			$(div).one('click',function(e){
				e.stopPropagation();
				$(element)[0].focus();
				clean();
			});
			element.one('focus',function() {
				clean();
			});
		},
		cleanErrors: function() {
			$('div.errorMessage').remove();
			$('.inputError').removeClass('inputError');
		},
		
		serialize: function(form,rules){
			if(typeof(rules) == 'undefined'){
				var rules = {};
			}
			var self = this;
	    	var a = [];
	    	$('input,textarea,select,button', form).each(function() {
	        	var n = this.name;
	        	if(typeof(rules[n]) != 'undefined'){
	        		self.validateInput(this,rules[n]);
	        	}
	        	var t = this.type;
	        	if ( !n || this.disabled || t == 'reset' || this.value == '' ||
	            	(t == 'checkbox' || t == 'radio') && !this.checked ||
	            	(t == 'submit' || t == 'image' || t == 'button') )
	            	{return;}
	        	if (t == 'select-multiple') {
		            $('option:selected', this).each( function() {
	    	            a.push(n+'='+this.value);
	            	});
	            	return;
	        	}
	        	a.push(n+'='+ self.encode(this.value));
	    	});
	    	return a.join('&'); 
		},
		
		encode: function(text)
		{
			if(typeof(text) == 'string'){
				return encodeURIComponent(text);
			}
		},
		
		getLength: function(value, element) {
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				return jQuery("option:selected", element).length;
			case 'input':
				if( this.checkable( element) ){
					return this.checkableGroup( element).filter(':checked').length;
				}
			}
			return value.length;
		},
		
		depend: function(param, element) {
			return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
		},
		dependTypes: {
			"boolean": function(param, element) {
				return param;
			},
			"string": function(param, element) {
				return !!jQuery(param, element.form).length;
			},
			"function": function(param, element) {
				return param(element);
			}
		},
		required: function(element) {
			return !this.methods.required.call(this, jQuery.trim(element.value), element);
		},
		
		
		methods: {
	
			required: function(value,element, param) {
				element = $(element)[0];
				switch( element.nodeName.toLowerCase() ) {
				case 'select':
					var options = jQuery("option:selected", element);
					return options.length > 0 && ( element.type == "select-multiple" || (jQuery.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
				case 'input':
					if ( this.checkable(element) )
						return this.getLength(value, element) > 0;
				default:
					return value.length > 0;
				}
			},
	
			email: function(value, element) {
				if(value == ''){
					return true;
				}
				return this.required(element) || /^[\w-+\.]+@([\w-]+\.)+[\w-]{2,}$/i.test(value);
			},
			checkable: function( element ) {
				return /radio|checkbox/i.test(element.type);
			}
		
		}
	};

