// Global Vars
var g_dataFrame;
var g_pageFrame;
var g_contentFrame;
var g_waibFrame;
var g_commFrame;
var g_upperNavFrame;

var g_dropdownFrame;	// frame where the dropdown listboxes are

var g_listbox1Elem;
var g_listbox2Elem;
var g_pageTextboxElem;

var g_currPageID = "";
var g_currTabID = null;

var g_originalTocID = null;
var g_requestTocID = null;

var g_initPageNum = null;      // the number of an initial page to display

// Indicates if the TabNav initial load has completed.
var g_tabnavLoaded = false;

// Indicates if the SpyVue initial load has completed.
var g_SpyVueLoaded = false;

var g_isbn;

// The student page window and variables
var g_studentPageWnd = null;
var g_studentPageURL = null;
var g_studentPageID = null;
var g_studentWndFocus = false;

// name of the glossary jsp w/o the .jsp extention
var g_glossaryJsp = "glossary";

//*************************************************************************************************
//
//	The following functions are general functions that update the display and/or get information
//	about the current state of the Tabnav.
//
//*************************************************************************************************


// This function parses the query string of the top frame.
function getTopFrameArgs()
{
	var args = new Object();
	var query = top.location.search.substring(1);
	var pairs = query.split("&");
	for (var i = 0; i < pairs.length; i++)
	{
		var pos = pairs[i].indexOf('=');
		if (pos == -1)
			continue;
		var argname = pairs[i].substring(0, pos);
		var value = pairs[i].substring(pos + 1);
		args[argname] = unescape(value);
	}
	return args;
}


// sets global vars that address different tabnav frames
function getFrames()
{
	g_dataFrame = window.content.data;
	g_pageFrame = window.content.page;
	g_contentFrame = window.content;
	g_waibFrame = window.waib;
	g_commFrame = window.comm;
	g_upperNavFrame = window.uppernav;

	if (g_variation == "SCIENCE" || g_variation == "HARCOURT_UCL" || g_variation == "HARCOURT_SP" || g_variation == "EOLIT" || g_variation == "MATH" || g_variation == "MATH07")
	{
		g_dropdownFrame = g_upperNavFrame;
	}
	else
	{
		g_dropdownFrame = g_waibFrame;
	}
}


// finds the tree node with the specified ID
function findNode(nodeArray, nodeID)
{
	return g_dataFrame.g_nodeMap[nodeID];
}


// Fills a listbox with the shortLabel of nodes from nodeArray of type nodeType.
// The depth of child nodes levels processed from nodeArray is specified by totalLevels.
var g_nextOptionNum = 0;
function fillListbox(listboxElem, nodeArray, nodeType, currLevel, totalLevels)
{
	// currLevel is 1 in the initial call - recursive calls increment currLevel so it's always greater than 1 in those cases
	if (currLevel == 1)
	{
		// clear out any existing entries in the listbox
		listboxElem.length = 0;
		// init the options array index
		g_nextOptionNum = 0;
	}

	// for non-default variations of the tabnav, the 1st option of the 1st listbox is set to one of these dummy entries
	if (g_variation != "DEFAULT" && listboxElem == g_listbox1Elem && g_nextOptionNum == 0)
	{
		if (g_variation == "SCIENCE" || g_variation == "HARCOURT_UCL" || g_variation == "HARCOURT_SP")
		{
			listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Select a unit or chapter", "0");
		}
		else if (g_variation == "EOLIT")
		{
			listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Choose a Collection", "0");
		}
		else if (g_variation == "HANDBOOK" || g_variation == "MATH" || g_variation == "EOL05" || g_variation == "MATH07")
		{
			listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Select a chapter", "0");
		}
	}

	// for the EOLIT variation of the tabnav, the 1st option of the 2nd listbox is set to a dummy entry
	if (g_variation == "EOLIT" && listboxElem == g_listbox2Elem && g_nextOptionNum == 0)
	{
		listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Collection Menu", "0");
	}
	else if (g_variation == "MATH" && listboxElem == g_listbox2Elem && g_nextOptionNum == 0)
	{
		listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Lesson Menu", "0");
	}
	else if (g_variation == "HARCOURT_UCL" || g_variation == "HARCOURT_SP" && listboxElem == g_listbox2Elem && g_nextOptionNum == 0)
	{
		listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option("Select a lesson", "0");
	}

	// loop through all the nodes in nodeArray and recursively call this function for their child node arrays
	for (var i = 0; i < nodeArray.length; i++)
	{
		var node = nodeArray[i];
		// if the current node is not the right nodeType, skip it
		if (node.node_type != nodeType)
			continue;

		// get the data for the option element
		var lbValue = node.id;
		var lbText = g_dataFrame.getNodeProp(node, "shortLabel");

		// add a new option element to the listboxes options array (i.e., add the listbox item)
		listboxElem.options[g_nextOptionNum++] = new g_dropdownFrame.Option(lbText, lbValue);

		// check if we need to process the children at the next tree level depth
		if (currLevel < totalLevels)
		{
			// recursively call this function for the current node's child node array
			var childNodeArray = node.children;
			fillListbox(listboxElem, childNodeArray, nodeType, currLevel + 1, totalLevels);
		}
	}
}


