/*jslint white: true, onevar: true, browser: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */
EONE.checkForObject('EONE.utils');

EONE.utils.core = {
	/**
	 * Determines if value is an Array
	 * From pg. 61 of "JavaScript: The Good Parts", by Douglas Crockford. Copyright 2008 Yahoo! Inc, 978-0-596-51774-8
	 */
	isArray: function (value) {
		return value &&
			typeof value === 'object' &&
			typeof value.length === 'number' &&
			typeof value.splice === 'function' &&
			!(value.propertyIsEnumerable('length'));
	},

	/**
	 * Determines if value is a Node List
	 */
	isNodeList: function (value) {
		var type = Object.prototype.toString.call(value);
		if (type === "[object NodeList]" || type === "[object HTMLCollection]") {
			return true;
		}
	},
	
	addEvent: function(elm, evType, fn, useCapture) {
		useCapture = useCapture || false;

		if (elm.addEventListener) {
			elm.addEventListener(evType, fn, useCapture);
			return true;
		} else if ( elm.attachEvent ) {
			var r = elm.attachEvent('on' + evType, fn);
			return r;	
		} else { 
			elm['on' + evType] = fn;
		}
	}

	
};


EONE.utils.browser = {
	urlParser: function (url) {
		url = {
			href: url,
			protocol: '',
			host: url,
			hostname: '',
			port: '',
			pathname: '',
			search: '',
			hash: ''
		};

		if (url.host.indexOf('://') >= 0) {
			url.protocol = url.host.slice(0, url.host.indexOf('//'));
			url.host = url.host.slice(url.host.indexOf('//') + 2);
		}

		if (url.host.lastIndexOf('#') > url.host.lastIndexOf('/')) {
			url.hash = url.host.slice(url.host.lastIndexOf('#'));
			if (url.hash === '#') {
				url.hash = '';
			}

			url.host = url.host.slice(0, url.host.lastIndexOf('#'));
		}

		if (url.host.indexOf('?') >= 0) {
			url.search = url.host.slice(url.host.indexOf('?'));
			if (url.search === '?') {
				url.search = '';
			}

			url.host = url.host.slice(0, url.host.indexOf('?'));
		}

		if (url.host.charAt(url.host.indexOf('/'))) {
			url.pathname = url.host.slice(url.host.indexOf('/'));
		}

		url.host = url.host.slice(0, url.host.indexOf('/'));

		if (url.host.indexOf(':') >= 0) {
			url.port = url.host.slice(url.host.indexOf(':') + 1);
			url.hostname = url.host.slice(0, url.host.indexOf(':'));
			if (url.port === '') {
				url.host = url.hostname;
			}
		} else {
			url.hostname = url.host;
		}

		return (url);
	},

	searchArgsGetter: function (argString) {
		var args = {},
		lc1;

		argString = argString.slice(argString.indexOf('?') + 1) || argString;
		argString = argString.split('&');

		for (lc1 = 0; lc1 < argString.length; lc1 += 1) {
			argString[lc1] = argString[lc1].split('=');

			if (!args[argString[lc1][0]]) {
				args[argString[lc1][0]] = [];
			}

			args[argString[lc1][0]].push(argString[lc1][1]);
		}

		return args;
	}
};


