/**
* class utilities
* Static class with general methods that aren't specific to any code
*
* @author Flash
*/
function utilities(){}

/* define browser types */
utilities.BROWSER_IE = 1;
utilities.BROWSER_MOZ = 2;

/* set current browser type */
utilities.z_browserType = document.all ? utilities.BROWSER_IE : utilities.BROWSER_MOZ;

/**
* @return boolean
* @param integer browserType
* @desc Returns whather the browser is of type 'browserType'
*/
utilities.isBrowser = function(browserType) 
{
	return (browserType == utilities.z_browserType);
};

/**
* @return HTMLElement
* @param string elementId
* @desc Returns the element that has id specified by elementId
*/
utilities.getElement = function(elementId)
{
	if (document.all)
		return document.all(elementId);
	else if (document.getElementById)
		return document.getElementById(elementId);

	return false;
};

/**
* @return void
* @param HTMLElement element
* @param event eventName
* @param function func
* @desc Add an event to the specified element
*/
utilities.addEvent = function(element, eventName, func) 
{
	/* IE */
	if (element.attachEvent) 
	{
		element.attachEvent("on" + eventName, func);
	}
	/* Mozilla */
	else 
	{
		element.addEventListener(eventName, func, false);
	}
};

/**
* @return void
* @param HTMLElement element
* @param event eventName
* @param function func
* @desc Remove an event from the specified element
*/
utilities.removeEvent = function(element, eventName, func) 
{
	/* IE */
	if (element.detachEvent) 
	{
		element.detachEvent("on" + eventName, func);
	}
	/* Mozilla */
	else 
	{
		element.removeEventListener(eventName, func, false);
	}
};

/**
* @return void
* @param HTMLElement element
* @param boolean setVisible
* @desc Sets the visibility of an element
*/
utilities.setVisibility = function(element, isVisible) 
{
	element.style.visibility = isVisible ? "visible" : "hidden";
};

/**
* @return array
* @desc Gets the size of the current window and returns it in an array with keys width, height
*/
utilities.getWindowSize = function() 
{
	var width;
	var height;
	
	/* Mozilla */
	if(typeof(window.innerWidth) == 'number')
	{
	    width = window.innerWidth;
	    height = window.innerHeight;
  	}
  	/* IE */
  	else if(typeof(document.body.clientWidth) == 'number')
  	{
	    width = document.body.clientWidth;
	    height = document.body.clientHeight;
  	}
  	
  	return {"width": width, "height": height};
};

/**
* @return void
* @param event event
* @desc Stops the given event from bubbling
*/
utilities.cancelEvent = function(event) 
{
	event = event ? event : window.event;

	try {	
		/* IE */
		event.cancelBubble = true;
		event.returnValue = false;

		/* cancel keypress */
		if (event.keyCode)
			event.keyCode = 0;
		/* W3C */
		if (event.preventDefault)
			event.preventDefault();
		if (event.stopPropogation)
			event.stopPropogation();
	}
	catch(e) {}
};

/**
* @return mixed
* @param mixed needle
* @param array haystack
* @desc Searches the array for a given value and returns the corresponding key if successful,
* false otherwise (PHP anyone ;))
*/
utilities.arraySearch = function(needle, haystack) 
{
	for (var key in haystack)
	{
		if (haystack[key] == needle)
			return key;
	}
	
	return false;
};

/**
* @return integer
* @param integer min
* @param integer max
* @desc Returns a random number in the range of min - max
*/
utilities.rand = function(minimum, maximum)
{
	with (Math)
	{
		return (floor(random() * (maximum - minimum)) + minimum);
	}
};

/**
* @return void
* @param bollean disable
* @desc Disables right mouse click
*/
utilities.disableRightClick = function(disable)
{
	if (disable)
		utilities.addEvent(document, 'contextmenu', utilities.cancelEvent);
	else 
		utilities.removeEvent(document, 'contextmenu', utilities.cancelEvent);
};

/**
* @return HTMLRadioElement
* @param radioElem mixed
* @desc Gets the selected radio element from the given radio or radio group
*/
utilities.getSelectedRadio = function(radioElem) {
	//see if we have a single element
	if (radioElem.tagName) {
		//only return if radio and checked
		if (radioElem.tagName.toLowerCase() == 'input' && radioElem.checked) {
			return radioElem;
		}
		
		return;
	}
	
	//loop through each one in the group and get the checked one (if any)
	for(var i = 0; i < radioElem.length; i++) {
		if (radioElem[i].checked) {
			return radioElem[i];	
		}
	}
}