// called when the frameset has finished loading (i.e., all child frames have completely finished loading)
function onFramesetLoad()
{
	var args = getTopFrameArgs();
	g_isbn = args["isbn"];
	g_initPageNum = (args["pagenum"] != null && args["pagenum"].length !=0) ? args["pagenum"] : null;

	// Determine browser and os for glossary.
	// If IE and Windows, use the glossary with no frames for 508 compliance.
	if (navigator.appName.indexOf("Microsoft") != -1 && navigator.appVersion.indexOf("Windows") != -1)
	{
		g_glossaryJsp = "glossary_no_frames";
	}

	// set global vars of frames
	getFrames();

	var waibForm = g_waibFrame.document.forms[0];
	var dropdownForm = g_dropdownFrame.document.forms[0];

	g_listbox1Elem = dropdownForm.elements["listbox1"];
	g_listbox2Elem = dropdownForm.elements["listbox2"];
	g_pageTextboxElem = waibForm.elements["pageTextbox"];

	// fill the waib's 1st listbox from the 1st 2 levels of the TOC
	fillListbox(g_listbox1Elem, g_dataFrame.Tree, 0, 1, 3);

	if (g_variation != "DEFAULT")
	{
		updateWaib("0");
		setTocSelNoDisp("0");
	}
	else
	{
		updateWaib(g_initialTocItemID);
		setTocSelNoDisp(g_initialTocItemID);
	}

	initTabMap();

	g_tabnavLoaded = true;

	// Load any initial page passed in the request.
	if (g_initPageNum != null)
	{
		getPage(g_initPageNum);
	}
	else
	{
		// Display the content associated with the initial tab.
		if (!g_initialTabID || g_initialTabID.length <= 0 || g_initialTabID == g_tocTabID)
		{
			if ((!g_initialTabID || g_initialTabID.length <= 0) && g_initialPageUrl.length > 0)
			{
				g_pageFrame.location = g_initialPageUrl;
				write508SkipNavLink(g_initialPageUrl);
			}
			else
			{
				// Show the TOC if no initial tab or page is specified as well as if it is set to the TOC tab.
				onClickTocTab();
			}
		}
		else if (g_initialTabID == g_pageTabID)
		{
			onClickPageTab();
		}
		else
		{
			onClickTab(g_initialTabID);
		}
	}

	// write the 508 toggle button to the page if it should be available to the user
	if (g_show508Toggle)
	{
		var spanElem = g_upperNavFrame.document.getElementById("toggle508Span");
		if (spanElem)
		{
			spanElem.innerHTML = '<a href="javascript:top.toggle508Mode()">' + g_toggle508Ctrl + '</a>';
		}
	}
}


// called when the waib is re-loaded to populate the drop downs
function onWaibLoad(loadedWaib)
{
	// set global vars of frames
	getFrames();

	var waibForm = g_waibFrame.document.forms[0];
	var dropdownForm = g_dropdownFrame.document.forms[0];

	g_listbox1Elem = dropdownForm.elements["listbox1"];
	g_listbox2Elem = dropdownForm.elements["listbox2"];
	g_pageTextboxElem = waibForm.elements["pageTextbox"];

	// fill the waib's 1st listbox from the 1st 3 levels of the TOC
	fillListbox(g_listbox1Elem, g_dataFrame.Tree, 0, 1, 3);

	g_currLoadedWaib = loadedWaib;
	if (g_currLoadedWaib == PAGE_WAIB)
	{
		// if 508 mode is on, add param to URL for alchemy pages
		adjustAlcURLFor508();

		g_currPageID = g_commFrame.pageID;
		g_pageTextboxElem.value = g_commFrame.pageNum;
		g_pageFrame.location = g_commFrame.pageURL;
		write508SkipNavLink(g_commFrame.pageURL);
		updateWaib(g_commFrame.tocID);
	}
	else
	{
		updateWaib(g_commFrame.tocID);
	}
}


// Updates the waib's 2nd listbox with the children of the selected item in the 1st listbox.
function updateListbox2()
{
	// get the selected item in the 1st listbox
	var nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	// for the non-default variations of the tabnav, the only option of the 2nd listbox is set to a dummy entry
	// when the 1st listbox is set to its 1st option which is also a dummy entry
	if (g_variation != "DEFAULT" && nodeID == "0")
	{
		// clear out any existing entries in the listbox
		g_listbox2Elem.length = 0;
		// fill the listbox with one of these dummy entries
		if (g_variation == "SCIENCE" || g_variation == "HANDBOOK" || g_variation == "EOL05")
		{
			g_listbox2Elem.options[0] = new g_dropdownFrame.Option("Select a section", "0");
		}
		else if (g_variation == "EOLIT")
		{
			g_listbox2Elem.options[0] = new g_dropdownFrame.Option("Collection Menu", "0");
		}
		else if (g_variation == "MATH")
		{
			g_listbox2Elem.options[0] = new g_dropdownFrame.Option("Lesson Menu", "0");
		}
		else if (g_variation == "MATH07")
		{
			g_listbox2Elem.options[0] = new g_dropdownFrame.Option("Select a lesson or feature", "0");
		}
		else if (g_variation == "HARCOURT_UCL" || g_variation == "HARCOURT_SP")
		{
			g_listbox2Elem.options[0] = new g_dropdownFrame.Option("Select a lesson", "0");
		}	
		return;
	}

	// find the node object in the TOC tree array
	var node = findNode(g_dataFrame.Tree, nodeID);
	if (node == null)
		alert("Couldn't find node with ID = " + nodeID);

	// fill the 2nd listbox with with the child nodes of the node selected in the 1st listbox.
	fillListbox(g_listbox2Elem, node.children, 1, 1, 1);

	return;
}


// Returns the listbox index of the item with the specified ID.
function getListboxIndex(listbox, id)
{
	for (var i = 0; i < listbox.options.length; i++)
	{
		if (listbox.options[i].value == id)
			return i;
	}
	return -1;
}


// Returns the ID of the current selection in the specified WAIB listbox.
function getCurrListboxSelection(listboxNum)
{
	var listbox = g_listbox1Elem;

	if (listboxNum == 1)
	{
		listbox = g_listbox1Elem;
	}
	else if (listboxNum == 2)
	{
		listbox = g_listbox2Elem;
	}
}


