// Default Initialise for Toll Pages
$(document).ready(function(){
	$(".nav").navigation();
	$(".hint").hints();
	
});

/******************************
*  Toll Navigation jQuery plugin
*******************************/
(function($) {
	/**
	* configureNavigation adds the appropriate classes to navigation in order to 
	* setup the drop down navigation functionality.
	*/
	$.fn.navigation = function() {
		
            return this.each(function() { 
	            
                // Get jquery object
                var $obj = $(this); 

				$obj.find("li").not("li li").hover(
					function(){
						$(this).addClass("hover");
						$(this).children("ul").show();	
					}, 
					function(){
						$(this).removeClass("hover");
						$(this).children("ul").hide();
					}
				);					   
				
				$obj.find("ul ul li.has-children a span").click(expandMenu);

				// Check hoverIntent Plugin Exists
				if(jQuery().hoverIntent) {
					var hiConfig = {    
					     sensitivity: 20, 
					     interval: 600, 
					     over: hoverExpand,
					     out: function() { return false; }
					};
					$obj.find("ul ul li.has-children").hoverIntent(hiConfig);
				}
													   
            });
        };        
        
        function expandMenu() {
			$(this).parent().parent().toggleClass("open");
			$(this).parent().toggleClass("open");
			$(this).parent().parent().children("ul").slideToggle();
			return false;
        }

        function hoverExpand() {
	        if($(this).hasClass("open") == false)
	        {
				$(this).toggleClass("open");
				$(this).children("a").toggleClass("open");
				$(this).children("ul").slideToggle();
			}
			return false; 
        }
                  
})(jQuery);

