/* CORE SCRIPTS
 * Required functionality
 * 1.0
 
 * SCRIPT CHANGES (Eg. Date (dd/mm/yyyy), Name (Tom.McCourt), Change (function name))
 *
 * 13/07/2007, Tom.McCourt, Created
------------------------------------------------------------*/

/* Load
------------------------------*/
var Event = {	
	onload: [],
	loaded: function() {
		if (arguments.callee.done) return;
		arguments.callee.done = true;
		for (i = 0;i < Event.onload.length;i++) Event.onload[i]();
	},
	pageLoad : function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != "function") {
			window.onload = func;
		} else {
			window.onload = function() {
				oldonload();
				func();
			}
		}
	},
	domLoad : function(fireThis) {
		this.onload.push(fireThis);
		if (document.addEventListener) 
			document.addEventListener("DOMContentLoaded", Event.loaded, null);
		if (/KHTML|WebKit/i.test(navigator.userAgent)) { 
			var _timer = setInterval(function() {
				if (/loaded|complete/.test(document.readyState)) {
					clearInterval(_timer);
					delete _timer;
					Event.loaded();
				}
			}, 10);
		}
		/*@cc_on @*/
		/*@if (@_win32)
		var proto = "src='javascript:void(0)'";
		if (location.protocol == "https:") proto = "src=//0";
		document.write("<scr"+"ipt id=__ie_onload defer " + proto + "><\/scr"+"ipt>");
		var script = document.getElementById("__ie_onload");
		script.onreadystatechange = function() {
		    if (this.readyState == "complete") {
		        Event.loaded();
		    }
		};
		/*@end @*/
		this.pageLoad(Event.loaded);
	},
	// Add event - For events fo not prefix the event name with 'on'
	add: function(e, type ,fn) {
		if (e.attachEvent) {
		e['e' + type + fn] = fn;
		e[type + fn] = function() {e['e' + type + fn](window.event);}
		e.attachEvent('on' + type, e[type + fn]);
		} else
		e.addEventListener(type, fn, false);
	},
	// Remove event - For events fo not prefix the event name with 'on'
	remove: function(e, type, fn) {
		if (e.detachEvent) {
		e.detachEvent('on' + type, e[type + fn]);
		e[type + fn] = null;
		} else
		e.removeEventListener(type, fn, false);
	}
};

/* Utils
 * Commonly used methods
------------------------------*/
// Fix IE CSS BG flicker problem
function flickerFix() {
	try {
		document.execCommand("BackgroundImageCache", false, true);
	} catch(e) {}
}

function convertToBoolean(property) {
	return (property == "true")
}

// Empty an element
function emptyElement(e) {
	if (e) {
		while (e.firstChild) {
			e.removeChild(e.firstChild);
		}
	}
}

// Insert element after a node as next sibling
function insertAfter(node, referenceNode) {
	var parent = referenceNode.parentNode;
	parent.insertBefore(node, referenceNode.nextSibling);
}

// Remove a class from an object
function removeClass(e, cssClass) {
	if (e.className) {
		var classList = e.className.split(' ');

		cssClass = cssClass.toUpperCase();

		for (var i = 0; i < classList.length; i++) {
			if (classList[i].toUpperCase() == cssClass) {
				classList.splice(i, 1);
				i--;
			}
		}
		e.className = classList.join(' ');
	}
}

