/**
* Method: GetElementById
* 
* @param	target
*/
function getElement (target) {
	
	return (typeof target == "object") ? target : document.getElementById(target);

}

/**
* Method: getNodeByName
* 
* @param	target
* @param	index
*/
function getNodeByName (target, index) {
	
	return document.getElementsByTagName(target).item((index == undefined) ? 0 : index);

}


/**
* Method: getNodesByName
* 
* @param	target
* @param	index
*/
function getNodesByName (target) {
	
	return document.getElementsByTagName(target);

}

/**
* Method: ObjRect
* 
* @param	id
*/
function ObjRect (id) {
	
	//	Add properties to ObjRect Object
	this.id = getElement(id);
	//this._x = this.id.offsetLeft;
	this._x = (this.id.parentNode.offsetLeft > this.id.offsetLeft) ? this.id.parentNode.offsetLeft + this.id.offsetLeft : this.id.offsetLeft;
	this._y = (this.id.parentNode.offsetTop > this.id.offsetTop) ? this.id.parentNode.offsetTop + this.id.offsetTop : this.id.offsetTop;
	this._width = this.id.offsetWidth;
	this._height = this.id.offsetHeight;
	
	//alert("id: " + this.id.id + "\n " + "tag: " + this.id.tagName + "\n " + "_x: " + this._x + "\n " + "_y: " + this._y + "\n " + "_width: " + this._width + "\n " + "_height: " + this._height);
	
}

/**
* Constructor: StyleElement
* 
* @param	id
* @param	attributes
* @param	css
* @param	location
*/
function StyleElement (id, attributes, css, location) {
	
	//	Get User Agent
	var ua = navigator.userAgent.toLowerCase();
	
	//	StyleElement Properties
	this.element = document.createElement("style");
	this.object = document.getElementById(id);
	this.cssText = (css.text == undefined) ? "" : css.text;
	this.cssTextIE = (css.textIE == undefined) ? "" : css.textIE;
	this.locElement = (location.id == undefined) ? document.getElementsByTagName(location.element).item((location.index == undefined) ? 0 : location.index) : document.getElementById(location.id);
	this.locInsert = location.insert;
	this.locPosition = location.position;
	
	//	Add if style does not already exsist
	if (this.object == null || this.object == undefined) {
		
		//	Add attributes to element
		for (var item in this.attributes) {
			
			this.element[item] = this.attributes[item];
			
		}
		
		//	Add id for tracking purposes
		//	Insert style element into location
		this.element.id = id;
		this.locElement[this.locInsert](this.element, this.locElement[this.locPosition]);
		
		//	Add css to style element
		if (ua.indexOf("msie") != -1) {
			
			//	IE Only
			this.element.styleSheet.cssText = this.cssText + "\n" + this.cssTextIE;
			
		} else {
			
			//	Firefox, Mozilla, Safari
			var textElement = document.createTextNode(this.cssText);
			this.element.appendChild(textElement);
			
		}
		
	}
}

/**
* Constructor: Class
* 
* @param	id
* @param	defaultClass
* @param	classes
*/
function Class (id, defaultClass, classes) {
	
	if (getElement(id) != null) {
		
		this.id = getElement(id);
		
		if (this.id.className == "") {
			
			this.id.className = defaultClass + " " + classes;
			
		} else if (this.id.className != "" && this.id.className.indexOf(defaultClass) == -1) {
			
			this.id.className = defaultClass + " " + classes + " " + this.id.className;
			
		} else if (this.id.className != "" && this.id.className.indexOf(defaultClass) != -1) {
			
			this.id.className = this.id.className + " " + classes;
			
		}
		
	}
	
}

