var Rules = {
  '#table-of-contents li a:click': function(element, event) {
		fixTOC(element.href, "table-of-contents");
		Event.stop(event);
	},
	'#table-of-contents:loaded': function(element) {
		fixTOC(window.location.href, "table-of-contents");
		// Keep from jumping to a stupid place on the page; 10msec is gonna be before the page is even done rendering...
		setTimeout("window.scroll(0, 0)", 10);
	},
	'.jump-to-top': function(element) {
		Element.hide(element);
	},
	'#home #main-banner': function(element) {
		randomize_image(element, '/images/home-banner-', 5, '.png');
	},
	'#local-nav ul a, #local-nav ul span': function(element) {
		// Remove the border from the first local nav element
		var item = element.parentNode;
		var sib = getPreviousSiblingElement(item);
		if (!sib) {
			element.style.border = "none";
		}
	},
	'a.popup-without-chrome:click': function(element, event) {
		window.open(element.href,'popup','resizable=yes,width=740,height=580');
		Event.stop(event);
	},
	'.initial-off, .toggled-off, #definitions dt, #definitions dd': function(element) {
		// addClass(element,"hidden");
		element.style.display = "none";
	},
	'.switch': function(element) {
		element.style.display = "inline";
	},
	'.switch:click': function(element, event) {
		var switchClasses = new Array();
		element.classNames().each(function(className) {
			if (className != 'switch') { switchClasses.push(className); }
		});
		var switchables = document.getElementsByClassName('switchable');
		switchClasses.each(function(c) {
			switchables.each(function(e) {
				if (e.hasClassName(c)) {
					// switch it on!
					e.style.display = "";
				}
			});
		});
		element.style.display = "none";
		Event.stop(event);
	},
	'.toggler:click': function(element, event) {
		toggleTarget(element);
		Event.stop(event);
	},	
	'#content-wrapper:loaded': function(element) {
		createCitations(element);
	},
	'.defined-term:click': function(element, event) {
		popupDefinition(element,event);
		Event.stop(event);
	}
}

function toggleTarget(element) {
	var elt = $(element);
	if (!elt.href) { return false; }
	var target = $(getTargetIdFromAddress(elt.href));
	if (!target) {return false;}
	if (target.hasClassName("toggled-off")) {
		target.removeClassName("toggled-off");
	}
	if (target.style.display == "none") {
		Effect.BlindDown(target, {duration: 0.3});
	}
	else {
		Effect.BlindUp(target, {duration: 0.3});
	}
}

function getTargetIdFromAddress(address) {
	// Given a string like "http://www.foo.com/bar/corge.html" reutrn "corge"
	
	var slashIndex = address.lastIndexOf('/');
	if (slashIndex == -1) { slashIndex = 0; }
	if (slashIndex != 0) { slashIndex += 1; }
	var dotIndex = address.lastIndexOf('.');
	if (dotIndex == -1) { dotIndex = address.length - 1; }
	return address.substring(slashIndex, dotIndex);
}

// TODO: Move this stuff out of this file

function randomize_image(element, prefix, limit, postfix) {
	num = Math.floor(Math.random()*limit + 1);
	if (element.src) {
		element.src = prefix+num+postfix;
	}
}

function showOnly(container, id) {
	container = $(container);
	var div_rule = "#"+container.id+" div";
	var div_list = $$(div_rule);
	div_list.each (function (elt) {
		if (elt.parentNode == container) {
			if (elt.id == id) {
				Element.removeClassName(elt, "hidden");
			}
			else {
				Element.addClassName(elt, "hidden");
			}
		}
	}); // End div_list.each
}

function setCurrent(tocElement, section) {
	tocElement = $(tocElement);
	var links = $$("#"+tocElement.id+" a");
	links.each( function(elt) {
		var regex = new RegExp("#"+section+"$");
		
		if (elt.href.search(regex) >= 0) {
			Element.addClassName(elt.parentNode, "current");
		}
		else {
			Element.removeClassName(elt.parentNode, "current");
		}
	});
}

function fixTOC(url, tocElement) {
	var section = getBestTOCSection(url, tocElement);
	showOnly("content", section);
	setCurrent("table-of-contents", section);
}

function getBestTOCSection(url, tocElement) {
	var id = getLocalAnchor(url);
	if (id) { return id; }
	var toc = $(tocElement);
	var items = toc.getElementsByTagName("a");
	id = getLocalAnchor(items[0].href);
	return id;
}