// Updates the listboxes in the waib so that the tree node with the specified ID is set as the current node.
function updateWaib(id)
{
	if (!id)
		id = g_dataFrame.getCurNodeID();

	var node = findNode(g_dataFrame.Tree, id);
	if (node)
	{
		if (node.node_type == 0)
		{
			var index = getListboxIndex(g_listbox1Elem, id);
			g_listbox1Elem.selectedIndex = index;

			updateListbox2();
			g_listbox2Elem.selectedIndex = 0;
		}
		else if (node.node_type == 1)
		{
			var index = getListboxIndex(g_listbox1Elem, node.parent_id);
			g_listbox1Elem.selectedIndex = index;

			updateListbox2();
			index = getListboxIndex(g_listbox2Elem, id);
			g_listbox2Elem.selectedIndex = index;
		}
	}
	else
	{
		if (g_variation != "DEFAULT")
		{
			g_listbox1Elem.selectedIndex = 0;
			updateListbox2();
			g_listbox2Elem.selectedIndex = 0;
		}
	}
}

// Updates the current page displayed in the student page popup.
function updateStudentPageWnd(wndURL)
{
	g_studentPageURL = wndURL;
	
	if (g_studentPageURL != "" && (g_studentPageWnd != null && !g_studentPageWnd.closed))
	{
		// Set the current state of whether answers should be displayed or not.
	    if (g_studentPageWnd.showAnswers)
	    	g_studentPageURL = g_studentPageURL + ((g_studentPageURL.indexOf('?') != -1) ? '&' : '?') + 'user=userType:teacher';
	    else
	    	g_studentPageURL = g_studentPageURL + ((g_studentPageURL.indexOf('?') != -1) ? '&' : '?') + 'user=userType:student';
	    
		// if the student page window is open, then update it.
		g_studentPageWnd.content.location = g_studentPageURL;
		
		// Give student popup page focus if it initiated the page change.
		if (g_studentWndFocus)
		{
			g_studentPageWnd.focus();
			g_studentWndFocus = false;
		}
	}
	else if (g_studentPageURL != "" && g_studentWndFocus && (g_studentPageWnd == null || g_studentPageWnd.closed))
	{
		// if the student page window should be opened, do so.
		getStudentPage();	
	}
	else if (g_studentPageURL == "" && (g_studentPageWnd != null && !g_studentPageWnd.closed))
	{
		g_studentPageWnd.close();
	}
}

function setTocSelection(id)
{
	g_contentFrame.tSel(id);
}


function setTocSelNoDisp(id)
{
	g_contentFrame.tSelNoDisp(id);
}


// Loads a page in tabnav's domain that triggers the re-display of the TOC.
// This is done because if the page that's already in that frame is in a different domain and
// an attempt is made to write to that frame, the javascript will generate errors due to browser
// frame security issues.
function showToc()
{
	if (g_currLoadedWaib != NO_PAGE_WAIB)
	{
		g_waibFrame.location = g_waibNoPageUrl;
	}
	g_pageFrame.location = "/tabnav/render_toc.html";
	write508SkipNavLink("/tabnav/render_toc.html");

	// swap the tab image to show it as selected
	setCurrTab(g_tocTabID);
}


//*************************************************************************************************
//
//	The following functions are called when users click controls in the Tabnav.
//
//*************************************************************************************************


// Call triggered by event of user changing waib's 1st listbox selection.
function onChangeListbox1()
{
	updateListbox2();
	g_listbox2Elem.selectedIndex = 0;

	var nodeID = null;
	if (g_listbox2Elem.length > 0)
		nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	else if (g_listbox1Elem.selectedIndex > -1)
		nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	if (nodeID)
	{
		setTocSelNoDisp(nodeID);
		getFirstPage(nodeID);
	}
}


// Call triggered by event of user changing waib's 1st listbox selection.
function onChangeListbox1Sci()
{
	updateListbox2();
	g_listbox2Elem.selectedIndex = 0;

	var nodeID = null;
	if (g_listbox2Elem.length > 0) { 
		nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	} else if (g_listbox1Elem.selectedIndex > -1) { 
		nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;
	}   // if 


	if (nodeID)
	{
		setTocSelNoDisp(nodeID);
//		getFirstPage(nodeID);
	}
}


// Call triggered by event of user changing waib's 2nd listbox selection.
function onChangeListbox2()
{
	var nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	setTocSelNoDisp(nodeID);
	getFirstPage(nodeID);
}


// Call triggered by event of user changing waib's 2nd listbox selection.
function onChangeListbox2Sci()
{
	var nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	setTocSelNoDisp(nodeID);
//	getFirstPage(nodeID);
}


// Call triggered by event of user clicking 'Go!' button in the uppernav.
function onClickGoNavSci()
{
	// if the TabNav is not finished loading, don't process button click
	if (!g_tabnavLoaded)
		return;

	var nodeID = null;
	if (g_listbox2Elem.length > 0)
		nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	else if (g_listbox1Elem.selectedIndex > -1)
		nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	if (nodeID)
	{
		if (nodeID == "0")
		{
			if (g_variation == "DEFAULT" || g_variation == "EOLIT")
			{
				showErrMsg("ERR_NO_TOC_ITEM_SELECTED");
				return;
			}
			else
			{
				updateWaib(g_initialTocItemID);
				setTocSelNoDisp(g_initialTocItemID);

				if (g_listbox2Elem.length > 0)
					nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
				else if (g_listbox1Elem.selectedIndex > -1)
					nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;
			}
		}

		if (!g_currTabID || g_currTabID == g_tocTabID)
		{
			g_currTabID = g_pageTabID;
			getFirstPage(nodeID);
		}
		else if (g_currTabID == g_pageTabID)
		{
			getFirstPage(nodeID);
		}
		else
		{
			g_requestTocID = nodeID;
			getTabContent(g_currTabID, nodeID);
		}
	}
	else
	{
		if (g_currTabID == g_pageTabID)
			showErrMsg("ERR_NO_OPENING_PAGE");
		else
			showErrMsg("ERR_NO_TAB_CONTENT");
	}
}