/* URL
------------------------------*/
var UrlUtils = {
	// Will return the web path as defined in config based on the protocol	
	absoluteWebPath : function(url) {
		var protocol = Config.absoluteHttpPath;
		if (this.protocol() == "https") {
			protocol = Config.absoluteHttpsPath;
		}
		return (url) ? protocol + url : protocol;
	},
	// Returns either the "HTTP" or "HTTPS" protocol
	protocol : function() {
		var url = location.protocol;
		return url.substring(0, url.indexOf(":")).toLowerCase();
	},
	// Return a property value from the page URL
	qs : function(param) {
		var url = location.href;
		if (url.indexOf("?") != -1) {
			var qs = url.substring(url.indexOf("?") + 1);
			var pairs = qs.split("&");
			var hash = [], key, value, pair;
			for (var i = 0, c = pairs.length; i < c; i++) {
				pair = pairs[i].split("=");
				if (param && param == pair[0]) {
					return pair[1].toString();
				}
				hash[pair[0]] = pair[1];
			}
			if (hash.length > 0) {
				return hash;
			} else {
				return null;
			}
		}
	},
	newURL : function(url, keys, values) {
		var link = url;
		if (keys && values) {
			var qs = "";
			for (var i = 0, c = keys.length; i < c; i++) {
				qs += "&" + encodeURIComponent(keys[i]) + "=" + encodeURIComponent(values[i]);
			}
			qs = "?" + qs.substring(1, qs.length);
		}
		return link + qs
	},
	// Redirect or delayed redirect
	// url : url to redirect to
	// t : time in seconds
	redirect : function(url, t) {
		if (t) {
			self.setTimeout("self.location.href = '" + url + "';",t * 1000);
		} else {
			self.location = url;
		}
	},
	// Replace a value in a URL
	// url: url to search
	// prop: property you want change value of
	// value: new value you want to replace with
	replaceValue : function(url, prop, value) {
		if (url.indexOf(prop) > 0) {
			var firstPart = url.substring(0, url.indexOf(prop) + prop.length + 1);
			var secondPart = url.substring(url.indexOf(prop) + prop.length + 1);
			if (secondPart.indexOf("&") > 0) {
				secondPart = secondPart.substring(secondPart.indexOf("&"));
				return firstPart + encodeURIComponent(value) + secondPart;
			} else {
				return firstPart + encodeURIComponent(value);
			}
		} else {
			return null;
		}
	}
};

/* Pop windows and new pages
------------------------------*/
var PopUp = {
	topPos : 0,
	leftPos : 0,
	height : 400,
	width : 600,
	settings : null,
	win : null,
	winName : "pop",
	getURL : function(e) {
		if (typeof(e) == "object") {
			return e.href
		} else {
			return e;
		}
	},
	win : null,
	// Opens a new browser window
	newWindow : function(e, options) {
		return this.openWindow(e, {popup: "window"});
	},
	// Opens a pop up window
	newPopUp : function(e, options) {
		if (options) {
			options.popup = "popup";
		} else {
			options = {popup: "popup"};
		}
		return this.openWindow(e, options);
	},
	// General new window 
	openWindow : function(e, options) {
		if (options) {
			this.height = (options.height) ? options.height : this.height;
			this.width = (options.width) ? options.width : this.width;
		}
		this.leftPos = (screen.width) ? (screen.width - this.width) / 2 : 0;
		this.topPos = (screen.height) ? (screen.height - this.height) / 2 : 0;

		this.settings = (options && options.popup == "popup") ? "height=" + this.height + ",width=" + this.width + ",top=" + this.topPos + ",left=" + this.leftPos + ",scrollbars=yes,noresize" : "";

		var link = this.getURL(e);

		this.win = window.open(link, this.winName, this.settings);
		this.win.focus();
		return false;
	},
	// Finds links that have a rel attribute of value and applies a function to them
	hookup : function(value, func) {
		var items = document.getElementsByTagName("a");
		for (var i = 0, c = items.length; i < c; i++){
			if (items[i].getAttribute("rel") == value) {
				items[i].onclick = func;
			}
		}
	}
};