/**
* Constructor: Accordion
* 
* @param	id
* @param	attributes
* 
* @see	SytleElement.js
*/
function Accordion (id, attributes) {
	
	var ua = navigator.userAgent.toLowerCase();
	
	if (getElement(id) != null) {
		
		//	Accordion properties
		this.id = getElement(id);
		this.instance = "";
		this.name = id;
		this.parent = this.id.parentNode;
		this.attributes = attributes;
		this.attributes.event = (attributes.event == undefined) ? "onmousedown" : attributes.event;
		this.attributes.autoHide = (attributes.autoHide == undefined) ? false : attributes.autoHide;
		this.attributes.type = (attributes.type == undefined) ? "" : attributes.type;
		this.currObj = "";
		this.prevObj = "";
		this.targetRef = (ua.indexOf("msie") != -1) ? "srcElement" : "target";
		
		var src = (document.getElementById("jsAccordion") == null) ? "../js/accordion" : document.getElementById("jsAccordion").src;
		this.loc = new Object();
		this.loc.parse = src.split("/");
		this.loc.file = this.loc.parse.pop();
		this.loc.host = this.loc.parse.join("/");
		
		//	Add default style if it has not been imported, do so now.
		//	Create style element and insert as the first child of head element
		var styleID = "accordion-css";
		var styleMedia = "all";
		var styleType = "text/css";
		var css = "@import url('" + this.loc.host + "/accordion.css');"
		var cssIE = "@import url('" + this.loc.host + "/accordion_ie.css');"
		var accordionStyle = new StyleElement(styleID, {media: styleMedia, type: styleType}, {text: css, textIE: cssIE}, {element: "head", insert: "insertBefore", position: "firstChild"});
		
		
		//	Add class to "Accordion instance"
		var defaultClass = "accordion-list";
		var accordionClass = new Class(this.id, defaultClass, [this.attributes.type]);
		
		/**
		* Method: show
		* Hide target object
		* 
		* @param	target
		*/
		this.show = function (target) {
			
			target.state = !target.state;
			target.className = (target.state) ? "show" : "hide";
			
		}
		
		/**
		* Method: hide
		* Hide target object
		* 
		* @param	target
		*/
		this.hide = function (target) {
			
			target.className = "hide";
			target.state = false;
			
		}
		
		/**
		* Method: showHide
		* Show or Hide objects with class of "show" or "hide" inside of "this.currObj"
		* 
		* @param	event
		*/
		this.showHide = function (event) {
			
			if (event[this.targetRef].tagName.toLowerCase() == "a") {
				/*
				var itemMouseOutEvent = (ua.indexOf("msie") != -1) ? "onmouseout" : "event";
				this.currObj.onmouseout = function (itemMouseOutEvent) {
					
					mainMenu.show(this);
					
				}
				*/
				
				if (event[this.targetRef].parentNode.parentNode.className != "show" || event[this.targetRef].parentNode.parentNode.className == "") {
					
					this.hide(this.currObj);
					
					for (var item = 0; item < event[this.targetRef].parentNode.childNodes.length; item++) {
						
						if (event[this.targetRef].parentNode.childNodes[item].className == "show" || event[this.targetRef].parentNode.childNodes[item].className == "hide") {
							
							this.prevObj = this.currObj;
							this.hide(this.prevObj);
							
							this.currObj = event[this.targetRef].parentNode.childNodes[item];
							this.show(this.currObj);
							/*
							var itemMouseOutEvent = (ua.indexOf("msie") != -1) ? "onmouseout" : "event";
							this.currObj.onmouseout = function (itemMouseOutEvent) {
								
								mainMenu.hide(this);
								
							}
							*/
							
							break;
							
						}
						
					}
					
				}
				
			} else if (event[this.targetRef] != undefined && event[this.targetRef].hasChildNodes() && event[this.targetRef].childNodes.length > 1) {
				
				for (var item = 0; item < event[this.targetRef].childNodes.length; item++) {
					
					if (event[this.targetRef].childNodes[item].className == "show" || event[this.targetRef].childNodes[item].className == "hide") {
						
						this.prevObj = this.currObj;
						this.hide(this.prevObj);
						
						this.currObj = event[this.targetRef].childNodes[item];
						this.show(this.currObj);
						
						break;
						
					}
					
				}
				
			}
			
		}
		
		/**
		* Method: hideOutsideCoords 
		* Hide object when mouse goes outside "this.id" object
		* 
		* @param	event
		*/
		this.hideOutsideCoords = function (event) {
			
			var mouse = new Mouse(event);
			var target = new ObjRect(this.id);
			
			if (mouse._x > target._x + target._width || mouse._x < target._x || mouse._y > target._y + target._height || mouse._y < target._y) {
				
				this.hide(this.currObj);
				
			}
			
		}
		
		/**
		* Method: addEvents
		* 
		*/
		this.addEvents = function (AccordionInstance) {
			
			this.instance = AccordionInstance;
			
			//	Auto hide open item
			if (this.attributes.autoHide) {
				
				//	IE Only
				if (ua.indexOf("msie") != -1) {
					
					document.body.onmouseover = function (onmouseover) {
						
						if (event[AccordionInstance.targetRef].tagName.toLowerCase() == "body") {
							
							AccordionInstance.hide(AccordionInstance.currObj);
							
						}
						
					}
					
				}
				
				//	Firefox, Mozilla, Safari
				if (ua.indexOf("msie") == -1) {
					
					document.body.onmouseover = function (event) {
						
						/*
						if (event[AccordionInstance.targetRef].tagName.toLowerCase() == "body") {
							AccordionInstance.hide(AccordionInstance.currObj);
							//AccordionInstance.clearTime = setTimeout(AccordionInstance.id + ".hide(" + AccordionInstance.currObj + ")", 500);
							
						}
						*/
						/*
						var anchors = AccordionInstance.id.getElementsByTagName("a");
						var lis = AccordionInstance.id.getElementsByTagName("li");
						var uls = AccordionInstance.id.getElementsByTagName("ul");
						
						for (var item = 0; item < anchors.length; item++) {
							
						}
						*/
					}
					
				}
				
			}			
			
			//	Mouse event for each item
			var accordionMouseEvent = (ua.indexOf("msie") != -1) ? this.attributes.event : "event";
			this.id[this.attributes.event] = function (accordionMouseEvent) {
				
				//clearTimeout(AccordionInstance.clearTime);
				AccordionInstance.showHide((ua.indexOf("msie") != -1) ? event : accordionMouseEvent);
				
			}
			
			this.id.onfocusin = function (onfocusin) {
				
				AccordionInstance.showHide(event);
				
			}
			
			this.id.onfocus = function (event) {
				
				AccordionInstance.showHide(event);
				
			}
			
		}
		
	}
	
}