// Call triggered by event of user clicking the page tab in the upper nav frame.
function onClickPageTab()
{
	// if the TabNav is not finished loading, don't process any tab clicks
	if (!g_tabnavLoaded)
		return;

	var nodeID = null;
	if (g_listbox2Elem.selectedIndex > -1)
		nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	else if (g_listbox1Elem.selectedIndex > -1)
		nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	if (nodeID)
	{
		if (nodeID == "0")
		{
			if (g_variation != "DEFAULT")
			{
				updateWaib(g_initialTocItemID);
				setTocSelNoDisp(g_initialTocItemID);

				if (g_listbox2Elem.length > 0)
					nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
				else if (g_listbox1Elem.selectedIndex > -1)
					nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;
			}
			else
			{
				showErrMsg("ERR_NO_TOC_ITEM_SELECTED");
				return;
			}
		}
		setTocSelNoDisp(nodeID);
		getFirstPage(nodeID);
	}
}


// Call triggered by event of user clicking 'Go!' button in the waib.
function onClickGo()
{
	// if the TabNav is not finished loading, don't process button click
	if (!g_tabnavLoaded)
		return;

	var pageNum = g_pageTextboxElem.value;
	if (pageNum == "")
	{
		alert("Please enter a Chapter or Page Number.");
		//showErrMsg("ERR_NO_PAGE_NUM_ENTERED");
		return;
	}

	getPage(pageNum);
}


// Call triggered by event of user clicking the page navigation links in the waib.
function onClickIncPage(inc, showStudentWnd)
{
	// if the TabNav is not finished loading, don't process click
	if (!g_tabnavLoaded)
		return;
		
	// if showStudentWnd is true, student popup should be given focus after page change.  But validate the value
	// as that parameter may not always be passed in.
	g_studentWndFocus = (showStudentWnd == null || showStudentWnd == "undefined") ? false : showStudentWnd;

	if (!g_currPageID || g_currPageID.length <= 0)
	{
		if (inc == '1')
			alert("You must load a page before navigating to the next page.");
		else if (inc == '-1')
			alert("You must load a page before navigating to the previous page.");
		else
			alert("You must load a page before navigating to the next or previous page.");
		return;
	}

	incPage(g_currPageID, inc);
	
}


// Call triggered by event of user clicking the TOC tab in the upper nav frame.
function onClickTocTab()
{
	// if the TabNav is not finished loading, don't process any tab clicks
	if (!g_tabnavLoaded)
		return;

	showToc();
}


// Call triggered by event of user clicking a tab in the upper nav frame.
function onClickTab(tabID)
{
	// if the TabNav is not finished loading, don't process any tab clicks
	if (!g_tabnavLoaded)
		return;

	var nodeID = null;
	if (g_listbox2Elem.selectedIndex > -1)
		nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
	else if (g_listbox1Elem.selectedIndex > -1)
		nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	if (nodeID)
	{
		if (nodeID == "0")
		{
			if (g_variation != "DEFAULT")
			{
				updateWaib(g_initialTocItemID);
				setTocSelNoDisp(g_initialTocItemID);

				if (g_listbox2Elem.length > 0)
					nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value;
				else if (g_listbox1Elem.selectedIndex > -1)
					nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;
			}
			else
			{
				showErrMsg("ERR_NO_TOC_ITEM_SELECTED");
				return;
			}
		}
		g_requestTocID = nodeID;
		getTabContent(tabID, nodeID);
	}
}

// Opens the index in a popup browser window. All index entries are displayed at once and anchor links for each letter 
// of the alphabet are listed at the top of the page for jumping to entries starting with that letter.
function onClickIndex()
{
	var indexWnd = window.open("/tabnav/index.jsp?css=" + g_glossaryCss + "&title=" + g_titleParam, "index", "scrollbars,status,width=500,height=400");
	indexWnd.focus();
}

// Opens the index in a popup browser window. Only index entries beginning with the specified letter are displayed at once.
// Links for each letter of the alphabet are listed at the top of the page for opening the index page showing entries starting 
// with that letter.
function onClickSegIndex()
{
	var indexWnd = window.open("/tabnav/segmented_index.jsp?css=" + g_glossaryCss + "&title=" + g_titleParam, "index", "scrollbars,status,width=500,height=400");
	indexWnd.focus();
}


function onClickHome()
{
	top.location = "/hrw/hub_page_director.jsp";
}


function onClickLogout()
{
	top.location = "/hrw/logout.jsp";
}


function onClickHelp()
{
	var helpWnd = window.open(g_helpUrl,'help','toolbar,menubar,scrollbars,resizable,location,status,width=500,height=400');
	helpWnd.focus();
}


function onSessionTimeout()
{
	top.location = "/hrw/login_all.jsp?alert=timeout";
}


function hrwSpawnGlossary()
{
	var glossaryWnd = window.open("/tabnav/" + g_glossaryJsp + ".jsp?css=" + g_glossaryCss + "&title=" + g_titleParam, "glossary", "scrollbars,status,width=500,height=400");
	glossaryWnd.focus();
}


function hrwSpawnGlossaryTerm(term)
{
	// replace spaces with %20
	term = term.split(" ").join("%20");
	// replace & with %26
	term = term.split("&").join("%26");
	var glossaryWnd = window.open("/tabnav/" + g_glossaryJsp + ".jsp?css=" + g_glossaryCss + "&title=" + g_titleParam + "&term=" + term, "glossary", "scrollbars,status,width=500,height=400");
	glossaryWnd.focus();
}


