var VITES = {
	Config : {},
	Data : {},
	Util : {}

};
VITES.Data.vites = {};
VITES.getVites = function (name) {
	return VITES.Data.vites[name];
}
VITES.setVites = function (name, val) {
	VITES.Data.vites[name] = val;
}
VITES.submitForm = function(formId){
	if(VITES.Util.saveFormData.call(VITES.Data[formId],formId)){
		fetchJSON(VITES.Config[formId].dataDestination + "?" + VITES.Util.getQueryString(VITES.Data[formId]), VITES.Config[formId].callBack, VITES.Data);
	};
	return false;
}
VITES.Util = {
	EmailRegex: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
	ForenameRegex: /^[a-zA-Z'\-\. ]{1,}$/,
	SurnameRegex: /^[a-zA-Z'\- ]{2,}$/,
	AddressRegex: /^[0-9a-zA-Z'\-,\. ]{4,}$/,
	TelephoneRegex: /^\d{5} \d{5}\d?$/,
	PostcodeRegex: /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})$/,
	NotNullRegex: /\S+/,
	YesRegex: /^yes$/,
	NoRegex: /^no$/,
	CleanRegex: /(^\s+|\s+$)/g,
	validate: function (val, type, compulsory) {
		if (compulsory == "custom" || compulsory == "no") {
			return val;
		}
		var Regex = {};
		switch (type) {
		case "email":
			Regex = VITES.Util.EmailRegex;
			val = val.toLowerCase();
			val = val.replace(VITES.Util.CleanRegex, "");
			break;
		case "forename":
			Regex = VITES.Util.ForenameRegex;
			val = val.toLowerCase();
			val = val.replace(VITES.Util.CleanRegex, "");
			val = val.replace(/(\s)\s+/g, ' ');
			val = VITES.Util.capitaliseString(val);
			break;
		case "surname":
			Regex = VITES.Util.SurnameRegex;
			val = val.toLowerCase();
			val = val.replace(VITES.Util.CleanRegex, "");
			val = val.replace(/(\s)\s+/g, ' ');
			val = VITES.Util.capitaliseString(val);
			break;
		case "address":
			Regex = VITES.Util.AddressRegex;
			val = val.toLowerCase();
			val = val.replace(/(^\s+|\s+$)/g, '');
			val = val.replace(/\s+,/g, ',');
			val = val.replace(/,/g, ', ');
			val = val.replace(/(\s)\s+/g, ' ');
			val = VITES.Util.capitaliseString(val);
			break;
		case "telephone":
			Regex = VITES.Util.TelephoneRegex;
			val = val.replace(/\D+/g, '');
			val = val.replace(/^44/, '');
			val = val.replace(/^([^0]\d+)/, '0$1');
			val = val.replace(/(\d{5})(\d+)/, '$1 $2');
			break;
		case "postcode":
			Regex = VITES.Util.PostcodeRegex;
			val = val.toUpperCase();
			break;
		case "not-null":
			Regex = VITES.Util.NotNullRegex;
			break;
		case "yes":
			Regex = VITES.Util.YesRegex;
			break;
		case "no":
			Regex = VITES.Util.NoRegex;
			break;
		case "custom":
			return val;
			break;
		}
		if (val.match(Regex)) {
			return val;
		} else {
			return false;
		}
	},
	capitaliseString: function (InputString) {
		var SplitString = new Array;
		var OutputString = '';
		SplitString = InputString.split(/\b/);
		for (var i = 0; i < SplitString.length; i++) {
			if (SplitString[i].match(/^(de|des|di|dalla|della|der|den|du|von|van|fon|la|of|on|over|upon)$/)) {} else {
				if (SplitString[i].match(/^mc/)) {
					SplitString[i] = SplitString[i].substr(0, 1).toUpperCase() + SplitString[i].substr(1, 1) + SplitString[i].substr(2, 1).toUpperCase() + SplitString[i].substr(3);
				} else if (SplitString[i].match(/^mac/)) {
					SplitString[i] = SplitString[i].substr(0, 1).toUpperCase() + SplitString[i].substr(1, 2) + SplitString[i].substr(3, 1).toUpperCase() + SplitString[i].substr(4);
				} else {
					SplitString[i] = SplitString[i].substr(0, 1).toUpperCase() + SplitString[i].substr(1);
				}
			}
		}
		OutputString = SplitString.join('');
		return OutputString;
	},	
	getQueryString: function (obj) {
		var temp = "";
		for (i in obj) {
			if (! (typeof(VITES.getVites(obj[i].formName)) === "undefined")) {
				temp += obj[i].formName + "=" + URLEncode(VITES.getVites(obj[i].formName)) + "&";
			}
		}
		return temp;
	},
	populateForm: function () {
		for (var i = 0; i < this.length; i++) {
			switch (this.elements[i].type) {
			case "radio":
				if (VITES.getVites(this.elements[i].name)) {
					setCheckedValue(this.elements[i], VITES.getVites(this.elements[i].name))
				}
				break;
			case "checkbox":
				if (VITES.getVites(this.elements[i].name) == "yes") {
					this.elements[i].checked = true;
				} else {
					this.elements[i].checked = false;
				}
				break;
			case "button":
				break;
			default:
				if (VITES.getVites(this.elements[i].name)) {
					this.elements[i].value = VITES.getVites(this.elements[i].name);
				}
				break;
			}
		}
	},
	saveFormData: function (formId) {
		var formConfig = this;
		var valid = true;
		var form = document.getElementById(formId);
		for (var i = 0; i < form.length; i++) {
			if (form.elements[i].type == "radio") {
				if (form.elements[i].checked == true) {
					VITES.setVites(form.elements[i].name, form.elements[i].value);
				} else {}
			} else if (form.elements[i].type == "checkbox") {
				if (form.elements[i].checked == true) {
					VITES.setVites(form.elements[i].name, "yes");
				} else {
					VITES.setVites(form.elements[i].name, "no");
				}
			} else {
				VITES.setVites(form.elements[i].name, form.elements[i].value);
			}
			for (j in formConfig) {
				if (formConfig[j].formName == form.elements[i].name) {
					var temp = VITES.Util.validate(VITES.getVites(form.elements[i].name), formConfig[j].validateAs, formConfig[j].compulsory);
					if (temp || ((temp == "" && VITES.getVites(form.elements[i].name) == "") && ((formConfig[j].validateAs != "not-null") && (formConfig[j].compulsory == "no")))) {
						form.elements[i].style.backgroundColor = "white";
					} else {
						valid = false;
						form.elements[i].style.backgroundColor = "yellow";
					}
				}
			}
		}
		if (valid == false) {
			document.getElementById("VITES-error").style.display = "block";
		} else {
			document.getElementById("VITES-error").style.display = "none";
		}
		return valid;
	}
};



function extend(destination, source) {
	for (var property in source)
	destination[property] = source[property];
	return destination;
}


function isUndefined(object) {
	return typeof object === "undefined";
}
extend(Object, {
	extend: extend,
	isUndefined: isUndefined
});
Object.extend(Function.prototype, (function () {
	var slice = Array.prototype.slice;

	function update(array, args) {
		var arrayLength = array.length,
			length = args.length;
		while (length--) array[arrayLength + length] = args[length];
		return array;
	}


	function merge(array, args) {
		array = slice.call(array, 0);
		return update(array, args);
	}


	function bind(context) {
		if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
		var __method = this,
			args = slice.call(arguments, 1);
		return function () {
			var a = merge(args, arguments);
			return __method.apply(context, a);
		}
	}


	function bindAsEventListener(context) {
		var __method = this,
			args = slice.call(arguments, 1);
		return function (event) {
			var a = update([event || window.event], args);
			return __method.apply(context, a);
		}
	}


	function boundDelay(context, timeout) {
		var __method = this,
			args = slice.call(arguments, 2);
		return window.setTimeout(function () {
			return __method.apply(context, args);
		},
		timeout);
	}


	function delay(timeout) {
		var __method = this,
			args = slice.call(arguments, 1);
		return window.setTimeout(function () {
			return __method.apply(__method, args);
		},
		timeout);
	}
	return {
		bind: bind,
		bindAsEventListener: bindAsEventListener,
		delay: delay,
		boundDelay: boundDelay
	}
})());

function getCheckedValue(radioObj) {
	if (!radioObj) return "";
	var radioLength = radioObj.length;
	if (radioLength == undefined) if (radioObj.checked) return radioObj.value;
	else return "";
	for (var i = 0; i < radioLength; i++) {
		if (radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}
function setCheckedValue(radioObj, newValue) {
	if (!radioObj) return;
	var radioLength = radioObj.length;
	if (radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for (var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if (radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
}
var scriptCallBackFunctions = [];
var callbackId = 0;
var scriptRefs = [];
var jVIT = (function () {
	var isIE = false;
	var isIE6 = /msie|MSIE 6/.test(navigator.userAgent);
	var isIE7 = /msie|MSIE 7/.test(navigator.userAgent);
	var uniqueHandlerId = 0;
	var DOMLoaded = false;
	var DOMLoadTimer = null;
	var functionsToCall = [];
	var addedStrings = {};
	var execFunctions = function () {
		for (var i = 0, il = functionsToCall.length; i < il; i++) {
			try {
				functionsToCall[i]();
			}
			catch(e) {}
		}
		functionsToCall = [];
	};
	var DOMHasLoaded = function () {
		if (DOMLoaded) {
			return;
		}
		DOMLoaded = true;
		execFunctions();
	};
	return {
		init: function () {
			window.elm = window.elm || this.elm;
			window.isIE6 = window.isIE6 || this.isIE6;
			window.isIE7 = window.isIE7 || this.isIE7;
			window.addClass = window.addClass || this.addClass;
			window.removeClass = window.removeClass || this.removeClass;
			window.addEvent = window.addEvent || this.addEvent;
			window.removeEvent = window.removeEvent || this.removeEvent;
			window.stopDefault = window.stopDefault || this.stopDefault;
			window.cancelBubbling = window.cancelBubbling || this.cancelBubbling;
			window.DOMReady = window.DOMReady || this.DOMReady;
			window.addBustCache = window.addBustCache || this.addBustCache;
			window.URLEncode = window.URLEncode || this.URLEncode;
			window.fetchJSON = window.fetchJSON || this.fetchJSON;
			window.handleJSON = window.handleJSON || this.handleJSON;
		},
		elm: function (id) {
			return document.getElementById(id);
		},
		addClass: function (elm, className) {
			var currentClass = elm.className;
			if (!new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i").test(currentClass)) {
				elm.className = currentClass + (currentClass.length ? " " : "") + className;
			}
		},
		removeClass: function (elm, className) {
			var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i");
			elm.className = elm.className.replace(classToRemove, function (match) {
				var retVal = "";
				if (new RegExp("^\\s+.*\\s+$").test(match)) {
					retVal = match.replace(/(\s+).+/, "$1");
				}
				return retVal;
			}).replace(/^\s+|\s+$/g, "");
		},
		fetchJSON: function (url, callback, obj) {
			var amp = "";
			if (url.match(/&$/)) {
				url = url.substring(0, url.length - 1);
			}
			callbackId++;
			url = addBustCache(url + amp + "&callback_id=" + callbackId);
			scriptRefs[callbackId] = document.createElement('script');
			scriptRefs[callbackId].setAttribute("type", "text/javascript");
			scriptRefs[callbackId].setAttribute("src", url);
			scriptCallBackFunctions[callbackId] = {}
			scriptCallBackFunctions[callbackId].callback = callback.bind(obj, url);
			scriptCallBackFunctions[callbackId].status = "pending";
			scriptCallBackFunctions[callbackId].url = url;
			scriptCallBackFunctions[callbackId].callbackId = callbackId
			if (typeof scriptRefs[callbackId] != "undefined") {
				document.getElementsByTagName("head")[0].appendChild(scriptRefs[callbackId]);
			};
		},
		handleJSON: function (JSONdata) {

			scriptCallBackFunctions[JSONdata.CallbackId].status = "complete";
			scriptCallBackFunctions[JSONdata.CallbackId].callback(JSONdata);
			x = document.getElementsByTagName("head")[0].childNodes;
			for (y in x) {
				if (x[y]) {
					if (x[y].src) {
						if (x[y].src.match("callback_id=" + JSONdata.CallbackId)) {
							document.getElementsByTagName("head")[0].removeChild(x[y]);
						};
					}
				}
			}
		},
		addBustCache: function (url) {
			var Temp = new Date();
			BustCache = "t_bustcache=" + URLEncode(Temp.getTime());
			if (url.search(/\?/) == -1) {
				url = url + "?" + BustCache
			} else {
				url = url + "&" + BustCache
			}
			return url;
		},
		URLEncode: function (clearString) {
			var output = '';
			var x = 0;
			clearString = clearString.toString();
			var regex = /(^[a-zA-Z0-9_.]*)/;
			while (x < clearString.length) {
				var match = regex.exec(clearString.substr(x));
				if (match != null && match.length > 1 && match[1] != '') {
					output += match[1];
					x += match[1].length;
				} else {
					if (clearString[x] == ' ') {
						output += '+';
					} else {
						var charCode = clearString.charCodeAt(x);
						var hexVal = charCode.toString(16);
						output += '%' + (hexVal.length < 2 ? '0' : '') + hexVal.toUpperCase();
					}
					x++;
				}
			}
			return output;
		},
		addEvent: function (elm, evt, func) {
			if (document.addEventListener) {
				this.addEvent = function (elm, evt, func) {
					elm.addEventListener(evt, func, false);
				};
			} else {
				this.addEvent = function (elm, evt, func) {
					if (!elm.uniqueHandlerId) {
						elm.uniqueHandlerId = uniqueHandlerId++;
					}
					var alreadyExists = false;
					if (func.attachedElements && func.attachedElements[evt + elm.uniqueHandlerId]) {
						alreadyExists = true;
					}
					if (!alreadyExists) {
						if (!elm.events) {
							elm.events = {};
						}
						if (!elm.events[evt]) {
							elm.events[evt] = [];
							var existingEvent = elm["on" + evt];
							if (existingEvent) {
								elm.events[evt].push(existingEvent);
							}
						}
						elm.events[evt].push(func);
						elm["on" + evt] = jVIT.handleEvent;
						if (!func.attachedElements) {
							func.attachedElements = {};
						}
						func.attachedElements[evt + elm.uniqueHandlerId] = true;
					}
				};
			}
			return this.addEvent(elm, evt, func);
		},
		handleEvent: function (evt) {
			var currentEvt = evt || event;
			var currentTarget = currentEvt.target || currentEvt.srcElement || document;
			while (currentTarget.nodeType !== 1 && currentTarget.parentNode) {
				currentTarget = currentTarget.parentNode;
			}
			currentEvt.eventTarget = currentTarget;
			var eventColl = this.events[currentEvt.type].slice(0);
			var eventCollLength = eventColl.length - 1;
			if (eventCollLength !== -1) {
				for (var i = 0; i < eventCollLength; i++) {
					eventColl[i].call(this, currentEvt);
				}
				return eventColl[i].call(this, currentEvt);
			}
		},
		removeEvent: function (elm, evt, func) {
			if (document.addEventListener) {
				this.removeEvent = function (elm, evt, func) {
					elm.removeEventListener(evt, func, false);
				};
			} else {
				this.removeEvent = function (elm, evt, func) {
					if (elm.events) {
						var eventColl = elm.events[evt];
						if (eventColl) {
							for (var i = 0; i < eventColl.length; i++) {
								if (eventColl[i] === func) {
									delete eventColl[i];
									eventColl.splice(i, 1);
								}
							}
						}
						func.attachedElements[evt + elm.uniqueHandlerId] = null;
					}
				};
			}
			return this.removeEvent(elm, evt, func);
		},
		stopDefault: function (evt) {
			evt.returnValue = false;
			if (evt.preventDefault) {
				evt.preventDefault();
			}
		},
		cancelBubbling: function (evt) {
			evt.cancelBubble = true;
			if (evt.stopPropagation) {
				evt.stopPropagation();
			}
		}
	};
})();
jVIT.init();
var loader = function () {
	var isIE = /*@cc_on!@*/false;
	var DOMLoaded = false;
	var DOMLoadTimer = null;
	var functionsToCall = [];
	var addedStrings = {};
	var execFunctions = function () {
		for (var i=0, il=functionsToCall.length; i<il; i++) {
			try {
				functionsToCall[i]();
			}
			catch (e) {
				// Prevent possible reference errors
			}
		}
		functionsToCall = [];
	};
	var DOMHasLoaded = function () {
		if (DOMLoaded) {
			return;
		}
		DOMLoaded = true;
		execFunctions();
	};
	return {
		init : function () {
			window.DOMReady = window.DOMReady || this.DOMReady;
			
			if (document.addEventListener) {
				document.addEventListener("DOMContentLoaded", DOMHasLoaded, false);
			}
			if (isIE) {
				if (document.getElementById) {
					document.write("<script id=\"ieScriptLoad\" defer src=\"//:\"><\/script>");
					document.getElementById("ieScriptLoad").onreadystatechange = function() {
						if (this.readyState === "complete") {
							DOMHasLoaded.call(this);
						}
					};
				}
			}
			if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
				DOMLoadTimer = setInterval(function () {
					if (/loaded|complete/i.test(document.readyState)) {
						DOMHasLoaded.call(this);
						clearInterval(DOMLoadTimer);
					}
				}, 10);
			}
			window.onload = DOMHasLoaded;
		},	
		DOMReady : function () {
			for (var i=0, il=arguments.length, funcRef; i<il; i++) {
				funcRef = arguments[i];
				if (!funcRef.DOMReady && !addedStrings[funcRef]) {
					if (typeof funcRef === "string") {
						addedStrings[funcRef] = true;
						funcRef = new Function(funcRef);
					}
					funcRef.DOMReady = true;
					functionsToCall.push(funcRef);
				}
			}
			if (DOMLoaded) {
				execFunctions();
			}
		}
	};
}();
loader.init();