/* Forms
------------------------------*/
var FormUtils = {	
	// Pass in a drop-down object, json data in the above format and a selected value
	populateDropDown : function(e, json, selected) {	
		if (!e) { return; }	
		emptyElement(e);
		for (var i = 0, c = json.length; i < c; i++) {
			e.options[i] = new Option(json[i].property, json[i].value);
			if (selected && json[i].value == selected) {
				e.options[i].selected = true;
			}
		}
		return;
	},
	assignButton : function(e, el, buttonId) {
		var code;
		if (window.event) {
		code = e.keyCode;
		} else if (e.which) {
			code = e.which;
		}
		if (code == 13) {
			var button = document.getElementById(buttonId);
			if (button) {
				button.focus();
				return false;
			}
		}
		return true;
	},
	queryString : "",
	addQueryString : function(param, value) {
		var preffix = (this.queryString.length > 0) ? "&" : "" ;
		this.queryString += preffix + encodeURIComponent(param) + "=" + encodeURIComponent(value);
	},	
	// If ID of input is not know use the name
	getOption : function(el, container, collectValues) {
		var wrapper = (!container || container == 'document') ? document : document.getElementById(container);
		var input = wrapper.getElementsByTagName("input");
		for (var i = 0, c = input.length; i < c; i++) {
			if (input[i].name && input[i].name == el) {
				return this.getValue(input[i].id, container, collectValues)
			}
		}	
	},
	// Assign querystring params with either array list of id's or container id (group/name for radio buttons)
	// The container is optional for an array of id's - it helps narrow down the search for radio button groups
	collect : function(collection, container) {
		this.queryString = "";
		var container;
		if (typeof(collection) == 'object') {
			container = (!container || container == 'document') ? document : document.getElementById(container);
			for (var i = 0, c = collection.length; i < c; i++) {
				var el = document.getElementById(collection[i]);
				if (el) {
					this.getValue(el, container);	
				}
			}
		} else {
			container		= document.getElementById(collection);
			var inputItem	= container.getElementsByTagName("input");
			var selectItem	= container.getElementsByTagName("select");	
			var textItem	= container.getElementsByTagName("textarea");
			
			for (var i = 0, c = inputItem.length; i < c; i++) {
				this.getValue(inputItem[i], container, true);	
			}
			for (var i = 0, c = selectItem.length; i < c; i++) {
				this.getValue(selectItem[i], container, true);	
			}
			for (var i = 0, c = textItem.length; i < c; i++) {
				this.getValue(textItem[i], container, true);	
			}
		}
		return this.queryString;
	},
	// Gets a form elements and adds the value and if onto the params
	getValue : function(el, container, collectValues) {	
		el = (typeof(el) == "string") ? document.getElementById(el) : el;
		container = (!container || container == 'document') ? document : document.getElementById(container);
		var n = el.id, v = null;
	
		switch (el.nodeName.toLowerCase()) {
			case 'input':
				switch (el.getAttribute('type').toLowerCase()) {
					case 'text':
						v = el.value;
					break;
					case 'checkbox':
						if (el.checked) {
							v = el.value;
						}
					break;
					case 'radio':
						n = el.name;
						var button = container.getElementsByTagName('input');
						for (var j = 0, d = button.length; j < d; j++) {
							if (button[j].name == el.name && button[j].checked) {
								v = button[j].value;
								break;
							}
						}	
					break;
					case 'password':
						v = el.value;
					break;
					case 'hidden':
						v = el.value;
					break;
				}
			break;
			case 'select':
				if (el.multiple) {
					l = [];
					for (var j = 0, d = el.length; j < d; j++) {
						if (el.options[j].selected) {
							l.push(el.options[j].value);
						}
					}
					v = l.join('|');
				} else {
					v = el.value;
				}
			break;
			case 'textarea':
				v = el.value;
			break;
		}
		if (n != null && n != '' && v != null && v != '') {
			if (collectValues) {
				this.addQueryString(n, v);
			} else {
				return v;
			}
		}
	}
};