function hrwSpawnGazetteer()
{
	var gazetteerWnd = window.open("/tabnav/" + g_glossaryJsp + ".jsp?type=1&css=" + g_glossaryCss + "&title=" + g_titleParam, "gazetteer", "scrollbars,status,width=500,height=400");
	gazetteerWnd.focus();
}


function hrwSpawnGazetteerTerm(term)
{
	// replace spaces with %20
	term = term.split(" ").join("%20");
	var gazetteerWnd = window.open("/tabnav/" + g_glossaryJsp + ".jsp?type=1&css=" + g_glossaryCss + "&title=" + g_titleParam + "&term=" + term, "gazetteer", "scrollbars,status,width=500,height=400");
	gazetteerWnd.focus();
}

function spawnStudentPageWindow(giveFocus, url, unurl)
{
	g_studentPageWnd = window.open("/tabnav/student_popup_controller.jsp?displayURL=" + url + "&upNavURL=" + unurl, "StudentPage", "scrollbars,resizable,status,width=850,height=400");

	if (giveFocus)
		g_studentPageWnd.focus();
}

//*************************************************************************************************
//
//	The following functions display popup windows for footnotes, images, etc.
//
//*************************************************************************************************


// Show a popup window with parameter noteText
function showPopupNote(noteText)
{
	var noteWindow = window.open("", "noteWindow", "resizable,height=220,width=220,screenX=300,left=300,screenY=300,top=300");
	var noteBody = "<div style=\"font-family:Verdana Arial Helvetica sans-serif\">" + noteText + "</div>";            
	var closeButton = "<a href=\"javascript:window.close()\"><img src=\"/tabnav/images/close_window_off.gif\" width=\"115\" height=\"22\" alt=\"Close Window\" border=\"0\"></img></a>";

	noteWindow.document.write("<HTML><HEAD><TITLE>HRW</TITLE>");
	noteWindow.document.write("</HEAD><BODY bgColor='white'><table height='100%' width='100%'><tr><td valign='top'>" + noteBody + "</td></tr><tr><td height='20'>" + closeButton + "</td></tr></table></BODY></HTML>");
	noteWindow.document.close();
	noteWindow.focus();
}


// Displays an image in the image gallery window.
// src is the URL of the image to be displayed
function showPopupImage(src, caption) 
{ 
	var imgWnd = window.open("/la/eolit/nsmedia/image_gallery.html?src=" + src + "&caption=" + escape(caption), "imageWindow", "resizable,height=410,width=410,screenX=300,left=300,screenY=150,top=150,scrollbars=yes");
	imgWnd.focus();
} 


//*************************************************************************************************
//
//	The following functions submit JSP requests from the comm frame.
//
//*************************************************************************************************


// Submits to a JSP to get the page info for the first page of the unit, chapter, or section specified by tocID.
function getFirstPage(tocID)
{
	var commForm = g_commFrame.document.forms[0];
	commForm.elements["tocID"].value = tocID;
	commForm.action = "/tabnav/get_first_page.jsp";
	commForm.method = "post";
	commForm.submit();
}


// Submits to a JSP to get the tab content info for tab specified by tabID at the TOC location specified by tocID.
function getTabContent(tabID, tocID)
{
	var commForm = g_commFrame.document.forms[0];
	commForm.elements["tabID"].value = tabID;
	commForm.elements["tocID"].value = tocID;
	commForm.action = "/tabnav/get_tab_content.jsp";
	commForm.method = "post";
	commForm.submit();
}


// Submits to a JSP to get the page info of the page specified by pageNum.
// pageNum is either the online textbook page number or the print textbook page number.
function getPage(pageNum)
{
	var commForm = g_commFrame.document.forms[0];
	commForm.elements["pageNum"].value = pageNum;
	commForm.action = "/tabnav/get_page.jsp";
	commForm.method = "post";
	commForm.submit();
}

// Checks if the Student Page URL is available and load it in a popup window.
function getStudentPage(pageNum)
{
	// if there is a valid value passed for pageNum, get the page directly.
	if (pageNum != null && pageNum != "" && pageNum != "undefined")
	{
		g_studentWndFocus = true;
		
		var commForm = g_commFrame.document.forms[0];
		commForm.elements["pageNum"].value = pageNum;
		commForm.elements["studentEditionISBN"].value = g_studentEditionISBN;
		commForm.action = "/tabnav/get_student_page.jsp";
		commForm.method = "post";
		commForm.submit();
	}
	else
	{
		// Otherwise, get the cached student page variables and load the url in the popup window.
		if (g_studentPageWnd != null && !g_studentPageWnd.closed)
		{
			g_studentPageWnd.focus();
		}	
		else if (g_studentPageURL != null || g_studentPageURL != "")
		{
			spawnStudentPageWindow(true, g_studentPageURL, g_studentPopupUpperNav);
		}
		else
		{
			alert("Student Page URL not available.");
		}
	}
}

// Submits to a JSP to get the page info of the page specified by pageID and inc.
// inc is either "-1", "0", or "1" to specify the page before, at, or after pageID.
// If the student page window is driving the page change call get_next_student_page.jsp
function incPage(pageID, inc)
{
	var commForm = g_commFrame.document.forms[0];
	commForm.elements["pageID"].value = pageID;
	commForm.elements["inc"].value = inc;
	commForm.elements["studentEditionISBN"].value = g_studentEditionISBN;
	commForm.elements["studentPageID"].value = g_studentPageID;
	if (g_studentWndFocus)
		commForm.action = "/tabnav/get_next_student_page.jsp";
	else
		commForm.action = "/tabnav/get_next_page.jsp";
	commForm.method = "post";
	commForm.submit();
}


