var currentlyDisplaying = 3;	// The right hand page in the spread that's currently showing up.
var instructionsDisplayed = true;

function hideCurrent() { 						// hide currently viewed pages
	var elem = document.getElementById('A'+(currentlyDisplaying-1));
	elem.className = 'hide';
	currentlyDisplaying++;
	elem = document.getElementById('A'+(currentlyDisplaying-1));
	elem.className = 'hide';
	currentlyDisplaying++;
}
function revealCurrent() {
	var elem = document.getElementById('A'+(currentlyDisplaying-1));
	elem.className = 'page left';
	elem = document.getElementById('A'+(currentlyDisplaying));
	elem.className = 'page right';
}
function prevPage() {
	if(document.getElementById('A'+(currentlyDisplaying-3)) != null){
		hideCurrent();
		currentlyDisplaying -= 4;
		revealCurrent();
	}
 	document.getElementById('pageNumber').childNodes[0].nodeValue = currentlyDisplaying;	// Update page number
}
function nextPage() {
// 	if(instructionsDisplayed){
// 		document.getElementById('instructions').className = 'hide';
// 		instructionsDisplayed = false;
// 		return;
// 	}

	if(!document.getElementById("A"+(currentlyDisplaying+1)).hasChildNodes()){return;} // Don't start if there's no need to start.
		hideCurrent();					// Hide the pages that are presently displayed
										// If the pages don't already exist, create two new pages, one "page right" and one "page left hide"; Unhide the left hand page that will presently be displayed, 'L', and pass from it to 'R', and from 'R' to the next.
	if(!document.getElementById("A"+currentlyDisplaying)){
		var sp = document.getElementById('spread');			// Make two new pages
		var newElem = document.createElement("DIV");		// one,
		newElem.id = 'A' + currentlyDisplaying;
		newElem.className = 'page right';
		sp.appendChild(newElem);
		newElem = document.createElement("DIV");			// two.
		newElem.id = 'A' + (currentlyDisplaying+1);
		newElem.className = 'page left hide';
		sp.appendChild(newElem);
		document.getElementById('A' + (currentlyDisplaying-1)).className = 'page left';
		populateSpread();
	}
	else {								// If they do already exist, just show them.
		document.getElementById('A' + currentlyDisplaying).className = 'page right';
		document.getElementById('A' + (currentlyDisplaying-1)).className = 'page left';
		document.getElementById('pageNumber').childNodes[0].nodeValue = currentlyDisplaying;	// Update page number
	}
}
function hover(elem, yes){
	if(yes)	elem.className = 'hover';		// COME BACK AND FIX - eventually this function should keep the existing class intact.
	else elem.className = '';
}
document.onkeydown = checkKeycode; // Thanks Ryan Cooper for this simple and very easy to understand example of how to use the keyboard as part of the UI. http://www.ryancooper.com/resources/keycode.asp
function checkKeycode(e) {
var keycode;
if (window.event) keycode = window.event.keyCode;
else if (e) keycode = e.which;

if(keycode == 37) prevPage();
else if(keycode == 39) nextPage();
//alert("keycode: " + keycode);
}

function cleanWhitespace(node) { // Thanks Alex Vincent
  for (var i=0; i<node.childNodes.length; i++) {
	var child = node.childNodes[i];
	if(child.nodeType == 3 && !/\S/.test(child.nodeValue)) {
	  node.removeChild(child);
	  i--;
	}
	if(child.nodeType == 1)	{
	  cleanWhitespace(child);
	}
  }
  return node;
}
function preprocess() { //This function puts a fits all OL LI content into a SPAN so that it looks right when it's processed. 
	var ol = document.getElementsByTagName("ol");
	if(ol[0] != null) {												// If there are OLs
		for(i=0; i<ol.length; i++) {
			if(ol[i].childNodes[0] != null) {						// And if this OL has LIs
				for(j=0; j<ol[i].childNodes.length; j++) {
					var span = document.createElement('span');		// make a new span, put everything from the LI into it, and append the span as the LI's child node.
					
					if(typeof draw != 'function') { // IE-specific block: IE's ol li number labels must be special ordered, since IE doesn't comprehend ol.style.counterReset.
						var label = document.createElement("span");
						label.appendChild(document.createTextNode((j+1)+". "));
						label.className = "label";
						ol[i].childNodes[j].appendChild(label);
					}
					
					if(ol[i].childNodes[j].childNodes[0] != null){
						for(k=0; k<ol[i].childNodes[j].childNodes.length; k++){
							span.appendChild(ol[i].childNodes[j].childNodes[k]);
						}
					}
					ol[i].childNodes[j].appendChild(span);
				}
			}
		}
	}
}
// Below this line is the code for paginating the book.

var idealBlockHeight = 610;
var block;
var blockSet = false;

