/*** please document (yeah, haha)
* todo: 
*	convert to functions with prototypes for all other functions within the object - paul 6/29/2011
*  	like the other ones
***/
var sna = {
	/*** html elements ***/
	elems:[],
	options: [], // for optional stuff you want to pass in from external functions
	docBody: document.body, // do something with this later
	setOptions: function(key, val) {
			this.options[key] = val;
			return this;
	},
	getOptions: function(key) {
		return this.options[key];
	},
	getById:function() {
		var tempElems = []; //temp Array to save the elements found
		for (var i = 0; i < arguments.length; i++) {
			if (typeof arguments[i] === 'string') { //Verify if the parameter is an string
				tempElems.push(document.getElementById(arguments[i])); //Add the element to tempElems
			}
		}
		this.elems = tempElems; //All the elements are copied to the property named elems
		return this; //Return this in order to chain
		
	},
	getByTagname:function() {
		var tempElems = []; //temp Array to save the elements found
		for (var i = 0; i < arguments.length; i++) {
			if (typeof arguments[i] === 'string') { //Verify if the parameter is an string
				tempElems.push(document.getElementsByTagName(arguments[i])); //Add the element to tempElems
			}
		}
		this.elems = tempElems; //All the elements are copied to the property named elems
		return this; //Return this in order to chain
	},
	getByClassname: function(className) {
		// set the tempElems like before
		var tempElems = []; //temp Array to save the elements found
		
		// loop over all of the DOM for anything with the classname equal to arguments[0] ( changed to pass variable className )
		elements = sc.getElementsByTagName('*');
		for( i=0; i < elements.length; i++ ){
			curClass = elements[i].getAttribute('class');
			if(curClass != null){
				curClass = curClass.split(" ");
				for( j=0; j < curClass.length; j++){
					if(curClass[j] === className){
						tempElems.push( elements[i] );
						break;
					}
				}
			}
		}
		this.elems = tempElems; //All the elements are copied to the property named elems
		return this; //Return this in order to chain
	},
	getElements: function(str) { // this one will get all the elements based on searching through the dom using querySelectorAll
		
		var tempElems = []; //temp Array to save the elements found
		if (document.querySelectorAll) {
			tempElems.push(document.querySelectorAll(str)); //All the elements are copied to the property named elems
		} else { // ie7 stuff here
			// this is going to have to use document.getElementById and then loop through the results to find what you are looking for (ugh, IE7!)
			// really flush this out later
			// I know I only use #navList > li but that is confusing
			tempNodes = document.getElementById("navList");
			tempLIs = tempNodes.parentNode.getElementsByTagName("li");
			for (i=0; i<tempLIs.length; i++) {
				/* if (tempLIs[i].children.length == 1) {
					
				} */
				if(tempLIs[i].parentElement.className.indexOf("secondary") == -1) { // the second level nav <ul>'s have a class name of secondary
					tempElems.push(tempLIs[i]);
				}
			}
		}
		this.elems = tempElems;
		return this;
		
	},
	getByNode: function(node) {
		var tempElems = []; //temp Array to save the elements found
		tempElems.push(node);
		this.elems = tempElems;
		return this;
	},
	
	getClassname: function() {
		// only worry about the first one 
		// and only call this on getById().getClassname() type thing
		return this.elems[0].className;
	},
	setClassname: function(str) {
		this.elems[0].className = str;
		return this;
	},
	getValue: function() {
		return this.elems[0].value;
	},
	setValue: function(str) {
		this.elems[0].value = str;
		return this;
	},
	activeNav: false,
	activeSubnav: false,
	setActiveNav: function(e) {
		this.activeNav = e;
		this.activeSubnav = e.parentNode.parentNode.children[1];
		//console.log(this.activeNav);
	},
	getClientHeight: function() {
		return this.elems[0].clientHeight;
	},
	setClientHeight: function(newHeight) {
		document.getElementById(this.elems[0].id).style.height = newHeight + "px";
	},
	getClientWidth: function() {
		return this.elems[0].clientWidth;
	},
	setClientWidth: function(newWidth) {
		document.getElementById(this.elems[0].id).style.width = newWidth + "px";
		console.log(this.elems[0]);
	},
	
	/*** events ***/
	// this function is for adding event listeners (onclick etc)
	on: function(action, callback) {
		/* had to add a loop in case you are using the getByClassname or getByTagname */
		if (this.elems[0].addEventListener) {
			for(var i = 0;i<this.elems.length;i++){
				this.elems[i].addEventListener(action,callback,false);
			}
		} else if (this.elems[0].attachEvent) {
			for(var i = 0;i<this.elems.length;i++){
				this.elems[i].attachEvent('on'+action,callback); // IE
			}
		}
		return this;
	},
	// DOM is ready
	isReady: false,
	// A counter to track how many items to wait for before
	// the ready event fires.  (snagged from jQuery)
	readyWait: 1,
	// Hold (or release) the ready event
	holdReady: function( hold ) {
		if ( hold ) {
			this.readyWait++;
		} else {
			this.ready( true );
		}
	},
	loadFunctionList: false,
	// Handle when the DOM is ready
	loadReady: function(wait) {
		s = this;
		// Either a released hold or an DOMready/load event and not yet ready
		if ( (wait === true && !--s.readyWait) || (wait !== true && !s.isReady) ) {
			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
			if ( !document.body ) {
				return setTimeout( s.loadReady, 1 );
			}
			
			// Remember that the DOM is ready
			s.isReady = true;
			
			// If a normal DOM Ready event fired, decrement, and wait if need be
			if ( wait !== true && --s.readyWait > 0 ) {
				return;
			}
			
			// If there are functions bound, to execute
			s.loadFunctions();
			
		}
	},
	loadFunctions: function() {
		if (typeof this.loadFunctionList == "function") {
			// figure this out later, load the functions passed
			this.loadFunctionList();
		}
	},
	
	ready: function(fn) {
		s = this;
		this.loadFunctionList = fn; // sort this out later
		
		
		// Mozilla, Opera and webkit nightlies currently support this event
		if ( document.addEventListener ) {
			// Use the handy event callback
			document.addEventListener( "DOMContentLoaded", function() { s.loadReady(); }, false );
			
			// A fallback to window.onload, that will always work - do not use this
			//window.addEventListener( "load", s.loadReady(), false );
			
			// If IE event model is used
		} else if ( document.attachEvent ) {
			// ensure firing before onload,
			// maybe late but safe also for iframes
			document.attachEvent( "onreadystatechange", function() { s.loadReady(); } );
			
			// A fallback to window.onload, that will always work - do not use this
			//window.attachEvent( "onload", s.loadReady() );
			
		}
	}
	
	
	
};