function hrwGotoPage(pageName)
{
	var commForm = g_commFrame.document.forms[0];
	commForm.elements["pageName"].value = pageName;
	commForm.action = "/tabnav/get_page_by_name.jsp";
	commForm.method = "post";
	commForm.submit();
}


function loadContentWithReturn(url)
{
	g_pageFrame.location = url;
	write508SkipNavLink(url);

	g_dataFrame.setCurNode(g_originalTocID);
	if (g_currLoadedWaib != RETURN_WAIB)
	{
		g_waibFrame.location = g_waibReturnUrl;
	}
}


function onReturnToTab()
{
	updateWaib(g_originalTocID);
	g_dataFrame.setCurNode(g_originalTocID);
	onClickTab(g_currTabID)
}


//*************************************************************************************************
//
//	The following functions are called when a JSP finishes loading in the comm frame to notify the 
//	Tabnav that the results of a request are available.
//
//*************************************************************************************************


// Called when results of a tab request are available in the comm frame.
function onGetTabContentReturned()
{
	if (!g_tabMapInit)
		return;

	if (g_commFrame.errMsg != "")
	{
		showErrMsg(g_commFrame.errMsg);
		return;
	}

	if (!g_commFrame.newWnd)
	{
		if (g_commFrame.url.length > 0)
		{
			g_pageFrame.location = g_commFrame.url;
			write508SkipNavLink(g_commFrame.url);
			g_originalTocID = g_requestTocID;
		}
		else if (g_commFrame.venusContentID.length > 0)
		{
			var kwdPgJspUrl = "/tabnav/keyword_page.jsp?tab_content_id=" + g_commFrame.venusContentID;
			g_pageFrame.location = kwdPgJspUrl;
			write508SkipNavLink(kwdPgJspUrl);
		}

		if (g_currLoadedWaib != NO_PAGE_WAIB)
		{
			g_waibFrame.location = g_waibNoPageUrl;
		}

		// swap the tab image to show it as selected
		setCurrTab(g_commFrame.tabID);
	}
	else
	{
		if (g_commFrame.url.length > 0)
		{
			var theWnd = window.open(g_commFrame.url, g_commFrame.tabID, g_commFrame.wndParams);
			theWnd.focus();
		}
		else if (g_commFrame.venusContentID.length > 0)
		{
			var theWnd = window.open("keyword_page.jsp?tab_content_id=" + g_commFrame.venusContentID, g_commFrame.tabID, g_commFrame.wndParams);
			theWnd.focus();
		}
	}
}


// Called when results of a page request are available in the comm frame.
function onGetPageReturned()
{
	if (!g_tabMapInit)
		return;

	if (g_commFrame.errMsg != "")
	{
		showErrMsg(g_commFrame.errMsg);
		return;
	}

	// swap the tab image to show it as selected
	setCurrTab(g_pageTabID);

	if (g_currLoadedWaib != PAGE_WAIB)
	{
		g_waibFrame.location = g_waibUrl;
	}
	else
	{
		// if 508 mode is on, add param to URL for alchemy pages
		adjustAlcURLFor508();

		// if SpyVue mode is on, add param to URL for alchemy pages
		adjustAlcURLForSpyVue();

		g_currPageID = g_commFrame.pageID;
		g_pageTextboxElem.value = g_commFrame.pageNum;
		g_pageFrame.location = g_commFrame.pageURL;
		write508SkipNavLink(g_commFrame.pageURL);
		updateWaib(g_commFrame.tocID);
		setTocSelNoDisp(g_commFrame.tocID);
	}
	
	// Set the global variable with the new studentPageURL and then update the student page window.
	g_studentPageURL = (g_commFrame.studentPageURL != null) ? g_commFrame.studentPageURL : "";
	g_studentPageID = (g_commFrame.studentPageID != null) ? g_commFrame.studentPageID : "";
	updateStudentPageWnd(g_studentPageURL);		
}

//*************************************************************************************************
//
//	The following functions spawn the Notebook in a new browser window.
//
//*************************************************************************************************


// Spawns in top level menu
function hrwSpawnNB()
{
	var notebookWnd = window.open("/notebook/hrwNB.jsp?isbn=" + g_isbn, "notebook", "status,width=290,height=398");
	notebookWnd.focus();
}


// Spawns in specified mode: 0 for question review, 1 for journal, to the level 2 chapter browse menu.
function hrwSpawnNBChapterBrowse(mode)
{
	var notebookWnd = window.open("/notebook/hrwNB.jsp?isbn=" + g_isbn + "&mode=" + mode, "notebook", "status,width=290,height=398");
	notebookWnd.focus();
}


// Spawns in specified mode: 0 for question review, 1 for journal, to the level 3 chapter content menu.
// If a current chapter is not available, this would fall back to the same behavior as top.hrwSpawnNBChapterBrowse(mode).
function hrwSpawnNBChapterContent(mode)
{
	var tocItemParam = "";

	// get the value of the selected item in the 1st listbox
	var nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	// find the node object in the TOC tree array
	var node = findNode(g_dataFrame.Tree, nodeID);
	if (node != null && node.tocItemType == 2)
	{
		tocItemParam = "&tocItem=" + nodeID;
		var notebookWnd = window.open("/notebook/hrwNB.jsp?isbn=" + g_isbn + "&mode=" + mode + tocItemParam, "notebook", "status,width=290,height=398");
		notebookWnd.focus();
	}
	else
	{
		hrwSpawnNBChapterBrowse(mode);
	}
}


// Spawns in a particular question set
function hrwSpawnNBQuesSet(quesSetID)
{
	var notebookWnd = window.open("/notebook/hrwNB.jsp?isbn=" + g_isbn + "&quesSet=" + quesSetID, "notebook", "status,width=290,height=398");
	notebookWnd.focus();
}


