//
// Javascript routines used in Dungeons & Dragons Review Guide.
//
// (c) 2003
//
// All material in this document is copyright Mark Bertenshaw.  None of this can be reproduced in any manner without the express permission of the author.
//
// Dependencies:	BrowserExtension.js, JavascriptCompat.js
//

var QS_SKIP = "?skip";

// First ensure that if this is being loaded for a search, then ignore virtually everything other than providing function stubs.
if (document.location.search == QS_SKIP) {
	createNavigationBar = function () {};
	addExpander = function () {};
	sendEmail = function () {};
	window.onload = function ()
	{
		window.opener.parseExternalWindow(document);
	}
} else {
	
	//
	// String constants.
	//
	var EXPAND_LIST = "(Expand List)";
	var COLLAPSE_LIST = "(Collapse List)";
	var NOT_COMPLETED = "Not Completed";
	
	var CLASS_UNFINISHED = "Unfinished";
	var CLASS_IN_PROGRESS = "InProgress";
	var CLASS_INDEX = "index";
	
	var PAGE_HOME = "dnd.html";
	var PAGE_REDIRECT = "redirect.html";
	var PAGE_RESULTS = "results.html";
	
	var TIMEOUT_COUNT = 20;
	var RETRY_INTERVAL = 500;
	var USE_TIMER = false;
	
	// This is used to store the timer ID between the window_onload event and the timer subsequently firing.
	var timerID;
	var anchorIndex;
	var timeOut = TIMEOUT_COUNT;
	
	// Used to create unique IDs.
	var scriptIdx = 0;
	
	//
	// List of pages with descriptions for use with navigation bar.
	//
	var nav = [
		["chainmail.html", "Chainmail"],
		["boxed.html","Boxed Rules Sets"],
		["rules.html","Rules"],
		["accessories.html","Accessories"],
		["basic.html","Basic Modules"],
		["expert.html","Expert Modules"],
		["companion.html","Companion Modules"],
		["master.html","Master Modules"],
		["immortals.html","Immortals Modules"],
		["InvisibleInk.html","Invisible Ink Modules"],
		["OneOnOne.html","One on One Modules"],
		["DA.html","Blackmoor Modules"],
		["DDA.html","Dungeons &amp; Dragons Adventure Modules"],
		["gazetteers.html","Gazetteers"],
		["KnownWorld.html","Known World"],
		["HollowWorld.html","Hollow World"],
		["CreatureCrucible.html","Creature Crucible"],
		["EntryLevel.html","Entry Level Modules"]
	];
	
	addEBayLinks = function ()
	{
		var divs = document.getElementsByTagName("DIV");
		for (var i=0; i<divs.length; i++) {
			if (divs[i].className == "summary") {
				var newButton = document.createElement("INPUT");
				newButton.type = "BUTTON";
				newButton.value = "Look on EBay";
				newButton.onclick = showEBayMatches;
				divs[i].appendChild(newButton);
			}
		}
	}
	
	// Adds some standard HTML which will be the placeholder hyperlink allowing us to subsequently expand and contract a list.
	addExpander = function ()
	{
		if (DOM1) {
			
			// Create an unique ID.
			var id = "I" + (++scriptIdx);
			
			// Send some HTML into the document HTML stream.		
			document.write("<A CLASS=\"Expander\" ID=\"" + id + "\" HREF=\"javascript:{}\" STYLE=\"block\">" + EXPAND_LIST + "</A>");
			
			// Trap the click event.
			addEventById(id, "click", expandList, false);
			
		}
	}
	
	// Creates a navigation bar in HTML at the current position.
	createNavigationBar = function ()
	{
		var html ="<DIV CLASS=\"Navigation\">";
		html += "<HR>";
		html += "<TABLE WIDTH=\"100%\"><TBODY><TR>";
		html += "<TD WIDTH=\"200\"><A HREF=\"" + PAGE_HOME + "\" CLASS=\"HideLink\">&#9674;</A> Return <A HREF=\"" + PAGE_HOME + "\">Home</A></TD><TD ALIGN=\"CENTER\"><TABLE><TBODY><TR>";
		var navLength = nav.length;
		for (var i = 0; i < navLength; i++) {
			if ( document.location.filename == nav[i][0] ) {
				var previousIdx = (navLength + i - 1) % navLength;
				var nextIdx = (navLength + i + 1) % navLength;
				html += "<TD ALIGN=\"CENTER\"><A HREF=\"" + nav[previousIdx][0] + "\" CLASS=\"HideLink\">&#9668;</A> Go to <A HREF=\"" + nav[previousIdx][0] + "\">" + nav[previousIdx][1] + "</A></TD>";
				html += "<TD ALIGN=\"CENTER\">Go to <A HREF=\"" + nav[nextIdx][0] + "\">" + nav[nextIdx][1] + "</A> <A HREF=\"" + nav[nextIdx][0] + "\" CLASS=\"HideLink\">&#9658;</A></TD>";
				html += "</TR></TBODY></TABLE></TD></TR></TBODY></TABLE>";
				html += "<HR>";
				html += "</DIV>";
				document.write(html);
				return;
			}
		}
	}
	
	// Called from the addExpander() hyperlink. Searches for the nearby list, and expands/contracts it, also toggling the hyperlink text.
	function expandList(e)
	{
		var link = getEventOrg(e)
		
		// Search upwards in the hierarchy from the triggering hyperlink, until a H4 or P tag is found.
		var hdr = link;
		do {
			var hdr = hdr.parentNode;
		} while (hdr.tagName != "H4" && hdr.tagName != "P");
		
		// Search forwards in the hierarchy from the H4 or P tag until the tag with the LongList class is found.
		var list = hdr;
		do {
			var list = list.nextSibling;
		} while (list.className != "LongList");
		
		// Toggle the style of the list between "none" and "block", and toggle the text of the triggering hyperlink.
		var style = list.style;
		if (style.display == "none" || style.display == "")
		{
			style.display = "block";
			link.innerHTML = COLLAPSE_LIST;
		}
		else
		{
			style.display = "none";
			link.innerHTML = EXPAND_LIST;
		}
	}

	// Go to product listed under ID.
	function findProduct(e)
	{
		var button = getEventOrg(e);
		var form = button.form;
		var productID = form.elements["ProductID"].value;
		window.location.href = ("redirect.html?" + productID);
	}
	
	// Retrieves a non escaped email address.
	function getEmailAddress(subject, body)
	{
		// Create the email address using "subject".
		var s = "mailto:mark.bertenshaw@virgin.net?subject=" + subject;
		
		// If there is a body, then add this in as well.
		if (body != undefined) {
			s += ("&body=" + body);
		}
		return s;
	}
	
	function getProductIdFromLink(a)
	{
		// Strip the product id from the HRef of the hyperlink from the summary (this is expanded by the browser into a standard URL).
		var anchorID = a.href;
		var hashPos = anchorID.indexOf("#");
		return anchorID.substr(hashPos + 1);	
	}
	
	function hideLongList(tagName)
	{
		var longLists = document.body.getElementsByTagName(tagName);
		for (var i = 0; i < longLists.length; i++) {
			var list = longLists[i];
			if (list.className == "LongList") {
				list.style.display = "none";
			}
		}
	}
	
	// Called when an "in progress" entry has been found by the window_onload event.
	function labelInProgress(a)
	{
		var productID = getProductIdFromLink(a)
		
		// Find the next anchor tag which has this product ID as a name.  The contents of this anchor tag contains the entire expanded entry.
		var target = document.getElementsByName(productID)[0];
		
		var divItem = target.parentNode;
		
		// The item name is found as text.
		var itemName = a.childNodes[0].nodeValue;
		
		var paraInProgress = document.createElement("P");
		var strongInProgress = document.createElement("STRONG");
		strongInProgress.appendChild(document.createTextNode("This review is in progress."));
		paraInProgress.appendChild(strongInProgress);
		
		divItem.insertBefore(paraInProgress,null);
	}
	
	// Called when an unfinished entry has been found by the window_onload event.
	function labelUnfinished(a)
	{
		
		var productID = getProductIdFromLink(a);
		
		// Find the next anchor tag which has this product ID as a name.  The contents of this anchor tag contains the entire expanded entry.
		var target = document.getElementsByName(productID)[0];
		
		var divItem = target.parentNode;
		
		// The item name is found as text.
		var itemName = a.childNodes[0].nodeValue;
		
		// Append a mail link to the end of the entry to get requests.
		var mailLink = document.createElement("A");
		mailLink.href = getEmailAddress(escape(itemName), "A vote for a " + itemName +" review!%0A%0A--%0A%0A");
		mailLink.appendChild(document.createTextNode("Vote for review of " + itemName));

		// Append a DIV for the mail link;
		var mailLinkDiv = document.createElement("DIV");
		mailLinkDiv.className = "MailLink";
		mailLinkDiv.appendChild(mailLink);
		
		// Delete the description.
		var divs = divItem.getElementsByTagName("DIV");		
		var divDescription = divs[1];
		var divHack = divs[2];
		divItem.removeChild(divDescription);
		var divNewDescription = document.createElement("DIV");
		divNewDescription.className = "description";
		divNewDescription.appendChild(document.createTextNode("To be done ... sometime."));
		divItem.insertBefore(divNewDescription, divHack);
		
		var paraEmailLink = document.createElement("P");
		paraEmailLink.className = "Navigation";
		paraEmailLink.appendChild(mailLinkDiv);
		var divSummary = divs[0];		
		divSummary.appendChild(paraEmailLink);
		
		// Append some text in the summary showing that this item is not completed. 
		a.appendChild(document.createTextNode(" "));
		var span = document.createElement("SPAN");
		span.className = "SmallFont";
		span.appendChild(document.createTextNode("(" + NOT_COMPLETED + ")"));
		a.appendChild(span);
		
		// Iterate through each row of the product summary, adding the text NOT_COMPLETED, if this is not the Stock Code.
		var table = divSummary.getElementsByTagName("TABLE")[0];
		var rows = table.rows;
		for (var i = 0; i < rows.length; i++) {
			var cells = rows[i].cells;
			if (cells.length > 1) {
				if (cells[0].innerHTML != "Stock Code") {
					cells[1].innerHTML = NOT_COMPLETED + ".";
				}
			}
		}
		
		// If the current URL has an anchor reference, then skip to it.
		if (document.location.hash == ("#" + productID)) {
			if (target.scrollIntoView) {
				target.scrollIntoView();
			}
		}

		return true;

	}
	
	function loadEBayHTML(url, handler)
	{
		var CACHE_START = "<!-- eBayCacheStart -" + "->";
		var CACHE_END = "<!-- eBayCacheEnd -" + "->";

		var xmlhttp;

		//try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		//} catch (e) {
		//	try {
		//		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		//	} catch (E) {
		//		try {
		//			xmlhttp = new XMLHttpRequest();
		//		} catch (NS_Error) {  //cannot load xmlhttp;
		//			xmlhttp = false;
		//			alert("cannot load xmlhttp!");
		//		}
		//	}
		//}
		
		if (xmlhttp) {} else {return};

		xmlhttp.onreadystatechange = function ()
		{
			if (xmlhttp.readyState == 4)
			{
				var html = xmlhttp.responseText;
				var startPos = html.indexOf(CACHE_START);
				var endPos = html.indexOf(CACHE_END, startPos);
				
				handler(html.slice(startPos + CACHE_START.length, endPos));
			};
		}

		xmlhttp.open("GET",url, true);
		xmlhttp.setRequestHeader("Content-Type", "text/html");
		xmlhttp.send();
	}
	
	// Resets the contents of all unfinished entries to show their state.
	function resetPage()
	{
		// Only do this for DOM1
		if (!DOM1) return;
		// Get the first DIV tag on the page.
		var div = document.getElementById("index");
		
		hideLongList("UL");
		hideLongList("TABLE");
		
		// Get all the hyperlinks in this DIV tag, then iterate through that collection looking for those with the class UNFINISHED, and calling
		// labelUnfinished() with those hyperlinks.
		var anchors = div.getElementsByTagName("A");
		for (var i = anchorIndex; i < anchors.length; i++) {
			var anchor = anchors[i];
			if (anchor.className == CLASS_UNFINISHED) {
				if (!labelUnfinished(anchor)) {
					if (i == anchorIndex) {
						timeOut--;
						if (timeOut == 0) {
							window.clearInterval(timerID);
							alert("Timeout");
							return;
						}
					} else {
						timeOut = TIMEOUT_COUNT;
						anchorIndex = i;
					}
					return;
				}
			}
			if (anchor.className == CLASS_IN_PROGRESS) {
				labelInProgress(anchor);
			}
		}
		
		addEBayLinks();
		
		if (timerID) {
			// Ensure that this isn't called again by clearing the timer.
			window.clearInterval(timerID);
		}
	}

	// Write the email address as a tag onto the current document.
	sendEmail = function (text, subject)
	{
		document.write(sendEmailHTML(text, subject));
	}

	// Construct HTML which will create a mailto: hyperlink.
	function sendEmailHTML(text, subject)
	{
		// Anti spammer protection.
		if (subject == undefined) {
			subject = "Dungeons and Dragons Reviews";
		}
		return "<A HREF=\"" + getEmailAddress(subject) + "\">" + text + "</A>";
	}
	
	function getSearchString(e)
	{
		// Find the title in the summary block in which the button was placed, and pull out all the SPAN tags.
		var elem = getEventOrg(e);
		var title = elem.parentNode.firstChild;
		while (title.nodeType != 1) {
			title = title.nextSibling;
		}
		
		var spans = title.getElementsByTagName("SPAN");
		
		// Use the SPAN tags which have the classes "Code" and "Title".  Use these to construct a search string.
		var queryString = "";
		for (var i=0; i<spans.length; i++) {
			switch (spans[i].className)
			{
				case "Code":
				{
					queryString += getInnerText(spans[i]) + "+";
					break;
				}
				case "Title":
				{
					titleName = getInnerText(spans[i]);
					queryString += titleName;
					break;
				}
			}
		}
		
		// If no string is forthcoming, then use whatever is currently in the summary title.
		if (queryString == "") {
			titleName = getInnerText(title);
			queryString = titleName;
		}
		
		// Ensure that any spaces are converted to plusses.
		queryString = queryString.replace(/\s/g, "+");
		
		// Create the search string.
        return "http://search-desc.ebay.co.uk/search/search.dll?" +
							"MfcISAPICommand=GetResult" +
							"&query=" + queryString +
							"&srchdesc=y" +
							"&ebaytag1=ebayctry" +
							"&ebaycurr=999" +
							"&ebaytag1code=0" +
							"&combine=y" +
							"&st=2" +
							"&SortProperty=MetaEndSort";
	}
	
	function showEBayMatches(e)
	{
		var searchString = getSearchString(e);
		window.open(searchString, "_new");
		
	}
	
	if (window.navigator.browserType == n.BT_INTERNET_EXPLORER) {
		processEBayMatches = function (e)
		{
			
			showEBayMatches(e);
			return;
			
			// SADLY THIS WON'T WORK
			
			// Create a small new window for the results.
			var newWin = window.open("about:blank", "_blank", "height=350,left=" + (window.screen.availWidth - 600) + ",width=600,top=0,scrollbars=yes");
			var newDoc = newWin.document;
			
			// Create a transitional message.
			newDoc.open();
			newDoc.write("<HTML><HEAD><TITLE>Downloading from EBay ... </TITLE><LINK REL=\"STYLESHEET\" HREF=\"dnd.css\" TYPE=\"text/css\" TITLE=\"Standard\"></HEAD><BODY><P>Downloading results for \"" + titleName + "\" from EBay.</P><P>Please Wait ...</P></BODY></HTML>");
			newDoc.close();
			
			loadEBayHTML(searchString, function(html)
			{
				if (!newWin.closed) {
					newDoc.open();
					newDoc.write("<HTML><HEAD><TITLE>EBay matches for " + titleName + "</TITLE><LINK REL=\"STYLESHEET\" HREF=\"dnd.css\" TYPE=\"text/css\" TITLE=\"Standard\"></HEAD><BODY>" +  html + "</BODY></HTML>");
					newDoc.close();
				}
			}
			);
		}
	} else {
		processEBayMatches = function (e)
		{
			showEBayMatches(e);
		}
	}
	
	
	/*
		BEGIN Not Generic Code
	*/

	//
	// In Internet Explorer 4+, expand all the lists just for the purposes of printing, then collapse them again.
	//
	if (navigator.browserType == navigator.BT_INTERNET_EXPLORER && navigator.browserVersion >= 4 ) {
		window.onbeforeprint = function ()
		{
			var elems = document.getElementsByTagName("A");
			for (var i = 0; i < elems.length; i++) {
				var elem = elems[i];
				if (elem.className == "Expander") {
					if (elem.innerHTML == EXPAND_LIST) {
						elem.collapseNext = true;
						elem.click();
					}
				}
			}
		}
		window.onafterprint = function ()
		{
			var elems = document.getElementsByTagName("A");
			for (var i = 0; i < elems.length; i++) {
				var elem = elems[i];
				if (elem.collapseNext) {
					elem.collapseNext = false;
					elem.click();
				}
			}
		}
	}
	
	var pn = window.location.pathname;
	// Sets up the window_onload event for non-home pages. Starts a timer to call resetPage ... soon.
	if ( pn.indexOf(PAGE_HOME) < 0 && pn.indexOf(PAGE_REDIRECT) < 0 && pn.indexOf(PAGE_RESULTS) < 0) {
		addEventByElem(window, "load", function () 
		{
			anchorIndex = 0;
			if (USE_TIMER) {
				timerID = window.setInterval(resetPage, RETRY_INTERVAL, "Javascript");
			} else {
				resetPage();
			}
		}
		, false);
	}


	/*
		END Not Generic Code
	*/

}