// and this
var addWindowEvent = function(type, eventHandle) {
	if ( window.addEventListener ) {
        window.addEventListener( type, eventHandle, false );
    } else if ( window.attachEvent ) {
        window.attachEvent( "on" + type, eventHandle );
    }
};


// page stuff starts here
sna.ready(init);

var NodeList = {
			toArray: function(list) {
				var array= new Array(list.length);
				for (var i= 0, n= list.length; i<n; i++)
					array[i]= list[i];
					return array;
				}
		};

function init() {
	sna.getById("searchBox").on('focus', reset_search).on('blur', reset_search);
	reset_search_text(); // this is needed in case someone hits the back button
	setNav();
	setBreadcrumb();
	/*  now that the footer is static, and the right nav is sticky, if the left column is shorter than the page, the page will reset when the right nav becomes sticky (when you scroll down a bit)
	* 	get the clientHeight of the left column and if it turns out to be smaller than the distance to the footer, then make it larger
	*	ok?
	*/
	// store the original height of the right column in the sna.options array
	sna.setOptions("rightColumnHeight", sna.getById("rightcolumn").getClientHeight());
	fixPageHeight(); 
	addWindowEvent('resize', function() { fixPageHeight() });
	addWindowEvent('scroll', function() { fixPageHeight() });
	addWindowEvent('resize', checkResetFooter);
	if (navigator.userAgent.indexOf("Firefox") != -1) { // it is firefox
		document.getElementById("footer").style.marginLeft = "-395px";
		document.getElementById("footer").style.width = "790px";
	} else {
		document.getElementById("footer").style.width = window.innerWidth ? "789px" : "790px";
	}
	/* Done! */
}

