var validateElements = [];
var oValid;
function validate ()
{	
	this.elements = [];	
	this.valid = true;	
	var self = this;	
	var keyPressed = false;
	var submitPressed = false;	
	var formSubmitted = false;
	var action = null
	this.init = function () 
	{	
		action = $.url.segment(2);		
		keycodes = new Array(13, 9, 16);
		$('input, select').keypress(function (e) 
		{		
			if(e.which == 13 || e.keyCode == 13)
			{
				return false 
			}	 
		});		
		$.each( this.elements, function(index, item)
		{			
			$('#' + item[0]).bind('keyup', function (e) 
			{
				for(key in keycodes)
				{
					if(e.which == keycodes[key] || e.keyCode == keycodes[key])
					{
						return false
					}	
				}
				keyAction(item)
			});
			$('#' + item[0]).bind('change', function (e) 
			{
				for(key in keycodes)
				{
					if(e.which == keycodes[key] || e.keyCode == keycodes[key])
					{
						return false
					}	
				}
				keyAction(item)
			});
		});
		$('input:not(.button), textarea').focus(function (){			
			removeMessagebox()}
		)
		function keyAction (item) 
		{
			keyPressed = true;
			submitPressed = false;			
			self.valid = validateInput(item[0], item[1]);
		}
	};
	
	//------------------------------------------------------------------------------------------------------------------
	
	function removeMessagebox() 
	{	
		$('.message-box')
			.slideUp('slow')
			.queue(function() 
			{
				$(this).remove();
			});
	}
	
	//------------------------------------------------------------------------------------------------------------------

	function validateInput(id, type) 
	{
		var result = 0;
		if (type instanceof Array) 
		{
			for (var i = 0; i < type.length; i++)
			{
				if(type[i] == 'allowEmpty')
				{
					if ($.trim($('#'+id).val()) == '')
					{	
						setFlag(id, result);
						return true; 						
					}
				}
				else if(type[i] == 'double')
				{
					var tmp = type[i];
					var table = type[i?0:1];
					break;
				}	
				else
				{
					var tmp = type[i]; 
				}
			}
			type = tmp;
		}		
		switch (type)
		{
			case 'alpha':
				if ( ! isAlpha($('#'+id).val()) || isEmpty($('#'+id).val())) {
					result = 1;
				}
				break;
			case 'numeric':
				if ( ! isNumeric($('#'+id).val()) || isEmpty($('#'+id).val()) ) {
					result = 2;
				}
				break;
			case 'float':
				if ( ! isFloat($('#'+id).val()) ) {
					result = 2;
				}
				break;				
			case 'alphanumeric':
				if ( ! isAlphaNumeric($('#'+id).val()) || isEmpty($('#'+id).val()) )  {
					result = 3;
				}
				break;
			case 'password':
				var passed = isPassword($('#'+id).val(), {
					length:   [6, 15],
					alpha:    1
				});
				if ( ! passed ) {
					result = 4;
				}
				break;
			case 'email':				
				if ( ! isEmail($('#'+id).val())) {
					result = 5;
				}
				break;
			case 'empty':
				if ( isEmpty($('#'+id).val())) {
					result = 6;
				}
				break;
			case 'domain':
				if ( ! isDomain($('#'+id).val()) ) {
					result = 7;
				}
				break;
			case 'price':				
				if(submitPressed)
				{
					if ( ! isPrice($('#'+id).val()) ) {
						result = 8;
					}					
				}
				else 
				{
					if ( ! validateNumber($('#'+id).val()) ) {
						result = 8;
					}
				}				
				break;
			case 'alphaNumericSpace':
				if ( ! isAlphaNumericSpace($('#'+id).val()) || isEmpty($('#'+id).val()) )  {
					result = 9;
				}
				break;
			case 'zipcode':
				if ( ! isZipcode($('#'+id).val()) ) {
					result = 11;
				}
				break;
			case 'username':
				if ( ! isAlphaNumeric($('#'+id).val()) || ! isLengthBetween($('#'+id).val(), 3, 25) )
				{
					result = 12
				}		
				break;
			case 'date':
				if ( ! isDate($('#'+id).val()) && ! isDate(convertDate($('#'+id).val())))
				{
					result = 13
				}
				break;
			case 'double':		
				doubleCheck('#'+id, table);
				return null;
			default:
		}
		setFlag(id, result);
		return result == 0; 
	};
	
	//------------------------------------------------------------------------------------------------------------------
	
	function setFlag(id, result) 
	{			
		$('#'+id).parent().find('.validation_flag').remove()
		$('#'+id).toggleClass('error', result > 0);		
		if (result > 0) 
		{			
			$($('#'+id).parent())
				.append(
				$('<span class="validation_flag"></span>')
					.html('<img id="'+id+'_validationflag" src="/cfg/img/config/flag-error.png" />')
			);
			$('#'+id+'_validationflag').wTooltip({
					className: 'tooltip',
					id:id+'_wtooltip' 
					,content:errorMessage(result)});
			$('#'+id+'_validationflag').css('cursor', 'pointer');
		}
	}

	//------------------------------------------------------------------------------------------------------------------
	
	function validationActive()
	{
		if (action == 'nieuw' && ! formSubmitted ) return false;
		return true;
	}
	
	//------------------------------------------------------------------------------------------------------------------

	function errorMessage(errnr) {
		var t = '';
		switch (errnr) {
			case 1:
				t ='Enkel A-Z en a-z.';
				break;
			case 2:
				t ='Enkel 0-9.';
				break;
			case 3:
				t ='Enkel A-Z, a-z en 0-9.';
				break;
			case 4:
				t ='Wachtwoord moet bestaan uit 7-15 karakters bestaan.';
				break;
			case 5:
				t ='Het email is adres is (nog) niet (goed) ingevuld (uw.naam@domein.nl).';
				break;
			case 6:
				t ='Dit invoervak mag niet leeg zijn.';
				break;
			case 7:
				t ='Domein fout.';
				break;
			case 8:
				t ='De prijs is (nog) (niet) goed ingevuld.';
				break;
			case 9:
				t ='Enkel A-Z, a-z, 0-9 en spaties.';
				break;
			case 10:
				t ='Het telefoonnummer is (nog) (niet) goed ingevuld.';
				break;
			case 11:
				t ='De postcode is (nog) (niet) goed ingevuld.';
				break;
			case 12:
				t ='De gebruikersnaam moet uit letters en/of cijfers en uit 3-25 karakters bestaan.';
				break;
			case 13:
				t ='De datum is (nog) (niet) goed ingevuld';
				break;
			case 14:
				t ='De ingevoerde waarde bestaat al';
				break;
			default:
				t ='';
		}
		return t;
	};
	
	//-----------------------------------------------------------------------------------------------------------------//
	
	this.validateForm = function () 
	{			
		try 
		{				
			var id;
			for( var i = 0; i < self.elements.length; i++) 
			{				
				id = self.elements[i][0];
				
				if ($('#' + id).length > 0 ) 
				{	
					if( ! validateInput(id, self.elements[i][1]) )
					{						
						self.valid = false						
					}
				}
			};	
			return self.valid;	
		}
		catch(e) 
		{	
			return false;
		}	
		return false;	
	};
	
	//------------------------------------------------------------------------------------------------------------------
	
	function doubleCheck(element, table)
	{	
		var id = $(element).attr('id');		
		if ($('#' + id + '_validationflag').length) return;		
		$.get('/admin/data/index/table/'+table+'/field/'+id+'/'+id+'/'+$('#' + id).val()+'/id/'+$('#' + id+'_id').val()+'/method/'+$('#form-action').val(), {id: id}, function(data)
		{
			doubleResult(data, id);
		})			
	}
	
	//-----------------------------------------------------------------------------------------------------------------//
	
	function doubleResult(data, id)
	{	
		
		var result = 0;
		self.valid=true;
		if (data == '0')
		{
			result = 14	
			self.valid=false
		}
		
		setFlag(id, result);		
		if(submitPressed)
		{			
			if(self.valid)
			{				
				$('#'+id).parents('form:first').submit();			
			}
		}		
	}
	
	//-----------------------------------------------------------------------------------------------------------------//
	
	// returns true if the string is empty
	function isEmpty(str){
	  return (str == null) || (str.length == 0);
	}
	
	function isPrice(str){
		if(isEmpty(str)) return true;
		var re = /^\d+(\,\d{1,2})?$/				
		return re.test(str);
	}
	
	function isFloat(str){
		if(isEmpty(str)) return true;
		var re = /^\d+(\,\d{1,9})?$/			
		return re.test(str);
	}	
	// returns true if the string is a valid email
	function isEmail(str){		
	  if(isEmpty(str)) return false;
	  var re = /^[^\s()<>@,;:\/]+@\w[\w\.-]+\.[a-z]{2,}$/i
	  return re.test(str);
	}
	// returns true if the string only contains characters A-Z or a-z
	function isAlpha(str){
	  var re = /[^a-zA-Z]/
	  if (re.test(str)) return false;
	  return true;
	}
	// returns true if the string only contains characters 0-9
	function isNumeric(str){
	  var re = /[\D]/
	  if (re.test(str)) return false;
	  return true;
	}
	// returns true if the string only contains characters A-Z, a-z or 0-9
	function isAlphaNumeric(str){
	  var re = /[^0-9a-zA-Z]/
	  if (re.test(str)) return false;
	  return true;
	}
	
	// returns true if the string only contains characters A-Z, a-z or 0-9
	function isAlphaNumericSpace(str){
	  var re = /[^0-9a-zA-Z\s]/
	  if (re.test(str)) return false;
	  return true;
	}
	
	function isZipcode(str)
	{	
		var re = /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/
		return (re.test(str));		
	}
	
	// returns true if the string's length equals "len"
	function isLength(str, len){
	  return str.length == len;
	}
	// returns true if the string's length is between "min" and "max"
	function isLengthBetween(str, min, max){
	  return (str.length >= min)&&(str.length <= max);
	}
	// returns true if the string is a US phone number formatted as...
	// (000)000-0000, (000) 000-0000, 000-000-0000, 000.000.0000, 000 000 0000, 0000000000
	function isPhoneNumber(str){
	  var re = /^\(?[2-9]\d{2}[\)\.-]?\s?\d{3}[\s\.-]?\d{4}$/
	  return re.test(str);
	}
	// returns true if the string is a valid date formatted as...
	// mm dd yyyy, mm/dd/yyyy, mm.dd.yyyy, mm-dd-yyyy
	function isDate(str){
	  var re = /^(\d{1,2})[\s\.\/-](\d{1,2})[\s\.\/-](\d{4})$/
	  if (!re.test(str)) return false;
	  var result = str.match(re);
	  var m = parseInt(result[1]);
	  var d = parseInt(result[2]);
	  var y = parseInt(result[3]);
	  if(m < 1 || m > 12 || y < 1900 || y > 2100) return false;
	  if(m == 2){
	          var days = ((y % 4) == 0) ? 29 : 28;
	  }else if(m == 4 || m == 6 || m == 9 || m == 11){
	          var days = 30;
	  }else{
	          var days = 31;
	  }
	  return (d >= 1 && d <= days);
	}
	// returns true if "str1" is the same as the "str2"
	function isMatch(str1, str2){
	  return str1 == str2;
	}
	// returns true if the string contains only whitespace
	// cannot check a password type input for whitespace
	function isWhitespace(str){ // NOT USED IN FORM VALIDATION
	  var re = /[\S]/g
	  if (re.test(str)) return false;
	  return true;
	}
	// removes any whitespace from the string and returns the result
	// the value of "replacement" will be used to replace the whitespace (optional)
	function stripWhitespace(str, replacement){// NOT USED IN FORM VALIDATION
	  if (replacement == null) replacement = '';
	  var result = str;
	  var re = /\s/g
	  if(str.search(re) != -1){
	    result = str.replace(re, replacement);
	  }
	  return result;
	}
	
	function isPassword (pw, options) {
		var o = {
			lower:    0,
			upper:    0,
			alpha:    0, /* lower + upper */
			numeric:  0,
			special:  0,
			length:   [0, Infinity],
			custom:   [ /* regexes and/or functions */ ],
			badWords: [],
			badSequenceLength: 0,
			noQwertySequences: false,
			noSequential:      false
		};
	
		for (var property in options)
			o[property] = options[property];
	
		var	re = {
				lower:   /[a-z]/g,
				upper:   /[A-Z]/g,
				alpha:   /[A-Z]/gi,
				numeric: /[0-9]/g,
				special: /[\W_]/g
			},
			rule, i;
	
		// enforce min/max length
		if (pw.length < o.length[0] || pw.length > o.length[1])
			return false;
	
		// enforce lower/upper/alpha/numeric/special rules
		for (rule in re) {
			if ((pw.match(re[rule]) || []).length < o[rule])
				return false;
		}
	
		// enforce word ban (case insensitive)
		for (i = 0; i < o.badWords.length; i++) {
			if (pw.toLowerCase().indexOf(o.badWords[i].toLowerCase()) > -1)
				return false;
		}
	
		// enforce the no sequential, identical characters rule
		if (o.noSequential && /([\S\s])\1/.test(pw))
			return false;
	
		// enforce alphanumeric/qwerty sequence ban rules
		if (o.badSequenceLength) {
			var	lower   = "abcdefghijklmnopqrstuvwxyz",
				upper   = lower.toUpperCase(),
				numbers = "0123456789",
				qwerty  = "qwertyuiopasdfghjklzxcvbnm",
				start   = o.badSequenceLength - 1,
				seq     = "_" + pw.slice(0, start);
			for (i = start; i < pw.length; i++) {
				seq = seq.slice(1) + pw.charAt(i);
				if (
					lower.indexOf(seq)   > -1 ||
					upper.indexOf(seq)   > -1 ||
					numbers.indexOf(seq) > -1 ||
					(o.noQwertySequences && qwerty.indexOf(seq) > -1)
				) {
					return false;
				}
			}
		}
		for (i = 0; i < o.custom.length; i++) {
			rule = o.custom[i];
			if (rule instanceof RegExp) {
				if (!rule.test(pw))
					return false;
			} else if (rule instanceof Function) {
				if (!rule(pw))
					return false;
			}
		}
		return true;
	}
	function isNumber(nr) {
		return /^-?\d+$/.test(nr);	
	}	
	function isDomain(url) {
	    var re = /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i
	    if (!re.test(url)) return false;
	    return true;	    
	}	
	function convertDate(date)
	{
		var arr = date.split('-');
		return arr[1]+'-'+arr[0]+'-'+arr[2];		
	}	
	function validateNumber(value)
	{
		var re = /^[0-9]{1,},?[0-9]{0,2}$/
		return re.test(value);				
	}
}
$(document).ready(function() 
{
	oValid = new validate();
	oValid.elements=validateElements;	
	oValid.init();	
})