// Spawns to a chapter journal entry for the specified type: 0 for notes, 1 for journal.
// If a current chapter is not available, this would fall back to the same behavior as top.hrwSpawnNBChapterContent(1).
function hrwSpawnNBChapterJournal(journalType)
{
	// get the value of the selected item in the 1st listbox
	var nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	// find the node object in the TOC tree array
	var node = findNode(g_dataFrame.Tree, nodeID);

	if (node != null && g_dataFrame.getNodeProp(node, "tocItemType") == 2)
	{
		var notebookWnd = window.open("/notebook/hrwNB.jsp?isbn=" + g_isbn + "&type=" + journalType + "&tocItem=" + nodeID, "notebook", "status,width=290,height=398");
		notebookWnd.focus();
	}
	else
	{
		hrwSpawnNBChapterContent(1);
	}
}


// Spawns to the unit journal for the current unit.
// If a current unit is not available, this would fall back to the same behavior as top.hrwSpawnNBChapterContent(1).
function hrwSpawnNBUnitJournal()
{
	// get the value of the selected item in the 1st listbox
	var nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value;

	// find the node object in the TOC tree array
	var node = findNode(g_dataFrame.Tree, nodeID);

	// The node type here is either 'unit'=1 or 'chapter'=2 since those are the only item types in the 1st listbox.
	// The following code makes sure it passes a unit node and not a chapter node to the jsp.
	if (node != null && g_dataFrame.getNodeProp(node, "tocItemType") == 1)
	{
		var notebookWnd = window.open("/notebook/hrwNB.jsp?type=1&isbn=" + g_isbn + "&tocItem=" + nodeID, "notebook", "status,width=290,height=398");
		notebookWnd.focus();
	}
	else if (node != null && g_dataFrame.getNodeProp(node, "tocItemType") == 2)
	{
		node = findNode(g_dataFrame.Tree, node.parent_id);
		// sanity check - this if should never fail
		if (node != null && g_dataFrame.getNodeProp(node, "tocItemType") == 1)
		{
			var notebookWnd = window.open("/notebook/hrwNB.jsp?type=1&isbn=" + g_isbn + "&tocItem=" + node.id, "notebook", "status,width=290,height=398");
			notebookWnd.focus();
		}
		else
		{
			hrwSpawnNBChapterContent(1);
		}
	}
	// the code should never get to this else
	else
	{
		hrwSpawnNBChapterContent(1);
	}
}

// Spawns in top level menu, in default size
function hrwSpawn508NB(templateName)
{
	var notebookWnd = window.open("/notebook/508/main.jsp?isbn=" + g_isbn + "&template=" + templateName, "notebook", "menubar,scrollbars,resizable,status,width=450,height=570");
	notebookWnd.focus();
}

function hrwSpawn508NBSized(templateName,width,height)
{
	var notebookWnd = window.open("/notebook/508/main.jsp?isbn=" + g_isbn + "&template=" + templateName, "notebook", "menubar,scrollbars,resizable,status,width=" + width + ",height=" + height);
	notebookWnd.focus();
}