/**
* @return string
* @param radioElem HTMLRadioElement
* @desc Gets the selected value of the given radio
*/
utilities.getRadioValue = function(radioElem) {
	if (radio = utilities.getSelectedRadio(radioElem)) {
		return radio.value;	
	}
	
	return false;
}

/**
* Calculates the distance top of the page from the top of an element
*
* @param HTMLElement element	Element to get offset
* @return integer				The distance to top of page
*/
utilities.offsetTop = function(element) {
	var top = element.offsetTop;
	
	if (element.offsetParent) {
		top += utilities.offsetTop(element.offsetParent);
	}

	return top;
}

/**
* Calculates the distance top of the page from the bottom of an element
*
* @param HTMLElement element	Element to get offset
* @return integer				The distance to top of page
*/
utilities.offsetBottom = function(element)
{
	var top = utilities.offsetTop(element);
	
	return top + element.offsetHeight;
}

/**
* Calculates the distance left of the page from the left of an element
*
* @param HTMLElement element	Element to get offset
* @return integer				The distance to left of page
*/
utilities.offsetLeft = function(element) {
	var left = element.offsetLeft;
	
	if (element.offsetParent) {
		left += utilities.offsetLeft(element.offsetParent);
	}

	return left;
}

/**
* Calculates the distance left of the page from the right of an element
*
* @param HTMLElement element	Element to get offset
* @return integer				The distance to left of page
*/
utilities.offsetRight = function(element) {
	var left = utilities.offsetLeft(element);
	
	return left + element.offsetWidth;
}

/**
* Returns the distance that the page has scrolled vertically
*
* @return integer		Distance page has scrolled
*/
utilities.scrollVert = function() {
	if (document.body.scrollTop) {
		return document.body.scrollTop;	
	}
	else if (window.pageYOffset) {
		window.pageYOffset;
	}
	
	return 0;
}

/**
* Returns the distance that the page has scrolled horizontally
*
* @return integer		Distance page has scrolled
*/
utilities.scrollHorz = function() {
	if (document.body.scrollLeft) {
		return document.body.scrollLeft;	
	}
	else if (window.pageXOffset) {
		window.pageXOffset;
	}
	
	return 0;
}

/**
* Toggles the state of all checkboxes on a form
*
* @param string formName	Name of form 
* @param boolean checked	Whether the checkboxes will be checked or not 
*/
utilities.toggleCheckboxes = function(formName, checked) {

	var form = document[formName];
	if (! form) {
		return;
	}

	for(var i = 0; i < form.elements.length; i++) {
		if (form.elements[i].type == 'checkbox') {
			form.elements[i].checked = checked;
		}
	}
}

/**
* Returns the current url
*
* @param boolean stripHost			Whether to strip the host
* @param boolean stripParams		Whether to strip paramaters
* @return string					Current url
*/
utilities.currentUrl = function(stripHost, stripParams) {
	var url = window.location.href;

	if (stripHost) {
		url = url.replace(/^http[s]?:\/\/[^\/]*/, '');
	}

	if (stripParams) {
		url = url.replace(/\?.*$/, '');
	}

	return url;
}

/**
* Appends query to the end of the url
*
* @param string url				Base url 
* @param string query			Query string no including initial ? or &
* @return string				Url with query appended to the end
*/
utilities.appendUrl = function(url, query) {

	//we are just deciding whether we should use & or ? as the glue
	return url + (url.match(/\?/) ? '&' : '?') + query;
}

/**
* Moves the caret with the given input element
* This will also move focus of course
*
* @param HTMLElement input		Input element
* @param integer position		New position of caret
*/
utilities.moveCaret = function(input, position){
	try {
		//default position to end of string
		if (typeof(position) == 'undefined')
			position = input.value.length;

		var tr = input.createTextRange();
		tr.collapse(true);
		tr.moveEnd('character', position);
		tr.moveStart('character', position);
		tr.select();
	}
	catch(e){}
};

/**
* Gets  the current caret position relative to it's text
*
* @return integer			Position of caret
*/
utilities.getCaretPos = function(){
	return Math.abs(document.selection.createRange().moveStart("character", -1000000));
};

/**
* Repeats the current string 
*
* @param integer num		Number of times to repeat string
*/
String.prototype.repeat = function(num){
	return new Array(num + 1).join(this);
};