/******************************
*  Toll Form Tools jQuery plugin
*******************************/
(function($) {

	/* XSSFilter removes any potential cross-site scripting or sql injection. */
	$.fn.xssFilter = function () {
        return this.each(function() { 
            
            // Get jquery object
            var $obj = $(this); 
            
            // Filter potential XSS threats
            var filteredString = $obj.val().replace(/\<|\>|\"|\'|\%|\;|\&|\+|\-/g,"");
            $obj.val(filteredString);
        });
	};
	
	/* Changes input fields default value to a hint. */
	$.fn.hints = function () {
		
		return this.each(function() { 
		
		    // Get jquery object
		    var $obj = $(this); 
		
		    // Clear values if default is already set
		    if($obj.val() == $obj.attr('defaultValue')) {
		        $obj.val('');
	            $obj.css('color','#888888');
		    } else {
				$obj.removeClass('defaultText');
		    }
		
		    // Setup focus/blue functions                
		    if ($obj.val() == '') {
		        $obj.focus(function() {
		            // if value = default value then clear it on focus
		            if ($obj.val() == $obj.attr('defaultValue')) {
		                $obj.val('');
			            $obj.css('color','');
		            }
		        }).blur(function() {
		            // trim value and set uservalue attribute
		            $obj.val(jQuery.trim($obj.val()));
		            
		            // if value is blank then put hintvalue back
		            if ($obj.val() == '') {
		                $obj.val($obj.attr('defaultValue'));
			            $obj.css('color','#888888');
	            	}
		        }).blur();
		    } 
		});		
	};
		
	/* Simple form validation based on class names
		required - allows any characters/length (blank fields/defaults are not allowed by default)
		phone - allowed characters '0123456789+() ' minimum length of 8, maximum of 30
		email - complicated regex taken from the interwebs to match most email address formats
		numeric3 - allows ### (eg 0, 1, 99, 999)
		decimal3 - same as numeric3 only decimal point is allowed
	*/
	$.fn.validateForm = function ( options ) {
		
		// Default options 
		var defaults = { 
			errorCSS : {'border' : '1px dashed #A60000'},
			validCSS : {'border' : '1px solid #6E6E6E'},
			allowDefaults : false,
			displayAttr : 'defaultValue',
			renderErrors : true,
			renderObject : '#form-messages',
			renderClass : 'failed',
			onSuccess : function (obj){},
			onFailure : function (obj){}
		}; 		
		
		// Overwrite defaults
		var options = $.extend({}, defaults, options); 
		
		// JQuery Object to validate
		var $vObject = $(this); 
		$vObject.validator = this.getValidator();
		
		$vObject.find(".required, .email, .phone, .postcode, .numeric3, .decimal3").each(function() {
			
			var $object = $(this); 
			$object.css(options.validCSS);
			var objectName = $object.attr('defaultValue') == '' ? $object.attr('name') : $object.attr('defaultValue');
			
			// Required Field
				if($object.hasClass("required") == true) {
				// Are defaults allowed?
				if(options.allowDefaults == false) {
					if($object.val() == $object.attr('defaultValue') || $object.val() == "") {
						$vObject.validator.addError(objectName + " is required");
						$object.css(options.errorCSS);
					}
				} else {
					// Is object value blank?
					if($object.val() == "") {
						$vObject.validator.addError(objectName + " is required");
						$object.css(options.errorCSS);
					}
				}
			}
			
			// Email Validation
			if($object.hasClass("email") == true) {
				var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);					
				if(pattern.test($object.val()) == false) 
				{
					$vObject.validator.addError(objectName + " address is invalid");
					$object.css(options.errorCSS);
				}
			}

			// Phone Validation
			if($object.hasClass("phone") == true) {
				//var pattern = new RegExp(/^[0-9 +()x]{8,12}$/g);
				var pattern = new RegExp(/^[0-9]{10,20}$/g);
				if(pattern.test($object.val().replace(/[ +()x\-_]/g, "")) == false) {
					$vObject.validator.addError(objectName + " phone number is invalid");
					$object.css(options.errorCSS);
				}
			}
						
			// Postcode Validation
			if($object.hasClass("postcode") == true) {
				//not making postcode a mandatory field, however if there is data, validate it
				if($object.val().length>0) {
					var pattern = new RegExp(/^[0-9]{4}$/g);
					if(pattern.test($object.val()) == false) {
						$vObject.validator.addError(objectName + " psotcode is invalid");
						$object.css(options.errorCSS);
					}
				}
			}
						
			// Numeric Validation
			if($object.hasClass("numeric3") == true) {
				var pattern = new RegExp(/^[0-9]{0,3}$/g);
				if(pattern.test($object.val()) == false) {
					$vObject.validator.addError(objectName + " enter valid number (0-999)");
					$object.css(options.errorCSS);
				}
			}
						
			// Decimal Validation
			if($object.hasClass("decimal3") == true) {
				var objectName = $object.attr(options.displayAttr) == '' ? $object.attr('name') : $object.attr(options.displayAttr);
				
				var pattern = new RegExp(/^[0-9.]{0,3}$/g);
				if(pattern.test($object.val()) == false) {
					$vObject.validator.addError(objectName + " enter valid number (0-999)");
					$object.css(options.errorCSS);
				}
			}
						
		});
		
				
		// Automatically render errors		
		if(options.renderErrors == true && $vObject.validator.isValid() == false)
		{
			$messageBox = $(options.renderObject);
			$messageBox.text('');
			$errorList = $("<ul></ul>").css('margin-bottom','0');
			$($vObject.validator.messages).each(function(i, item) { 
				$("<li></li>").text(item).appendTo($errorList);
			});
			$errorList.appendTo($messageBox);
			$(options.renderObject).addClass(options.renderClass);
			$(options.renderObject).fadeIn("slow");
		}			
		
		if($vObject.validator.isValid() == false) {
			if (typeof options.onFailure == "function") {
				options.onFailure($vObject);
			} else { alert(typeof options.onFailure + " is not a function."); }
		} else {
			if (typeof options.onSuccess == "function") {
				options.onSuccess($vObject);
			} else { alert(typeof options.onSuccess + " is not a function."); }
		}
	}
	
	// Validator Object
	$.fn.getValidator = function() {
		return {
				messages : [],
				isValid : function() { 
					var valid = false;
					if(this.messages.length == 0) 
						valid = true; 
					return valid; 
				},
				clear : function() {
					this.messages.clear();
				},
				addError : function(message) {
					this.messages.push(message);
				}
		};
	}
	
	$.fn.postForm = function ( options ) {
		
		// Default options 
		var defaults = { 
			allowDefaults : false,
			url : './',
			onSuccess : function (data){},
			onFailure : function (data){}
		}; 		
		
		// Overwrite defaults
		var options = $.extend({}, defaults, options); 

		// JQuery Object to validate
		var $vObject = $(this); 

		// Filter form inputs for XSS characters
		$vObject.find(":input").xssFilter(); 		
		
		// Get form data
		var formData = [];
		$vObject.find(":input").each(function() {
			var $formObj = $(this);
			
			switch($formObj.attr('type')) 
			{
				case "text":
				case "textarea":
					if(options.allowDefaults == false) {
						if($formObj.val() == $formObj.attr('defaultValue') || $formObj.val() == "") {
							formData.push({ name : $formObj.attr('name'), value : '' });
						} else {
							formData.push({ name : $formObj.attr('name'), value : $formObj.val() });
						}
					} else {
						formData.push({ name : $formObj.attr('name'), value : $formObj.val() });
					}
					break;
				case "select-one":
					formData.push({ name : $formObj.attr('name'), value : $formObj.find(":selected").text() });
					break;
				case "checkbox":
					var isChecked = ($formObj.attr('checked') == true ? 'yes' : 'no')
					formData.push({ name : $formObj.attr('name'), value : $formObj.val() + "|" +isChecked });
					break;
				case "button":
				case "reset":
					// Ignore buttons for now.
					break;
				default:
					if(window.console) console.log($formObj.attr('type') + " default case");
					break;
			}
		});
		
		// Make ajax request
		$.ajax({
			type: 'POST',
			url: options.url,
			data: formData,
			cache: false,
			dataType: 'json',
			success: options.onSuccess,
			error: options.onFailure
		});	
	}
	
	// text limit for textarea (or whatever field that act as caller)
	$.fn.textlimit = function(options) {
		
		// Default options 
		var defaults = { 
			limit : 500,
			indicator : '#counter',
			useIndicator : true,
			callback : jQuery.noop()
		}; 		
		
		// Overwrite defaults
		var options = $.extend({}, defaults, options); 
		
		// Get indicator object and update the text limit
		var $indicator = $(options.indicator);
		// If indicator is not found do not use it.
		if($indicator.length == 0) options.useIndicator = false;
		
		if(window.console) console.log("Use Indicator"+options.useIndicator);
		
		if(options.useIndicator == true) $indicator.text(options.limit);
		
		//setup text limit
		$(this).keyup(function() {
			if($(this).val().length > options.limit)
			{
				$(this).val($(this).val().substr(0,options.limit));
								
				//set cursor/position
				if($(this).setSelectionRange) {
					$(this).focus();
					$(this).setSelectionRange(start, end);
				} else if($(this).createTextRange) {
					var range = $(this).createTextRange();
					range.collapse(true);
					range.moveEnd('character', end);
					range.moveStart('character', start);
					range.select();
				}
				
				//second try on setting cursor/position
				$(this).scrollTop($(this).attr('scrollHeight'));
			}
			
			// Update Counter Text
			if(options.useIndicator == true) {
				var count = options.limit - ($(this).val().length < 0 ? 0 : $(this).val().length);
				$indicator.text(count);
			}
			
			// Call our callback function
			if (typeof options.callback == "function") {
				options.callback.call(this, options);
			}
		});		
			
	}
})(jQuery);