function fixPageHeight() {
	
	/* this became an issue because it was never set so when the right hand column becomes sticky, it loses it's clientHeight 
	*	and sets the left column to height: 0px and then resets the page, un-sticking the right hand column and getting 
	*	back clientHeight and resetting the left column to the height of the right column
	*/
	if (sna.getById("rightcolumn").getClientHeight() == 0) {
		sna.getById("rightcolumn").setClientHeight(sna.getOptions("rightColumnHeight"));
	}
	
	
	
	wrapperHeight = sna.getById("wrapper").getClientHeight();
	
	leftHeight = sna.getById("leftcolumn").getClientHeight();
	rightHeight = sna.getById("rightcolumn").getClientHeight();
	navHeight = sna.getById("navigation").getClientHeight();
	headerHeight = sna.getById("header").getClientHeight();
	footerHeight = sna.getById("footer").getClientHeight();
	windowHeight = window.innerHeight;
	
	//alert("Right: " + sna.getById("rightcolumn").getClientHeight());
	
	stackHeight = rightHeight + navHeight + headerHeight; // total nav +  right column
	leftStackHeight = leftHeight + navHeight + headerHeight; // total nav + left column
	
	differenceHeight = windowHeight - leftStackHeight; // difference between the total page height and the window height
	// so the left column should be the difference between the windowHeight - (nav height + header height) - footerHeight
	/* figure out what the height of the left column shoud be by adding the leftHeight to the differenceHeight and subtracting the navHeight plus the headerHeight Plus the current leftHeight minus the footer (so it won't scroll if it doesn't have to) */
	if (differenceHeight > 0) { // the left column is too short
		//newLeftHeight = (((leftHeight + differenceHeight) - (navHeight + headerHeight)) + leftHeight) - footerHeight;
		newLeftHeight = windowHeight - (navHeight + headerHeight) - footerHeight;
		if (newLeftHeight < rightHeight) {
			newLeftHeight = rightHeight;
		}
		sna.getById("leftcolumn").setClientHeight(newLeftHeight);
	} else if (leftHeight < rightHeight && leftStackHeight < windowHeight) {
		sna.getById("leftcolumn").setClientHeight(rightHeight);
	} else {
		//sna.getById("leftcolumn").setClientHeight(leftHeight); // just so it is there - yeah, um, that really messed stuff up
	}
	
	
	
	
}
function setBreadcrumb() {
	// the page title comes in this format Academy of Special Needs Answers | [PAGE TITLE]
	// so grab the [PAGE TITLE] and put it in the breadcrumb
	if (document.getElementById("current_page")) {
		
		title = sna.getByTagname("title").elems[0][0].innerHTML
		title = title.substr((title.indexOf("| ") + 2));
		
		// clean it up a bit
		title = title.replace(/&(lt|gt);/g, function (strMatch, p1){ return (p1 == "lt")? "<" : ">"; });
		var titleText = title.replace(/<\/?[^>]+(>|$)/g, "");
		
		
		sna.getById("current_page").elems[0].innerHTML = "&nbsp; &raquo; &nbsp;" + titleText;
	} else {
		// don't worry about it
	}
}
function reset_search_text() {
	//alert("search function");
	sna.getById("searchBox").value = "Search our site";
}