EONE.utils.dom = {		//	Basic utilities for interaction with the DOM.
	walkTheDom: function walk(node, func) {		//	General Method for walking the DOM
												//	From pg. 35 of "JavaScript: The Good Parts", by Douglas Crockford. Copyright 2008 Yahoo! Inc, 978-0-596-51774-8
		func(node);									//	Run Function on Node
		node = node.firstChild;						//	Take the First Child of Node
		while (node) {								//	(Proceed unless the previous Node was Last Child, or had no Child Nodes.)
			walk(node, func);						//	Recursively call this method.
			node = node.nextSibling;				//	Continue the loop with the Next Sibling of Node
		}
	},

	getElementsByAttribute: function (att, value, node) {		//	General Method for retrieving Elements by Attribute Values
																//	From pg. 35 of "JavaScript: The Good Parts", by Douglas Crockford. Copyright 2008 Yahoo! Inc, 978-0-596-51774-8
																//	Extended to allow walking of a specific subset of elements (not just document.body), and to account for multiple values (such as class="a b").
		var results = [];		//	Results Array -- The final product of this function.

		node = node || document.body;		//	If the nodeStart is set, use the set value. Otherwise, use document.body.

		this.walkTheDom(node, function (node) {						//	Walk The Dom, starting on nodeStart, with the following function being run on node:
				var actual,		//	Actual = (value of node.att when node is an Element node)
				lc1;			//	Loop Counter

				if (att === 'class') {
					actual = node.nodeType === 1 && node.className;
				} else {
					actual = node.nodeType === 1 && node.getAttribute(att);
				}

				if (typeof actual === 'string' && actual !== '') {						//	If Actual has a valid value
					if (typeof value !== 'string') {					//		If Value was not specified
						results.push(node);								//			Add any Node with this Attribute, regardless of Attribute's value, to Results.
					} else {											//		Otherwise
						actual = actual.split(' ');						//			Split Actual by ' ' (account for multiple values of one attribute)
						for (lc1 = 0; lc1 < actual.length; lc1 += 1) {		//			Iterate through all values of Actual
							if (actual[lc1] === value) {					//			If Actual has a value that matches Value
								results.push(node);							//				Add Node to results.
								lc1 = actual.length;						//				Break Loop, so that Node is only added to Results once.
							}
						}
					}
				}
			});

		return results;		//	Returns array of Nodes requested.
	},

	getElementsByClassName: function (node, classname) {
		var a = [];
		var re = new RegExp('(^| )'+classname+'( |$)' );
		var els = node.getElementsByTagName("*");
		for(var i=0,j=els.length; i<j; i++) {
			if(re.test(els[i].className)) {
				a.push(els[i]);
			}
		}
		return a;
	},
	
	clearNode: function (node) {
		for (node; node.childNodes.length > 0; node) {
			node.removeChild(node.lastChild);
		}

		return node;
	}
};

EONE.utils.form = {
	getCheckedRadio: function (radios) {
		var checked = false,
			lc1;

		for (lc1 = 0; lc1 < radios.length; lc1 += 1) {
			radios[lc1].checked ? checked = radios[lc1] : checked;
		}

		return checked;
	}
};

EONE.utils.ui = {
	moveElement: function (args) {
		var x, y;
	},

	animationHScroll: function scroll(container, destination, callback) {
		var distance,
		departure = parseInt(container.style.left, 10);
	
		if (container.movement) {
			clearTimeout(container.movement);
		}
	
		if (!callback) {
			callback = function () {
					return true;
				};
		}
		if (departure === destination) {
			container.movement = null;
			callback();
			return true;
		} else {
			
			if (destination > departure) {
				distance = Math.ceil((Math.abs(departure - destination)) / 5);
			} else {
				distance = (Math.ceil(Math.abs((destination - departure)) / 5) * -1);
			}
	
			container.style.left = (departure + distance) + 'px';
			container.remainingTravel = destination - departure;
			container.movement = setTimeout(function () {
					scroll(container, destination, callback);
				}, 100);
		}
	},

	tabControl: {
		tabs: [],

		active: null,

		init: function () {
			var activeTab = false,
				lc1;

			if (window.location.hash) {
				activeTab = window.location.hash.substring(1);
			} else {
				activeTab = this.tabs[0].tabId;
			}

			for (lc1 = 0; lc1 < this.tabs.length; lc1 += 1) {
				this.tabs[lc1].onclick = function () {
						return EONE.utils.ui.tabControl.tabSwitch(this);
					};
				if (this.tabs[lc1].tabId === activeTab) {
					EONE.utils.ui.tabControl.tabSwitch(this.tabs[lc1]);
				}
			}
		},

		tabSwitch: function (newActiveTab) {
			if (this.active !== newActiveTab) {
				if (this.active !== null) {
					this.active.className = this.active.className.replace('tabActive', '');
					this.active.container.className = this.active.container.className.replace('tabActive', '');
				}
				
				newActiveTab.className += ' tabActive';
				newActiveTab.container.className += ' tabActive';

				this.active = newActiveTab;
			}

			return false;
		}
	}
};