function pass(L,R) {									// The pass function removes the overflow content from L, the left page, and passes it to R, the right page.
	if(!blockSet && L.offsetHeight < idealBlockHeight) {// Since this function is called recursively, this first IF is set up to make sure it doesn't attempt to fix what ain't broke. (First time in and nothing to pass right; then return.)
		return;
	}
	if(!blockSet){										// The block is set once per external call of the pass function.
		block = L;
		blockSet = true;
	}
	if(R.nodeType != 3 && block.offsetHeight > idealBlockHeight) {
		R.appendChild(L.lastChild);						// Move something over into the empty R element. (We assume it's empty.)
	}
	while(block.offsetHeight > idealBlockHeight) {
		if(R.nodeType == 3){
			var feed = L.nodeValue.split(' ');
			while (block.offsetHeight > idealBlockHeight) {
				R.nodeValue = feed.pop() + ' ' + R.nodeValue;
				L.nodeValue = feed.join(' ');
			}
			blockSet = false;
			return;										// This is where the pass function, after being internally called several times, ultimately finishes its job. 
		}
		if(L.lastChild == null){ // Occasionally this happens: Remove everything from a node and it still takes up space. In this case, the node itself needs removing.
			L.parentNode.removeChild(L);
			blockSet = false;
			return;
		}
		R.insertBefore(L.lastChild,R.childNodes[0]);
	}
	if(typeof draw == 'function') { // Keeps IE out, which wonders "What's style.counterReset?"
		if(L.nodeName == 'OL') {
			var newCounter = 0;
			if(L.style.counterReset.charAt(0) == 's') {
				var newCounter = parseInt(L.style.counterReset.substr(5));
			}
			R.style.counterReset = "start "+(newCounter + L.childNodes.length);
		}
	}
	if(L.nodeName == 'LI') { // This check makes sure that LIs that get split are not numbered or bulleted twice.
		R.className = 'unlabeled';
	}
	if(block.offsetHeight <= idealBlockHeight) {		// If you passed one too many elements to the right
			L.appendChild(elem = R.firstChild);			// Put the last one back
		if(elem.nodeName == '#text'){					// If the thing that needs splitting in two is a text element, this is a special case that gets handled differently than the bottom most frequent case.
			if(R.childNodes[0] == null){ R.appendChild(document.createTextNode("")); }
			else { R.insertBefore(document.createTextNode(""), R.childNodes[0]); }
			pass(L.lastChild,R.firstChild);
		}
		else {
			var rElem = document.createElement(elem.nodeName);	// Most frequent case: Split L's last element in two by creating a copy of it
			var lElem = elem;											// For some reason, passing lElem into the hover function below instead of elem does not trigger IE's blow-up sensitivities (elem apparently goes to null when passed in as a parameter to the hover function).
			if(R.childNodes[0] == null){								// Sometimes R doesn't have child nodes, 
				R.appendChild(rElem);
			}
			else R.insertBefore(rElem, R.childNodes[0]);		// and inserting it at the beginning of R.
			if(elem.nodeName == 'A'){							// If the element getting split is an anchor
				if(elem.href != undefined){rElem.href = elem.href;}
				if(elem.title != undefined){rElem.title = elem.title;}
				elem.onmouseover = function() {hover(rElem, true);} // when visitor hovers over a link on the left side, it hovers on the right side as well, and vice versa. // Unique IDs set for the split link's two sides; 
				elem.onmouseout = function() {hover(rElem, false);}
				rElem.onmouseover = function() {hover(lElem, true);} // Two attributes get set for each segment of the link, onMouseOver and onMouseOut.
				rElem.onmouseout = function() {hover(lElem, false);}	
			}
			if(elem.nodeName == 'OL' || elem.nodeName == 'UL'){							// If the element getting split is an ordered list or unordered list
				rElem.className = 'lastSection';				// this puts the margin on li:last-child at the end of the list.
				elem.className = "";
// 									if(typeof draw != 'function') { // IE-specific block: IE's ol li number labels must be special ordered, since IE doesn't comprehend ol.style.counterReset.
// 										if(elem.nodeName == 'OL') {
// 											if(elem.childNodes[elem.childNodes.length-1].childNodes[0].className != 'label'){
// 												if(elem.childNodes[0] != null){
// 													for(i=0; i<elem.childNodes.length; i++){
// 														var label = document.createElement("span");
// 														label.appendChild(document.createTextNode((i+1)+". "));
// 														label.className = "label";
// 														elem.childNodes[i].insertBefore(label, elem.childNodes[i].childNodes[0]);
// 													}
// 												}
// 											}
// 										}
// 									}
			}
			pass(L.lastChild,R.firstChild);
		}
		return;
	}
}

function populateSpread(){
	pass(document.getElementById('A'+(currentlyDisplaying-1)), document.getElementById('A'+currentlyDisplaying));
 	pass(document.getElementById('A'+currentlyDisplaying), document.getElementById('A'+(currentlyDisplaying+1)));
 	document.getElementById('pageNumber').childNodes[0].nodeValue = currentlyDisplaying;	// Update page number
}
function initialize(){
	cleanWhitespace(document.getElementById('spread'));	// 	
	preprocess();										// preprocess handles putting spans into OL LIs, (for IE: numbers the LIs).
	if(typeof draw == 'function') {draw();}				// This keeps IE from calling the draw function, which it has not loaded.
	populateSpread();
}

window.onload = initialize;
