
/**
 * Singleton object of commonly used functions
 * @class Commonly needed methods
 */
W.Util = new function()
{

	/**
	 * check if we're using Safari
	 */
	this.isSafari = navigator.userAgent.indexOf('Safari') != -1 ? true : false;
	
	
	
	/**
	 * Returns an HTMLElement
	 * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
	 * @return {HTMLElement} A DOM reference to an HTML element.
	 */
	this.$ = function(id) {
		if (typeof id == 'string') { // accept object or id
			id = document.getElementById(id);
		}
	
		return id;
	};
	
	
	
	/**
	 * Determines the given style property for an elemnt taking the stylesheets into account
	 * Adapted from "The JavaScript Anthology" by James Edwards & Cameron Adams
	 * @param {HTMLElement | String} element Element who's styles we're interested in
	 * @param {String} property The style property we're interested in
	 * @return {String} Value of the style property
	 */
	this.getStyle = function(element, property)
	{
		var computedStyle	= null;
		element = this.$(element);
		
		if (element.currentStyle) {
			computedStyle = element.currentStyle;
		} else {
			computedStyle = document.defaultView.getComputedStyle(element, null);
			if (!computedStyle) { return false;	}	// Safari 1.3 will not return a valid computedStyle if the display is none
		}
		
		return computedStyle[property];
	};
	
	
	
	/**
	 * Returns an arry of elements that have th same class
	 * Adapted from a script originally written by Dustin Diaz http://www.dustindiaz.com/getelementsbyclass/
	 * @param {String} searchClass class name to search for
	 * @param {String} property The style property we're interested in
	 * @return {String} Value of the style property
	 */
	this.getElementsByClassName = function(searchClass, tag, node) {
		
		var classElements = [];
		
		node	= W.Util.$(node) || document.body;
		tag		= tag || '*';
		
		var els 	= node.getElementsByTagName(tag);
		var elsLen 	= els.length;
		var pattern = new RegExp('(^|\\s)' + searchClass + '(\\s|$)');
		
		for (i = 0, j = 0; i < elsLen; i++) {
			if (pattern.test(els[i].className)) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	};
	
	
	
	this.getWindowSize = function()
	{
		var size = {x: 0, y: 0};
		
		if (window.innerWidth) {
			size.x = window.innerWidth;
			size.y = window.innerHeight;
		} else if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth !== 0) {
			size.x = document.documentElement.clientWidth;
			size.y = document.documentElement.clientHeight;
		} else {
			size.x = document.getElementsByTagName('body')[0].clientWidth;
			size.y = document.getElementsByTagName('body')[0].clientHeight;
		}
		
		return size;
	};
	
	
	
	this.addClassname = function(node, className)
	{
		node	= this.$(node);
		if (node.className.indexOf(className) == -1) {
			node.className = node.className + ' ' + className;
		}
	};
	
	
	
	this.removeClassname = function(node, className)
	{
		node		= this.$(node);
		var regex	= new RegExp('\\b ?' + className + '\\b');
		node.className = node.className.replace(regex, '');
	};
	
	
	
	this.changeClassname = function(node, className)
	{
		if (!node) { return; }
		
		var elements = [];
		
		if (typeof node == 'string') {
			node	= this.$(node);
			elements.push(node);
		} else {
			elements = node;
		}
		
		for (var obj in elements) {
			elements[obj].className = className;
		}
	};
	
}();