/*	Cookies - yum
 *	Can use single short methods, or for long values use a splitter
------------------------------ */
var Cookie = {
	maxLength : 3000,
	splitter : '||',
	get : function(name) {
		return this.getValues(name + '_0', true);	
	},
	getValues : function(name, split) {
		var cookie = this.getValue(name);
		if (cookie) {
			var splitterLength = this.splitter.length;
			var splitter = cookie.indexOf(this.splitter);
			if (splitter > 0) {
				return cookie.substr(0, splitter - 1) + this.getValues(cookie.substr(splitter + splitterLength), true);
			} else {	
				return cookie;
			}
		}
	},
	getValue : function(name) {
		var arg = name + "=";
		var alen = arg.length;
		var clen = document.cookie.length;
		var i = 0;
		while (i < clen){
			var j = i + alen;
			if (document.cookie.substring(i, j) == arg){
				return this.getOffset(j);
			}
			i = document.cookie.indexOf(" ", i) + 1;
			if (i == 0) break;
		}
		return null;
	},
	getOffset : function(offset) {
		var endstr = document.cookie.indexOf (';', offset);
		if (endstr == -1)
		endstr = document.cookie.length;
		return unescape(document.cookie.substring(offset, endstr));
	},
	set : function(name, value) {
		var tray = [];
		for (var i = 0, count = value.length; i < count; i += this.maxLength) {
			if ((i + this.maxLength) > count) {
				tray.push(value.substr(i));
			} else {
				tray.push(value.substr(i, this.maxLength + 1));
			}
		}
		var bite;
		for (var i = 0, count = tray.length; i < count; i++) {
			bite =  (i + 1 != count) ? this.splitter + name + '_' + (i + 1) : '';
			this.setValue(name + '_' + i, tray[i] + bite);
		}
	},
	setValue : function(name, value) {
		var never = new Date();
		never.setTime(never.getTime() + 2000 * 24 * 60 * 60 * 1000);
		var expString = '; expires=' + never.toGMTString();
		var newpath = '; path=/';
		document.cookie = name + '=' + escape(value) + expString + newpath;
	},
	kill : function(name) {
		var expString = '; expires=Thu, 01-Jan-1970 00:00:01 GMT';
		var newpath = '; path=/';
		document.cookie = name + '=' + '' + expString + newpath;
	}
};

/* Position elements
------------------------------*/
var Position = {
	// Internal use to get object from Id if supplied
	getElement : function(e) {
		if (typeof(e) == "string") {
			return document.getElementById(e);
		} else if (typeof(e) == "object") {
			return e;
		} else {
			return null;
		}
	},
	getLeft : function(e) {
		e = this.getElement(e);
		var curLeft = 0;
		if (e.offsetParent) {
			while (e.offsetParent) {
				curLeft += e.offsetLeft
				e = e.offsetParent;
			}
		} else if (e.x) {
			curLeft += e.x;
		}
		return curLeft;
	},
	getTop : function(e) {
		e = this.getElement(e);
		var curTop = 0;
		if (e.offsetParent) {
			while (e.offsetParent) {
				curTop += e.offsetTop
				e = e.offsetParent;
			}
		} else if (e.y) {
			curTop += e.y;
		}
		return curTop;
	},
	// e (object) - the element you want to position
	// el (object) - the element you want to anchor another element to
	// options (object) - options e.g. {"offsetX": 10, "offsetY": 50}
	// Position.anchor("basket-message", "add-to-basket", {"offsetX": 10, "offsetY": 50});
	anchor : function(e, el, options) {
		e = this.getElement(e);
		el = this.getElement(el);

		var elY = this.getTop(el);
		var elX = this.getLeft(el);

		if (e && el) {
			if (options.top) e.style.top			= (options.offsetY) ? options.offsetY + elY + "px" : elY + "px";
			if (options.left) e.style.left			= (options.offsetX) ? options.offsetX + elX + "px" : elX + "px";
			if (options.position) e.style.position	= options.position;
		}
	},
	// e (object) - the element you want to position
	// options (object) - options e.g. {"top": Position.getTop("add-to-basket"), "offsetX": 10, "offsetY": 50}
	// Position.anchor("basket-message", "add-to-basket", {"offsetX": 10, "offsetY": 50});
	position : function(e, options) {
		if (e) {
			if (options.top) e.style.top			= (options.offsetY) ? options.offsetY + options.top + "px" : options.top + "px";
			if (options.right) e.style.right		= (options.offsetX) ? options.offsetX + options.right + "px" : options.right + "px";
			if (options.bottom) e.style.bottom		= (options.offsetY) ? options.offsetY + options.bottom + "px" : options.bottom + "px";
			if (options.left) e.style.left			= (options.offsetX) ? options.offsetX + options.left + "px" : options.left + "px";
			if (options.position) e.style.position	= options.position;
			//Debug.w("Position: " + e.id + ", top: " + options.top + ", right: " + options.right + ", bottom: " + options.bottom + ", left: " + options.left);
		}
	}
};
