/**
 * Autor: Ben Nimmo
 * 
 * Validator
 * 
 */
(function($){  
	$.fn.validate = function(options) {  
		
		var defaults = {
			showErrors: true,
			errorMessages: {
				text: 'You must enter something here',
				telephone: 'You must enter a valid number',
				number: 'You must enter a valid number',
				email: 'You must enter a valid email address',
				password: 'Your passwords must match',
				date: 'The date must be valid',
				unique: 'This value must be unique'
			}
		};
		var options = $.extend(defaults, options); 
		var valid = true;
		var uniqueVals = new Object;
		this.each(function() {  
			var elem = $(this);
			var currentValid = true;
			var value = elem.val();
			var other = elem.attr('valother');
			var type = elem.attr('valtype') == undefined ? 'text' : elem.attr('valtype');
			var max = elem.attr('valmax') == undefined ? Number.MAX_VALUE : elem.attr('valmax');
			var min = elem.attr('valmin') == undefined ? 1 : elem.attr('valmin');
			var required = elem.attr('valrequired') == undefined ? true : Boolean(elem.attr('valrequired'));
			var unique = elem.attr('valunique') == undefined ? false : elem.attr('valunique');
			if(unique){
				if(!(unique in uniqueVals)) uniqueVals[unique] = new Object;
				if(!(value in uniqueVals[unique])){
					uniqueVals[unique][value] = 1
				}else if(!required || (required && value != '')){
					type = 'unique';
					valid = currentValid = false;
				}
			}else if((value == undefined || value == null || value == '') && required){
				valid = currentValid = false;
			}else if((value == undefined || value == null  || value == '') && !required){
				currentValid = true;
			}else if(type == 'password'){
				if((value != $('#'+other).val()) || value == ''){
					valid = currentValid = false;
					elem = $('#'+other);
				}
			}else if(type == 'text'){
				if(value.length < min || value.length > max ) valid = currentValid = false;
			}else if(type == 'date'){
				var date = elem.datepicker("getDate");
				if(min == 'now' && date <= new Date()){
					valid = currentValid = false
				}
				
				if(max == 'now' && date >= new Date()){
					valid = currentValid = false
				}
				var mSecInDay = 60*60*24*1000;
				var currentDate = new Date();
				if(min != 'now' && min != ''){
					min = parseInt(min);
					if(date <= new Date(currentDate.getTime() + mSecInDay * min)){
						valid = currentValid = false;
					}
				}
				
				if(max != 'now' && max != ''){
					max = parseInt(max);
					if(date >= new Date(currentDate.getTime() + mSecInDay * max)){
						valid = currentValid = false;
					}
				}
				
			}else if(type == 'telephone'){
				// Convert into a string and check that we were provided with something
				var telnum = value + " ";
				if (telnum.length == 1)  {
					valid = currentValid = false;
				}
				telnum.length = telnum.length - 1;

				// Don't allow country codes to be included (assumes a leading "+")
				var exp = /^(\+)[\s]*(.*)$/;
				if (exp.test(telnum) == true) {
					valid = currentValid = false;
				}

				// Remove spaces from the telephone number to help validation
				while (telnum.indexOf(" ")!= -1)  {
				telnum = telnum.slice (0,telnum.indexOf(" ")) + telnum.slice (telnum.indexOf(" ")+1)
				}

				// Remove hyphens from the telephone number to help validation
				while (telnum.indexOf("-")!= -1)  {
				telnum = telnum.slice (0,telnum.indexOf("-")) + telnum.slice (telnum.indexOf("-")+1)
				}  

				// Now check that all the characters are digits
				exp = /^[0-9]{10,11}$/;
				if (exp.test(telnum) != true) {
					valid = currentValid = false;
				}

				// Now check that the first digit is 0
				exp = /^0[0-9]{9,10}$/;
				if (exp.test(telnum) != true) {
					valid = currentValid = false;
				}

				// Disallow numbers allocated for dramas.

				// Array holds the regular expressions for the drama telephone numbers
				var tnexp = new Array ();
				tnexp.push (/^(0113|0114|0115|0116|0117|0118|0121|0131|0141|0151|0161)(4960)[0-9]{3}$/);
				tnexp.push (/^02079460[0-9]{3}$/);
				tnexp.push (/^01914980[0-9]{3}$/);
				tnexp.push (/^02890180[0-9]{3}$/);
				tnexp.push (/^02920180[0-9]{3}$/);
				tnexp.push (/^01632960[0-9]{3}$/);
				tnexp.push (/^07700900[0-9]{3}$/);
				tnexp.push (/^08081570[0-9]{3}$/);
				tnexp.push (/^09098790[0-9]{3}$/);
				tnexp.push (/^03069990[0-9]{3}$/);

				for (var i=0; i<tnexp.length; i++) {
					if ( tnexp[i].test(telnum) ) {
						valid = currentValid = false;
					}
				}

				// Finally check that the telephone number is appropriate.
				exp = (/^(01|02|03|05|070|071|072|073|074|075|07624|077|078|079)[0-9]+$/);
				if (exp.test(telnum) != true) {
					valid = currentValid = false;
				}
			}else if(type == 'email'){
				value = value.toLowerCase();
				var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
				if(reg.test(value) == false || value.length == 0) valid = currentValid = false;
			}else if(type == 'number'){
				if((parseFloat(value) == parseInt(value)) && !isNaN(value)){
					if(value <= min || value >= max ) valid = currentValid = false;
				} else { 
					valid = currentValid = false;
				} 
				
			}
			elem.removeClass('error').parent().parent().removeClass('error');
			elem.parent().children().remove('.help-inline');
			if(!currentValid && defaults['showErrors']){
				var errorMsg = elem.attr('valmsg') == undefined ? defaults['errorMessages'][type] : elem.attr('valmsg');
				elem.addClass('error').parent().parent().addClass('error');
				elem.parent().append($('<span class="help-inline"></span>').html(errorMsg));
			}
		});  
		return valid;
	};  
})(jQuery); 