function getLocalAnchor(url) {
	var match = url.match(/#(.*)/);
	if (match && match.length > 1) {
		return match[1];
	}
	return null;
}

function getPreviousSiblingElement(element) {
	var node = element.previousSibling;
	while (node) {
		if (node.nodeType == 1) {
			return node;
		}
		node = node.previousSibling;
	}
	return null;
}

function createCitations(container) {

	if (container.className.match("print-url-citations")) {
			
		var links = container.getElementsByTagName("a");
		var citation_holder = document.createElement("ol");
		var reference = 0;
	
		for ( var i=0; i < links.length; i++ ) {
	
			if ( (checkIfAnchor(links[i]) == false) && (checkIfMailto(links[i]) == false) ) {
	
				reference++;
				var superscript_ref = document.createElement("sup");
				var sup_ref_text = document.createTextNode(reference);
				superscript_ref.appendChild(sup_ref_text);
				links[i].appendChild(superscript_ref);
				
				var list_item = document.createElement("li");
				var link_to = links[i].getAttribute("href");
				
				// Safari sometimes defaults to shrink a page to the width of a long
				// URL, so I am chopping off the end of long ones.
				if (link_to.length > 75) {
					link_to = link_to.substring(0,75) + "...";
				}
				
				// This is used to relative catch links back to our web site.
				if (link_to.match(/^\//)) {
					link_to = "http://www.library.wisc.edu" + link_to
				}
				
				var url = document.createTextNode(link_to);
				list_item.appendChild(url);
				citation_holder.appendChild(list_item);
			}	
		}	

		var citations = document.createElement("div");
		citations.setAttribute("id","citations");
		container.appendChild(citations);
		var heading = document.createElement("h3");
		var h_text = document.createTextNode("URL References");
		heading.appendChild(h_text);
		citations.appendChild(heading);
		citations.appendChild(citation_holder);
		addClass(citations,"hidden");
	} else {
		return false;
	}
}

function checkIfAnchor(link) {
	if (link.getAttribute("href").match(/^#/)) {
		return true;
	} else {
		return false;
	}
}

function checkIfMailto(link) {
	if (link.getAttribute("href").match(/^mailto/)) {
		return true;
	} else {
		return false;
	}
}

function addClass(element,value) {
  if (!element.className) {
    element.className = value;
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;
		element.className = newClassName;
  }
}

function popupDefinition(element,event) {

	// Hide any other open definitions to avoid clutter.
	var def_holder = document.getElementById("definitions");
	var all_defs = def_holder.getElementsByTagName("dd");
	for (i = 0; i < all_defs.length; i++) {
		all_defs[i].style.display = "none";
	}

	// Get the definition that is going to display
	var definition = document.getElementById(element.id + "-def");
	// Get the span inside the definition - this is used for keeping 
	// the formatting tight.
	var inner_span = definition.getElementsByTagName("span");
	
	// The user will need to close the popup definition, 
	// create a clickable 'X' to close the definition and append 
	// it to the definition.
	var close_link = document.createElement("a");
	var close_text = document.createTextNode("X");
	close_link.setAttribute("href","#");
	close_link.onclick = function() {
		closeDefinition(definition,close_link);
		return false;
	}
	close_link.appendChild(close_text);
	definition.appendChild(close_link);
	close_link.style.color = "#fff";
	close_link.style.textDecoration = "none";
	close_link.style.display = "block";
	close_link.style.fontSize = "11px";
	close_link.style.height = "10px";
	close_link.style.widht = "10px";
	close_link.style.position = "absolute";

	// Set the styles that are common to both kinds of popups, 
	// left- and right-anchored (see next section...)
	definition.style.position = "absolute"; 
	definition.style.marginTop = "-5em";
	definition.style.width = "200px"; 
	definition.style.backgroundRepeat = "no-repeat"; 
	definition.style.zIndex = "1000";	
	inner_span[0].style.display = "block";
	inner_span[0].style.border = "1px solid #999";
	inner_span[0].style.borderTop = "none";
	inner_span[0].style.padding = "5px";
	inner_span[0].style.background = "#fff";	
	definition.style.top = event.layerY ? event.layerY - 10 + "px" : event.offsetY - 10 + "px";
	close_link.style.top = "1px";
	
	// This section determines the width of the window.
	// If the mouse is clicked to the left of the window center, 
	// the definition pops up to the right, if click is to the 
	// right, the definition pops up to the left. This keeps 
	// the definition from popping up off screen. It sets the styles
	// unique to the popup positioning...
	var winwidth = document.width ? document.width : document.documentElement.offsetWidth - 25;
	if (event.clientX > (winwidth / 2)) {
		// Place the definition popup to the left of the word...
		definition.style.padding =  "25px 50px 0px 0px"; 
		definition.style.background = "url(/images/quick-definition-point-right.gif)"; 
				
		inner_span[0].style.marginRight = "1px";
		inner_span[0].style.borderRight = "none";

		definition.style.left = event.layerX ? event.layerX - 245 + "px" : event.offsetX - 245 + "px";
		
		close_link.style.right = "55px";
	} else {
		// Place the definition popup to the right of the word...
		definition.style.padding =  "25px 0px 0px 50px"; 
		definition.style.background = "url(/images/quick-definition.gif)"; 
				
		inner_span[0].style.marginLeft = "1px";
		inner_span[0].style.borderLeft = "none";
		
		definition.style.left = event.layerX ? event.layerX + 10 + "px" : event.offsetX + 10 + "px";
		close_link.style.right = "5px";
	}

	// Show the definition, but first append it to the "wrapper" div. The "content" 
	// div may be positioned relatively for toc and goodies-boxes pages. This will 
	// ensure that the definition is positioned relative to the mouse click and 
	// not relative to the "content" div.
	definition.style.display = "block";	
}

function closeDefinition(definition,close_link) {
	close_link.style.display = "none";
	definition.style.display = "none";
}
