var validator  = function(){

	var obsoleteKeyCodes = [9,16,18,33,34,35,36,37,38,39,40]
	var ajaxCall 	= null
	var rules		= []

	return {
		validate: function(e, j, o)
		{
			// Fetch obsolete keycodes
			if ( e ) {
				var key = e.keyCode ? e.keyCode : e.which;
				if ( $.inArray( key, obsoleteKeyCodes ) > -1 ) return
			}
			var data = validator.getValue(j)

			// If input field is not required and data is empty no need for sending ajax request
			if ( o.required === false && data == '' ) {
				j.removeClass('validator-invalid')
				$('#'+o.id+'Message').remove()
				return
			}

			$(".validator-loading").removeClass('validator-loading')
			j.addClass('validator-loading')
			params = {numberElements: 1, e0_id: o.id, e0_label: o.label, e0_data: data, e0_rule:o.rule, e0_options:o.options, e0_required: o.required}
			validator.sendRequest(params)
		},

		getValue: function (j)
		{
			var s = j.val()
			if ( j.is('input[type=checkbox]') && j.is(":checked") === false ) s = ''
			if ( j.is('input[type=radio]') && j.is(":checked") === true ) s = j.is(":checked").val()
			$.trim(s)
			return s
		},

		sendRequest: function( params, callbackExtra )
		{
			callback = $.isFunction(callbackExtra) === false ? validator.result : function(o) { validator.result(o);callbackExtra(o) }
			// Process ajax validation
			if ( ajaxCall ) {
				ajaxCall.abort()
			}
			ajaxCall = $.getJSON( '/_ajax/util/validator/validate.php', params, callback)
		},

		result: function( response )
		{
			elements = response.elements
			//Loop thru elements passed from server
			for ( var i = 0; i < elements.length; i++ ){
				element = elements[i]
				id = element.id
				// Clean up
				$('#'+id).removeClass('validator-invalid')
				$('#'+id+'Message').remove()
				// Result handling
				if ( element.valid ) {
					$('#'+id).val(element.dataFormatted)
				} else {
					$('#'+id).parent().after('<p id="'+id+'Message" class="required">&nbsp;&#187;&nbsp;'+element.message+'</p>')
					$('#'+id).addClass('validator-invalid')
				}
				$(".validator-loading").removeClass('validator-loading')
			}
		},

		/**
		*
		*/
		addRule: function ( o )
		{
			if ( typeof(o.required) == 'undefined' ) 		o.required = false
			if ( typeof(o.validateInline) == 'undefined' )	o.validateInline = false
			if ( typeof(o.options) == 'undefined' ) 		o.options = ''
			rules[rules.length] = { id: o.id, rule: o.rule, options: o.options, label: o.label, required: o.required, validateInline: o.validateInline }
		},

		getRules: function (){
			return rules
		},

		getLabelFromHtml: function (id)
		{
			j = $("#" + id + "Label")
			j = j.length == 0 ? $("label[for='" + id + "']") : j;
			text = j.length == 0 ? '' : j.text();
			if ( text ) {
				text = text.replace(/\*|\:/g,'');
				text = $.trim(text)
			}
			return text
		},

		init: function()
		{
			// Fetch formelements and add onchange validation, onkeypress only if validateInline is set
			$.each(rules, function(key, o)
				{
					if ( typeof(o.label) == 'undefined' ) {
						o.label = validator.getLabelFromHtml(o.id);
					}
					var validate = function(e){ validator.validate(e, $(this), o) }
					$('#'+this.id).change(validate)
					if ( o.validateInline === true ) $('#'+this.id).keyup(validate)
				}
			)
		},

		validateAll: function( callbackOnSuccess, callbackOnFailure ){
			if( $.isFunction(callbackOnSuccess) === false )  callbackOnSuccess = function(){}
			if( $.isFunction(callbackOnFailure) === false )  callbackOnFailure = function(){}

			// Make request
			var prefix
			var params = {}
			params.numberElements = rules.length
			$.each(rules, function(i, o){
				prefix = 'e'+i+'_'
				params[prefix+'id'] 		= o.id
				params[prefix+'label'] 		= o.label
				params[prefix+'data'] 		= validator.getValue($('#'+o.id))
				params[prefix+'rule'] 		= o.rule
				params[prefix+'options'] 	= o.options
				params[prefix+'required'] 	= o.required
			})
			callback = function(response){
				if ( response.numberErrors > 0 ) {
					alert('Kontrollér din indtastning.\n\nFelter der ikke er udfyldt korrekt er markeret med rødt.\n\nPrøv venligst igen.')
					callbackOnFailure()
				} else {
					callbackOnSuccess()
				}
			}
			validator.sendRequest(params, callback)
			return false
		}


	}
}();