function reset_search() {
	o = sna.getById("searchBox");
	if (o.getClassname() == "searchStyle") {
		o.setClassname("searchReset").setValue("");
	} else if (o.getClassname() == "searchReset" && o.getValue().length == 0) {
		o.setClassname("searchStyle").setValue("Search our site");
	} else {
	// leave it alone
	}
}


/* navigation things here */
function setNav() {
	/* this depends on navigation items that have child ul */
	sna.getElements("#navList > li");
	/* if (typeof window.NodeList == "function" ) {
		tmpArray = sna.elems[0].toArray(); // this does not work in IE
	} else {
		tmpArray = sna.elems; // this does
	} */
	tmpArray = NodeList.toArray(sna.elems[0]);
	if (tmpArray.length == 1) { // it's IE7 again
		tmpArray = NodeList.toArray(sna.elems);
	}
	for (i=0; i<tmpArray.length; i++) { 
		if (sna.getByNode(tmpArray[i]).elems[0].children[1]) { // if it has a ul as a child
			sna.setActiveNav(sna.getByNode(tmpArray[i]).elems[0]);
			sna.getByNode(sna.getByNode(tmpArray[i]).elems[0].children[0].children[0]).on('click', sethover);
			sna.getByNode(tmpArray[i]).on('mouseover', setMouseOverNav); // added the mouseover 
			/* set up key click listener here */
		} else {
			// set it to clear the reset if mouseover on other nav items
			sna.getByNode(tmpArray[i]).on('mouseover', setMouseOverNav);
		}
	}
}

function checkDismiss() {
	if (event.keyCode == 27) { // esc key
		setMouseOverNav();
	}
	event.returnValue = false;
}

function setMouseOverNav() {
	if (sna.activeNav && sna.activeSubnav) {
		sna.activeNav.className = "";
		sna.activeSubnav.style.visibility = '';
		
		sna.activeNav = false;
		sna.activeSubnav = false;
		document.body.onclick = null;
	}
}

function sethover() {
	event.srcElement.parentNode.parentNode.children[1].style.visibility = 'visible';
	event.srcElement.className = "hover-state";
	sna.setActiveNav(event.srcElement);
	
	document.body.onclick = resetnav;
	document.body.onkeyup = checkDismiss;
	
	event.returnValue = false;
}


function resetnav() {
	if (event) {
		if (sna.activeNav && sna.activeSubnav) {
			if (event.srcElement != sna.activeNav) {
				sna.activeNav.className = "";
				sna.activeSubnav.style.visibility = '';
				
				sna.activeNav = false;
				sna.activeSubnav = false;
				document.body.onclick = null;
				document.body.onkeyup = null;
			}
		}
	}
}

function checkResetFooter() {
	// firefox 5 on Mac os seems to need the margin-left to be -395 instead of -394
	// this checks the footer to see if it is going off the side of the page
	width = window.innerWidth ? window.innerWidth : document.getElementsByTagName("body")[0].clientWidth;
	left = window.innerWidth ? "12px" : "11px";
	marginLeft = window.innerWidth ? "-394px" : "-395px";
	
	
	if (navigator.userAgent.indexOf("Firefox") != -1) { // it is firefox
		marginLeft = "-395px";
	}
	
	footerClientWidth = window.innerWidth ? document.getElementById("footer").clientWidth + 40 : document.getElementById("footer").clientWidth + 24;
	
	if (width < footerClientWidth) {
		// reset the left and margin-left of the footer
		document.getElementById("footer").style.left = left;
		document.getElementById("footer").style.marginLeft = "0px";
	} else if (document.getElementById("footer").style.left == left && width > document.getElementById("footer").clientWidth) {
		
		document.getElementById("footer").style.left = "50%";
	//	if ((window.innerWidth / 2) != parseInt(window.innerWidth / 2)) {
			document.getElementById("footer").style.marginLeft = marginLeft;
	//	} else {
	//		document.getElementById("footer").style.marginLeft = "-395px";
	//	}
	}
	
	
}