// Spawns to a particular question set, to the first question, in default size
function hrwSpawn508NBQuesSet(templateName, quesSetID)
{
	var notebookWnd = window.open("/notebook/508/nqset.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesSetID, "notebook", "menubar,scrollbars,resizable,status,width=450,height=570");
	notebookWnd.focus();
}

function hrwSpawn508NBQuesSetSized(templateName, quesSetID, width, height)
{
	var notebookWnd = window.open("/notebook/508/nqset.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesSetID, "notebook", "menubar,scrollbars,resizable,status,width=" + width + ",height=" + height);
	notebookWnd.focus();
}

// Spawns to a particular question, given that the question set is unknown, in default size
function hrwSpawn508NBQuestion(templateName, quesID)
{
	var notebookWnd = window.open("/notebook/508/nq.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesID, "notebook", "menubar,scrollbars,resizable,status,width=450,height=570");
	notebookWnd.focus();
}

function hrwSpawn508NBQuestionSized(templateName, quesID, width, height)
{
	var notebookWnd = window.open("/notebook/508/nq.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesID, "notebook", "menubar,scrollbars,resizable,status,width=" + width + ",height=" + height);
	notebookWnd.focus();
}

// Spawns to a particular question set, to the given question, in default size
function hrwSpawn508NBQuesSetQues(templateName, quesSetID, questionID)
{
	var notebookWnd = window.open("/notebook/508/nqset.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesSetID + "&questionID=" + questionID, "notebook", "menubar,scrollbars,resizable,status,width=450,height=570");
	notebookWnd.focus();
}

function hrwSpawn508NBQuesSetQuesSized(templateName, quesSetID, questionID, width, height)
{
	var notebookWnd = window.open("/notebook/508/nqset.jsp?isbn=" + g_isbn + "&template=" + templateName + "&q=" + quesSetID + "&questionID=" + questionID, "notebook", "menubar,scrollbars,resizable,status,width=" + width + ",height=" + height);
	notebookWnd.focus();
}


//*************************************************************************************************
//
//	The following functions swap tab images to reflect a tabs current state.
//
//*************************************************************************************************


// changes the tab image and the status bar text when hovering over a tab
function onOverTab(tabID)
{
	if (!g_tabMapInit)
		return;

	if (g_currTabID != tabID && g_tabMap[tabID].overImg.length > 0)
		g_tabMap[tabID].tagRef.src = g_tabMap[tabID].overImg;

	window.status = g_tabMap[tabID].altText;
	return true;
}


// changes the tab image back and the status bar text back when finished hovering over a tab
function onOutTab(tabID)
{
	if (!g_tabMapInit)
		return;

	if (g_currTabID == tabID)
	{
		if (g_tabMap[tabID] != null && g_tabMap[tabID].selImg.length > 0)
			g_tabMap[tabID].tagRef.src = g_tabMap[tabID].selImg;
	}
	else
	{
		g_tabMap[tabID].tagRef.src = g_tabMap[tabID].outImg;
	}

	window.status = "";
	return true;
}


// do some image swapping of the tabs to show the new selected tab
function setCurrTab(tabID)
{
	if (!g_tabMapInit)
		return;

	if (g_currTabID != null)
		g_tabMap[g_currTabID].tagRef.src = g_tabMap[g_currTabID].outImg;

	if (g_currTabID != null) {

		if (g_tabMap[tabID] && g_tabMap[tabID].selImg.length > 0)
			g_tabMap[tabID].tagRef.src = g_tabMap[tabID].selImg;

		if (tabID && tabID != "")
			g_currTabID = tabID;
	}	
}


//*************************************************************************************************
//
//	The following function displays error messages in an alert box.
//
//*************************************************************************************************


function showErrMsg(errCode)
{
	var errMsg = g_errObj[errCode];
	if (!errMsg)
	{
		errMsg = g_errObj["ERR_INTERNAL_ERROR"];
		if (!errMsg)
		{
			if(errCode == "ERR_PAGE_NOT_FOUND"){
				errMsg = "Unable to locate chapter or page.";
			}else{
				errMsg = "Unknown error occurred.";
			}
		}
	}
	else if (errCode == "ERR_KEYWORD_NOT_FOUND")
	{
		errMsg += "\nKeyword: '" + g_commFrame.keyword + "'";
	}

	alert(errMsg);
}


//*************************************************************************************************
//
//	The following functions are for bookmarking.
//
//*************************************************************************************************


// sets a bookmark
function setBookmark()
{
	if (g_currTabID == g_pageTabID)
	{
		var commForm = g_commFrame.document.forms[0];
		commForm.elements["pageNum"].value = g_commFrame.pageNum;
		commForm.elements["pageID"].value = g_currPageID;
		commForm.elements["tocID"].value = g_currTabID;
		commForm.action = "/tabnav/set_bookmark.jsp";
		commForm.method = "post";
		commForm.submit();
	}
	else
	{
		alert("You must have a textbook page loaded to set a bookmark.");
	}
}


// returns to a bookmark
function gotoBookmark()
{
	var commForm = g_commFrame.document.forms[0];
	commForm.action = "/tabnav/goto_bookmark.jsp";
	commForm.method = "post";
	commForm.submit();
}


//*************************************************************************************************
//
//	Functions added by Dave Alvarado
//
//*************************************************************************************************


function onClickGoNavEolit() 
{ 

        // if the TabNav is not finished loading, don't process button click 
        if (!g_tabnavLoaded) 
                return; 

        var nodeID = null; 
        if (g_listbox2Elem.length > 0) 
                nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value; 
        else if (g_listbox1Elem.selectedIndex > -1) 
                nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value; 

        if (nodeID) 
        { 
                if (nodeID == "0") 
                { 
                        if (g_variation == "DEFAULT" || g_variation == "EOLIT") 
                        { 
                                showErrMsg("ERR_NO_TOC_ITEM_SELECTED"); 
                                return; 
                        } 
                        else 
                        { 
                                updateWaib(g_initialTocItemID); 
                                setTocSelNoDisp(g_initialTocItemID); 

                                if (g_listbox2Elem.length > 0) 
                                        nodeID = g_listbox2Elem.options[g_listbox2Elem.selectedIndex].value; 
                                else if (g_listbox1Elem.selectedIndex > -1) 
                                        nodeID = g_listbox1Elem.options[g_listbox1Elem.selectedIndex].value; 
                        } 
                } 

                onClickPageTab(); 
        } 
        else 
        { 
                if (g_currTabID == g_pageTabID) 
                        showErrMsg("ERR_NO_OPENING_PAGE"); 
                else 
                        showErrMsg("ERR_NO_TAB_CONTENT"); 
        } 
} 


//*************************************************************************************************
//
//	The following function toggles 508 mode off and on for alchemy pages.
//
//*************************************************************************************************

function toggle508Mode()
{
	g_is508ModeOn = !g_is508ModeOn;
	write508SkipNavLink();
}

function adjustAlcURLFor508()
{
	// if 508 mode is on, add param to URL for alchemy pages
	if (g_is508ModeOn)
	{
		// if this is an alchemy page, add the user accessibility parameter
		if (g_commFrame.pageURL.indexOf("/apps/alchemy/editors/display.jsp") != -1)
		{
			g_commFrame.pageURL += "&user=accessibility:high";
		}
	}
}

function adjustAlcURLForSpyVue()
{
	// if SpyVue mode is on, add param to URL for alchemy pages
	if (g_SpyVueLoaded == true)
	{
		// if this is an alchemy page, add the user accessibility parameter
		if (g_commFrame.pageURL.indexOf("/apps/alchemy/editors/display.jsp") != -1)
		{
			g_commFrame.pageURL += "&test=state:done";
		}
	}
}

function write508SkipNavLink(url)
{
	if (g_has508)
	{
		var spanElem = g_upperNavFrame.document.getElementById("skipNav508Span");
		if (spanElem)
		{
			if (g_is508ModeOn)
			{
				if (!url)
				{
					url = g_pageFrame.location.pathname;
				}

				// normally, the target frame is "page"
				var target = "page";

				// if an alchemy page is opened, the target frame is "main"
				if (url.indexOf("/apps/alchemy/editors/display.jsp") != -1)
				{
					target = "main";
				}

				spanElem.innerHTML = '<a href="' + url + '#skipnav" target="' + target + '">' + g_skipnav508Ctrl + '</a>';
			}
			else
			{
				spanElem.innerHTML = '';
			}
		}
	}
}
