// NAV_FUNCTIONALITY SCRIPT STARTS HERE

//    MODIFICATION HISTORY
//    
//    02-21-04 DC Pulled global text into a GLOBAL TEXT section and added 
//                functions to display text with and without tags based on flag
//    02-22-04 DC Added folio suffix handling
// - ###############################################################################
//    GLOBAL CONSTANTS
// -

// DEBUGGING Setting
//
// uncomment the appropriate line for debugging mode:
//   DEGUGGING when true will display alerts for page URLs and popup URLs
//
//DEBUGGING = true;
DEBUGGING = false;

STATE_ABBR_COOKIE_NAME = 'eBookStateAbbr';

DEFAULT_PAGE_SIZE = 2;
DEFAULT_STATE_ABBR = 'NA';

// pop-up location
POPUP_LOCATION_OPENER = true;
POPUP_LOCATION_SCREEN = false;

POPUP_LEFT_OFFSET = 50;
POPUP_TOP_OFFSET = 50;
POPUP_LEFT_OFFSET_MINIMUM = 10;
POPUP_TOP_OFFSET_MINIMUM = 10;

POPUP_MINIMUM_WIDTH = 500;
POPUP_MINIMUM_HEIGHT = 350;

SCREEN_MARGIN = 25;
SCREEN_MIN_MARGIN = 5;

// pop-up chrome types
POPUP_CHROME_MINIMUM = 0;
POPUP_CHROME_MENUBAR = 1;
POPUP_CHROME_FULL = 2;
POPUP_CHROME = new Array();
POPUP_CHROME[POPUP_CHROME_MINIMUM] = 'channelmode=no,directories=no,fullscreen=no,location=no,menubar=no,resizable=yes,scrollbars=yes,status=yes,titlebar=no,toolbar=no';
POPUP_CHROME[POPUP_CHROME_MENUBAR] = 'channelmode=no,directories=no,fullscreen=no,location=no,menubar=yes,resizable=yes,scrollbars=yes,status=yes,titlebar=no,toolbar=no';
POPUP_CHROME[POPUP_CHROME_FULL] = 'channelmode=no,directories=no,fullscreen=no,location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=yes,titlebar=yes,toolbar=yes';
POPUP_CHROME_HEIGHT = new Array();
POPUP_CHROME_HEIGHT[POPUP_CHROME_MINIMUM] = 50;
POPUP_CHROME_HEIGHT[POPUP_CHROME_MENUBAR] = 75;
POPUP_CHROME_HEIGHT[POPUP_CHROME_FULL] = 150;
POPUP_CHROME_WIDTH = new Array();
POPUP_CHROME_WIDTH[POPUP_CHROME_MINIMUM] = 10; // changed from 25 to fit 800x600
POPUP_CHROME_WIDTH[POPUP_CHROME_MENUBAR] = 25;
POPUP_CHROME_WIDTH[POPUP_CHROME_FULL] = 25;

// pop-up settings

//
// NOTE: Keep *_MIN_WIDTHs x *_MIN_HEIGHTs at or below 765x545
//       for 800x600 minimum resolution support
//

POPUP_EBOOK_WIDTH = 925;
POPUP_EBOOK_HEIGHT = 820;
POPUP_EBOOK_MIN_WIDTH = 760;
POPUP_EBOOK_MIN_HEIGHT = 540;
POPUP_EBOOK_NAME = 'EBook';
POPUP_EBOOK_CHROME_TYPE = POPUP_CHROME_MINIMUM;

POPUP_HELP_WIDTH = 755;
POPUP_HELP_HEIGHT = 700;
POPUP_HELP_MIN_WIDTH = 755;
POPUP_HELP_MIN_HEIGHT = 540;
POPUP_HELP_NAME = 'Help';
POPUP_HELP_CHROME_TYPE = POPUP_CHROME_MENUBAR;

POPUP_EPLINK_WIDTH = 620;
POPUP_EPLINK_HEIGHT = 660;
POPUP_EPLINK_MIN_WIDTH = 620;
POPUP_EPLINK_MIN_HEIGHT = 540;
POPUP_EPLINK_NAME = 'EPLink';
POPUP_EPLINK_CHROME_TYPE = POPUP_CHROME_FULL;

POPUP_BOTHPAGES_WIDTH = 755;
POPUP_BOTHPAGES_HEIGHT = 700;
POPUP_BOTHPAGES_MIN_WIDTH = 755;
POPUP_BOTHPAGES_MIN_HEIGHT = 540;
POPUP_BOTHPAGES_NAME = 'BothPages';
POPUP_BOTHPAGES_CHROME_TYPE = POPUP_CHROME_MINIMUM;

POPUP_HOMEWORK_WIDTH = 755;
POPUP_HOMEWORK_HEIGHT = 700;
POPUP_HOMEWORK_MIN_WIDTH = 755;
POPUP_HOMEWORK_MIN_HEIGHT = 540;
POPUP_HOMEWORK_NAME = 'Homework';
POPUP_HOMEWORK_CHROME_TYPE = POPUP_CHROME_MENUBAR;

POPUP_PRINTABLE_WIDTH = 755;
POPUP_PRINTABLE_HEIGHT = 700;
POPUP_PRINTABLE_MIN_WIDTH = 755;
POPUP_PRINTABLE_MIN_HEIGHT = 540;
POPUP_PRINTABLE_NAME = 'Printable';
POPUP_PRINTABLE_CHROME_TYPE = POPUP_CHROME_MENUBAR;

// directions
DIRECTION_NEXT = 1;
DIRECTION_PREV = -1;

// -
//    GLOBAL CONSTANTS
// - ###############################################################################

// GLOBAL TEXT / GUI TEXT constants moved to functionality.js

// + ###############################################################################
//     eBook Objects


// + ==============================================
//     Folio Class
//       Properties:
//         prefix : string
//         number : integer
//         suffix : string
//
//       Methods:
//         Folio(folioStr : string) : Folio
//         toString() : string
//         isFolioEmpty() : boolean
//         isFolioOdd() : boolean
//         getNextOrPrevFolio(direction : DIRECTION) : string
//         isInFolioRange(startFolio : string, endFolio : string) : boolean
//
//       Class Methods:
//         translateRomanNumberFolio(folio : string) : string
//         newFolioFromParts(folioPrefix : string, folioNumber : integer, folioSuffix : string) : string
//         toStringFromParts(folioPrefix : string, folioNumber : integer, folioSuffix : string) : string
// + ==============================================

function Folio(folioStr) {

	this.prefix = '';
	this.number = 0;
	this.suffix = '';
		
	// allow an empty folio
	if (folioStr == '') {
		return;
	}
	
	// cleans the folio of anything but letters and digits
	var regex = /\W|\_/g;
	folioStr = folioStr.replace(regex, '');

	// substitute front matter folios for roman numerals
	regex = /^[ivx]+$/i;
	if (regex.exec(folioStr)) {
		folioStr = Folio.translateRomanNumberFolio(folioStr);
	}
	
	// test for standard optional prefix, digits, optional suffix (FM001, 001, 001a etc.)
	regex = /^(\D*)(\d+)([a-z]*)$/i;
	if (regex.exec(folioStr)) {
		this.prefix = RegExp.$1;
		this.number = parseInt(RegExp.$2, 10);
		this.suffix = RegExp.$3;
		return;
	}

	// test for kindergarten pull outs (01p1)
	regex = /^(\d+)(p\d+)$/i;
	if (regex.exec(folioStr)) {
		this.prefix = '';
		this.number = parseInt(RegExp.$1, 10);
		this.suffix = RegExp.$2;
		
		return;
	}

	// invalid folio string, return null
	return null;
			
} // Folio constuctor


Folio.prototype.toString = function() {

	// kindergarten pull-out numbers have 2 digits, others 3
	var folioNumberString = '';

	// test for kindergarten pullout suffix
	var regex = /^p\d+$/i;
	if (this.suffix && regex.exec(this.suffix)) {

		// we are working with kindergarten pullout
		// get a 2-digit number string
		folioNumberString = String (100 + this.number);
    	folioNumberString = folioNumberString.substring(1);

	} else if (!this.isFolioEmpty()) {
	
		// non-empty folio, get a 3-digit number string
		folioNumberString = String (1000 + this.number);
    	folioNumberString = folioNumberString.substring(1);
 
	} else {
	
		// empty folio => empty folioNumberString (as initialized)
		
	}

	// assemble string from parts   
	return this.prefix + folioNumberString + this.suffix.toString();

} // Folio.prototype.toString


Folio.prototype.isFolioEmpty = function() {

	if (this.number || this.prefix || this.suffix) {
		return false;
	} else {
		return true;
	}
	
} // Folio.prototype.isFolioEmpty


Folio.prototype.isFolioOdd = function (folio) {

	if (this.suffix) {
		// folio has suffix, test oddness of suffix
		var regex = /^p(\d+)$/i;
		if (regex.exec(this.suffix)) {
			// kindergarten pullout
			if (RegExp.$1 % 2 == 1) {
				return true;
			} else {
				return false;
			}    
		} else {
			// single alphanumeric character suffix
			if (Folio.ODD_ALPHA_SUFFIXES.indexOf(this.suffix) != -1) {
				// found suffix in odd suffixes
				return true;
			} else {
				return false;
			}
		}
	} else {
		// folio doesn't have a suffix, return oddness of number
		if (this.number % 2 == 1) {
			return true;
		} else {
			return false;
		}
	}   
	
} // Folio.prototype.isFolioOdd


Folio.prototype.isInFolioRange = function(startFolioStr, endFolioStr) {

	// if folio invalid or empty, not in range
	if (this.isFolioEmpty()) return false;
	
	// if start or end folios invalid, not in range (might want to flag data file problem)
	var startFolio = new Folio(startFolioStr);
	var endFolio = new Folio(endFolioStr);
	if (!startFolio || !endFolio) return false;
	
	// if prefixes don't match, not in range	
	if (this.prefix != startFolio.prefix) {
		// folio prefixes don't match, not in range
		return false;
	}
	
	// if neither folio nor range folios have suffixes then folio number needs to be in number range
	if (!this.suffix && !startFolio.suffix) {
		// check that folio number is in range
		if (	(this.number >= startFolio.number)
			&&	(this.number <= endFolio.number)
		   )
		{
			return true;
		} else {
			return false;
		}
	}
	
	// if both folio and range folios have suffixes then the numbers and suffixes must be the same to be in range
	if (this.suffix && startFolio.suffix) {

		if (	(this.number == startFolio.number)
			&&	(this.suffix == startFolio.suffix)
		   )
		{
			return true;
		} else {
			return false;
		}
	}
	
	// only one of folio and folio range has a suffix, not in range
	return false;
		
} // Folio.prototype.isFolioInFolioRange


Folio.prototype.getNextOrPrevFolio = function (nextOrPrev) {

	if (this.suffix) {
		// punt if there is a suffix
		return null;
	} else {
	
		var nextOrPrevNumber = this.number;
	
		nextOrPrevNumber += nextOrPrev;
		if (	(nextOrPrevNumber < 0) 
			||	(nextOrPrevNumber >= 1000) 
		   )
		{
			// number out of range
			return null;
		} else {
			// assemble new folio from folio and new number
			return Folio.newFolioFromParts(this.prefix, nextOrPrevNumber, '');
			
		}
	}

} // Folio.prototype.getNextOrPrevFolio


// CLASS PROPERTY
Folio.ODD_ALPHA_SUFFIXES = 'a c e g i k m o q s u w y ';


// CLASS METHOD
Folio.newFolioFromParts = function (folioPrefix, folioNumber, folioSuffix) {

	var folio = new Folio('');

    folio.prefix = folioPrefix;
    folio.number = folioNumber;
    folio.suffix = folioSuffix;
    
    return folio;
	
} // Folio.newFolioFromParts


// CLASS METHOD
Folio.toStringFromParts = function (folioPrefix, folioNumber, folioSuffix) {

    var folio = Folio.newFolioFromParts(folioPrefix, folioNumber, folioSuffix);
    return folio.toString();
	
} // Folio.toStringFromParts


// CLASS METHOD
Folio.translateRomanNumberFolio = function ( folioStr )
{
    var UCFolio = folioStr.toUpperCase();

    if ( UCFolio == "I" ) folioStr = "FM001" ;
    else if ( UCFolio == "II" ) folioStr = "FM002" ;
    else if ( UCFolio == "III" ) folioStr = "FM003" ;
    else if ( UCFolio == "IV" ) folioStr = "FM004" ;
    else if ( UCFolio == "V" ) folioStr = "FM005" ;
    else if ( UCFolio == "VI" ) folioStr = "FM006" ;
    else if ( UCFolio == "VII" ) folioStr = "FM007" ;
    else if ( UCFolio == "VIII" ) folioStr = "FM008" ;
    else if ( UCFolio == "IX" ) folioStr = "FM009" ;
    else if ( UCFolio == "X" ) folioStr = "FM010" ;
    else if ( UCFolio == "XI" ) folioStr = "FM011" ;
    else if ( UCFolio == "XII" ) folioStr = "FM012" ;
    else if ( UCFolio == "XIII" ) folioStr = "FM013" ;
    else if ( UCFolio == "XIV" ) folioStr = "FM014" ;
    else if ( UCFolio == "XV" ) folioStr = "FM015" ;
    else if ( UCFolio == "XVI" ) folioStr = "FM016" ;
    else if ( UCFolio == "XVII" ) folioStr = "FM017" ;
    else if ( UCFolio == "XVIII" ) folioStr = "FM018" ;
    else if ( UCFolio == "XIX" ) folioStr = "FM019" ;
    else if ( UCFolio == "XX" ) folioStr = "FM020" ;
    else if ( UCFolio == "XXI" ) folioStr = "FM021" ;
    else if ( UCFolio == "XXII" ) folioStr = "FM022" ;
    else if ( UCFolio == "XXIII" ) folioStr = "FM023" ;
    else if ( UCFolio == "XXIV" ) folioStr = "FM024" ;
    else if ( UCFolio == "XXV" ) folioStr = "FM025" ;
    else if ( UCFolio == "XXVI" ) folioStr = "FM026" ;
    else if ( UCFolio == "XXVII" ) folioStr = "FM027" ;
    else if ( UCFolio == "XXVIII" ) folioStr = "FM028" ;
    else if ( UCFolio == "XXIX" ) folioStr = "FM029" ;
    else if ( UCFolio == "XXX" ) folioStr = "FM030" ;

    return folioStr ;

} // translateRomanNumberFolio


//     End of Folio object
// - ==============================================


// + ==============================================
//     Page object
//       Properties:
//         folio : folio
//         pageRange : PageRange
//
//       Class Properties:
//         CURRENT_PAGE : 'CURRENT_PAGE'
//
//       Methods:
//         Page(folioStr : string) : Page
//         toPageCode() : string
//         toURL() : string
//
//       Class Methods:
//         getFolioFromPageCode(pageCode : string) : string
// + ==============================================

function Page(folio, pageRange) {

	this.folio = folio;
	this.pageRange = pageRange;
	
} // Page constructor


Page.prototype.toPageCode = function () {

	return this.pageRange.pagePrefix + this.folio.toString();
	
} // Page.prototype.toPageCode


Page.prototype.toURL = function () {

	var queryString = '';

	queryString = '?s=' + eBookViewer.userState;
	queryString += '&ps=' + GetSize();

	return sessionInfo.baseURL + '/' + this.toPageCode() + '.html' + queryString;
	
} // Page.prototype.toURL


// CLASS METHOD
Page.getFolioFromPageCode = function (pageCode) {

	var regex = /([^\-]+)$/;
	if (regex.exec(pageCode)) {
		return new Folio(RegExp.$1);
	} else {
		return null;
	}
	
} // Page.getFolioStrFromPageCode


//     End of Page object
// - ==============================================



// + ==============================================
//     PageRange object
//       Properties:
//         startFolioStr : string
//         endFolioStr : string
//         pagePrefix : string
//         oddLeftPage : boolean
//         pageRangeIndex : integer
//
//       Methods:
//         PageRange(pageRangeString: string, pageRangeIndex : integer) : PageRange
//         isFolioInPageRange(folio : Folio) : boolean
// + ==============================================

function PageRange(pageRangeString, pageRangeIndex) {

	// parse pageRangeString to get properties
	var pageRangeFields = pageRangeString.split('\t');
	this.startFolioStr = pageRangeFields[0];
	this.endFolioStr = pageRangeFields[1];
	this.pagePrefix = pageRangeFields[2];
	if (pageRangeFields[3] != '0') {
		this.oddLeftPage = true;
	} else {
		this.oddLeftPage = false;
	}

	// index into pageRanges array
	this.pageRangeIndex = pageRangeIndex;
	
} // PageRange constructor


PageRange.prototype.isFolioInPageRange = function(folio) {

	return folio.isInFolioRange(this.startFolioStr, this.endFolioStr);
		
} // PageRange.prototype.isFolioInPageRange


//     End of PageRange object
// - ==============================================



// + ==============================================
//     EBook object
//       Properties:
//         pageRanges : Array of PageRange
//         TOCFirstFolio : string
//
//       Methods:
//         EBook(pageRangeString : string, TOCFirstFolioStr : string) : EBook
//         getNextOrPrevPage(page : Page, direction : DIRECTION) : Page
//         getNextOrPrevPageRange(pageRange : PageRange, direction : DIRECTION) : PageRange
//         getPageRangeFromFolio(folio : Folio) : PageRange
//         getBothPageCodes(page : Page) : Array[1] of strings 
// + ==============================================

function EBook(pageRangesString, TOCFirstFolioStr) {

	this.pageRanges = new Array();
	var pageRangeStringArray = pageRangesString.split('\n');
	for (var r=0; r<pageRangeStringArray.length; r++) {

		// create new pageRange from string and append to pageRanges array
		this.pageRanges[this.pageRanges.length] = new PageRange(pageRangeStringArray[r], this.pageRanges.length);		

	}
	
	this.TOCFirstFolio = new Folio(TOCFirstFolioStr);

} // EBook constructor


EBook.prototype.getNextOrPrevPage = function (page, nextOrPrev) {

	// get next/prev numeric folio
	var nextOrPrevFolio = page.folio.getNextOrPrevFolio(nextOrPrev);

	// return next/prev folio if it is in current pageRange
	if (nextOrPrevFolio) {
		if (page.pageRange.isFolioInPageRange(nextOrPrevFolio)) {
			return new Page(nextOrPrevFolio, page.pageRange);
		}
	}
	
	// next/prev out of current range, get next/prev pageRange and return start/end page

	var nextOrPrevPageRange = this.getNextOrPrevPageRange(page.pageRange, nextOrPrev);
	if (nextOrPrevPageRange) {
		if (nextOrPrev == DIRECTION_NEXT) {
			// next folio is startFolio of pageRange
			nextOrPrevFolio = new Folio(nextOrPrevPageRange.startFolioStr);
		} else {
			// prev folio is endFolio of pageRange
			nextOrPrevFolio = new Folio(nextOrPrevPageRange.endFolioStr);
		}
		return new Page(nextOrPrevFolio, nextOrPrevPageRange);
	} else {
		// couldn't find a next/prev pageRange
		return null;
	}
		
} // EBook.prototype.getNextOrPrevPage


EBook.prototype.getNextOrPrevPageRange = function (pageRange, nextOrPrev) {

	var nextOrPrevPageRangeIndex = pageRange.pageRangeIndex + nextOrPrev;
	
	if (	(nextOrPrevPageRangeIndex < 0) 
		||	(nextOrPrevPageRangeIndex >= this.pageRanges.length)
	   )
	{
		// no next/prev pageRange, out of bounds
		return null;
	}
	
	// return the next/prev pageRange
	return this.pageRanges[nextOrPrevPageRangeIndex];
	
} // EBook.prototype.getNextOrPrevPageRange


EBook.prototype.getPageRangeFromFolio = function (folio) {

	// loop through pageRanges looking for a pageRange that contains the folio
	for (var r=0; r<this.pageRanges.length; r++) {
		if (this.pageRanges[r].isFolioInPageRange(folio)) {
			return this.pageRanges[r];
		}
	}
	
	return null;
	
} // EBook.prototype.getPageRangeFromFolio


EBook.prototype.getBothPageCodes = function (page) {

	var bothPageCodes = Array();
	
	var pageIsOdd = page.folio.isFolioOdd();
	
	if (	(pageIsOdd && page.pageRange.oddLeftPage)
		||	(!pageIsOdd && !page.pageRange.oddLeftPage)
	   )
	{

		// current page is left page
		bothPageCodes[0] = page.toPageCode();
		
		// right page is next page
		var nextPage = this.getNextOrPrevPage(page, DIRECTION_NEXT);
		if (nextPage) {
			bothPageCodes[1] = nextPage.toPageCode();
		} else {
			bothPageCodes[1] = 'blank';
		}
		
	} else {

		// current page is right page
		bothPageCodes[1] = page.toPageCode();
		
		// left page is prev page
		var prevPage = this.getNextOrPrevPage(page, DIRECTION_PREV);
		if (prevPage) {
			bothPageCodes[0] = prevPage.toPageCode();
		} else {
			bothPageCodes[0] = 'blank';
		}
		
	}

	return bothPageCodes;
	
} // EBook.prototype.getBothPageCodes


//     End of EBook object
// - ==============================================


// + ==============================================
//     EBookViewer object
//       Properties:
//         eBook : EBook
//         currentPage : Page
//         pageSize : int
//         userState : string
//         userStateName : string
//         popupWindows : Array of window references
//       Methods:
//         gotoPage(page : Page) : 0 if fails
//         gotoFolioStr(folio : string) : 0 if fails
//         gotoNextOrPrevPage(direction : DIRECTION) : 0 if fails
//         gotoTOC() : 0 if fails
//         popupResource(URL : string, width : integer, height : integer, name : string) : Window
//         popupBothPages() : Window
//         popupEPLink(pageSpecificLink : boolean) : Window
//         popupPrintPage() : Window
//         setPageSize(pageSize : integer)
//         getEBookGrade() : character
// + ==============================================

function EBookViewer(eBook, sessionInfo) {

	this.eBook = eBook;
	var currentFolio = Page.getFolioFromPageCode(sessionInfo.pageCode);
	var currentPageRange = eBook.getPageRangeFromFolio(currentFolio);
	this.currentPage = new Page(currentFolio, currentPageRange);
	this.pageSize = sessionInfo.pageSize;
	this.userState = sessionInfo.userState;
	this.userStateName = sessionInfo.userStateName;
	this.popupWindows = new Array();
	
} // EBookViewer constructor


EBookViewer.prototype.gotoPage = function (page) {

	var newPageURL = page.toURL();
	
	if (DEBUGGING) {
		alert('gotoPage => ' + newPageURL);
	}

	window.location.href = newPageURL;

	return 1;
	
} // EBookViewer.prototype.gotoPage


EBookViewer.prototype.gotoFolioStr = function (folioStr) {

	if (!folioStr) return 0;
	
	var folio = new Folio(folioStr);
	if (!folio) return 0;

	var folioPageRange = eBook.getPageRangeFromFolio(folio);
	if (!folioPageRange) return 0;
	
	var folioPage = new Page(folio, folioPageRange);

	return this.gotoPage(folioPage);

} // EBookViewer.prototype.gotoFolioStr


EBookViewer.prototype.gotoNextOrPrevPage = function (nextOrPrev) {

	var nextOrPrevPage = this.eBook.getNextOrPrevPage(this.currentPage, nextOrPrev);
	
	if (nextOrPrevPage) {
		this.gotoPage(nextOrPrevPage);
		return 1;
	} else {
		return 0;
	}
	
} // EBookViewer.prototype.gotoPage


EBookViewer.prototype.gotoTOC = function () {

	var TOCPageRange = eBook.getPageRangeFromFolio(this.eBook.TOCFirstFolio);
	var TOCPage = new Page(this.eBook.TOCFirstFolio, TOCPageRange);
	
	if (TOCPage) {
		this.gotoPage(TOCPage);
	} else {
		return 0;
	}
	
} // EBookViewer.prototype.gotoTOC


EBookViewer.prototype.redisplayPage = function () {

	this.gotoPage(this.currentPage);
	return 1;
	
} // EBookViewer.prototype.gotoPage


EBookViewer.prototype.popupResource = function (resourceURL, name, width, height, minWidth, minHeight, chromeType) {

	if (DEBUGGING) {
  		alert('popup => ' + resourceURL);
  	}

	// if existing popup close it
	//if (this.popupWindows[name] && !this.popupWindows[name].closed) {
	//	this.popupWindows[name].close();
	//}
	// close all popups with other names
	for (popupWindowIndex in this.popupWindows) {
		if (	(popupWindowIndex != name)
			&&	this.popupWindows[popupWindowIndex]
			&& 	!this.popupWindows[popupWindowIndex].closed
		   )
		{
			this.popupWindows[popupWindowIndex].close();
		}
	}

	// popup the resource and save reference to it
 	var resourceWindow = popupWindow(resourceURL, name, 
 										width, height, 
 										minWidth, minHeight, 
 										chromeType, POPUP_LOCATION_OPENER);
	
	this.popupWindows[name] = resourceWindow;
	
	return resourceWindow;
	
} // EBookViewer.prototype.popupResource


EBookViewer.prototype.popupEPLink = function (pageSpecificLink) {

//	old direct link to education place
//	var EPLinkURL = "http://www.eduplace.com/cgi-bin/jumpto/emathbook?" + this.currentPage.toPageCode();

	var EPLinkURL = "../resources/eplink.html";
	
// removed logic that embedded the next line in: if (pageSpecificLink) 

	EPLinkURL += "?" + this.currentPage.toPageCode();

	var popupWindow = this.popupResource(EPLinkURL, POPUP_EPLINK_NAME,
											POPUP_EPLINK_WIDTH, POPUP_EPLINK_HEIGHT, 
											POPUP_EPLINK_MIN_WIDTH, POPUP_EPLINK_MIN_HEIGHT, 
											POPUP_EPLINK_CHROME_TYPE);

} // EBookViewer.prototype.popupEPLink


EBookViewer.prototype.popupBothPages = function (leftImageType, rightImageType) {

	var bothPages = this.eBook.getBothPageCodes(this.currentPage);
	
//	var bothPagesURL = "bothpages.html?lp=" + bothPages[0] + "&rp=" + bothPages[1];
	var bothPagesURL = "../resources/bothpages.html?" + bothPages[0] + '.' + leftImageType + "/" + bothPages[1] + '.' + rightImageType;

	var popupWindow = this.popupResource(bothPagesURL, POPUP_BOTHPAGES_NAME, 
											POPUP_BOTHPAGES_WIDTH, POPUP_BOTHPAGES_HEIGHT, 
											POPUP_BOTHPAGES_MIN_WIDTH, POPUP_BOTHPAGES_MIN_HEIGHT, 
											POPUP_BOTHPAGES_CHROME_TYPE);

} // EBookViewer.prototype.popupBothPages


EBookViewer.prototype.popupHomework = function (homeworkCode) {

	var homeworkURL = '../resources/homework.html?' + homeworkCode;
	var popupWindow = this.popupResource(homeworkURL, POPUP_HOMEWORK_NAME, 
											POPUP_HOMEWORK_WIDTH, POPUP_HOMEWORK_HEIGHT, 
											POPUP_HOMEWORK_MIN_WIDTH, POPUP_HOMEWORK_MIN_HEIGHT, 
											POPUP_HOMEWORK_CHROME_TYPE);

} // EBookViewer.prototype.popupHomework


EBookViewer.prototype.popupPrintableVersion = function () {

//	var printableVersionURL = "printable.html?p=" + this.currentPage.toPageCode();
	var printableVersionURL = "../resources/printable.html?" + this.currentPage.toPageCode();

	var popupWindow = this.popupResource(printableVersionURL, POPUP_PRINTABLE_NAME, 
											POPUP_PRINTABLE_WIDTH, POPUP_PRINTABLE_HEIGHT, 
											POPUP_PRINTABLE_MIN_WIDTH, POPUP_PRINTABLE_MIN_HEIGHT, 
											POPUP_PRINTABLE_CHROME_TYPE);

} // EBookViewer.prototype.popupPrintableVersion


EBookViewer.prototype.closePopups = function () {

	// close all open popups
	for (popupWindowIndex in this.popupWindows) {
		if (this.popupWindows[popupWindowIndex] && !this.popupWindows[popupWindowIndex].closed) {
			this.popupWindows[popupWindowIndex].close();
		}
	}
	
} // EBookViewer.prototype.close


EBookViewer.prototype.close = function () {

	// close all open popups
	this.closePopups();
	
	// close main window
	if (window.opener && !window.opener.closed) {
		window.close();
	} else {
		window.location.href = 'index.html';
	}
	
} // EBookViewer.prototype.close


EBookViewer.prototype.setPageSize = function (pageSize) {

	this.pageSize = pageSize;
	sessionInfo.pageSize = pageSize;
	
} // EBookViewer.prototype.setPageSize


EBookViewer.prototype.getEBookGrade = function () {

	return this.currentPage.pageRange.pagePrefix.substring(2,3);
	
} // EBookViewer.prototype.gotoTOC




//     End of EBookViewer object
// - ==============================================


// + ==============================================
//     SessionInfo object
//       Properties:
//         URL : string
//         baseURL : string
//         pageCode : string
//         userState : string
//         userStateName : string
//
//       Class Methods:
//         getBaseURL() : string
//         getPageCodeFromURL(url : string) : string
// + ==============================================

function SessionInfo() {

	this.URL = window.location.href;
	this.queryParams = getQueryParams()
	this.baseURL = SessionInfo.getBaseURL(this.URL);
	this.pageCode = SessionInfo.getPageCodeFromURL(this.URL);
	if (this.queryParams['ps']) {
		this.pageSize = this.queryParams['ps']
	} else {
		this.pageSize = DEFAULT_PAGE_SIZE;
	}
	if (this.queryParams['s']) {
		this.userState = this.queryParams['s'];
	} else {
		this.userState = DEFAULT_STATE_ABBR;
	}

} // SessionInfo constructor


// CLASS METHOD
SessionInfo.getBaseURL = function(url) {

	// delete everything after and including ? of query string
	url = url.replace(/\?.+$/, "");

	// delete everything after last \ or /
	return url.replace(/(\\|\/)[\w\.\-]+$/, '');

} // SessionInfo_getBaseURL


// CLASS METHOD
SessionInfo.getPageCodeFromURL = function(url) {

	// start with pathname (URL without host, query, or hash
	var url = window.location.pathname;

	// get url file name without extension
	var re = /([\w\-]+)\.\w+$/;
	
	if (re.exec(url)) {
		return RegExp.$1;
	} else {
		return '';
	}

} // SessionInfo_getPageCodeFromURL


// CLASS METHOD
SessionInfo.getStateAbbrFromCookie = function() {
	var thisCookie = document.cookie.split("; ")
	for (i=0; i<thisCookie.length; i++) {
		if (COOKIE_EBOOK_STATE_ABBR == thisCookie[i].split("=")[0]) {
			return thisCookie[i].split("=")[1];
		}
	}
	
	return null;
	
} // SessionInfo_getStateAbbrFromCookie




//     End of EBookViewer object
// - ==============================================


//     End of eBook Objects
// - ###############################################################################


//
// core functions - non-eBook specific
//
//   getQueryParams() : Array
//
//   getGlobalText -- moved to functionality.js 2/28/04 TS


function getQueryParams() {
  
	var queryString = window.location.search.substring(1); 

	// Array to store parameters
	var queryParams = new Array();
 
 	// save full query string as parameter
 	queryParams['QUERY_STRING'] = queryString;
 	
	// multi-value separator
	multivalueSeparator = ', ';
	
	if (queryString.length < 1) { return queryParams; }

	var params = queryString.split('&');
	
	for (p in params) {
		var curParam = params[p];

		var paramParts = curParam.split('=');

		// if param missing 
		if (paramParts.length == 1) {
			paramParts[1] = '';
		}
		
		// unencode value
		paramParts[1] = paramParts[1].replace('+', ' ');
		paramParts[1] = unescape(paramParts[1]);
		
		if (queryParams[paramParts[0]]) {
			// parameter already exits, append additional value
			queryParams[paramParts[0]] += multivalueSeparator + paramParts[1];
		} else {
			// create new parameter in array
			queryParams[paramParts[0]] = paramParts[1];
		}
	}
	
	return queryParams;
  
} // getQueryParams


function popupWindow (URL, name, width, height, minWidth, minHeight, chromeType, relativeToOpener) {

	// default pop-up sizing
	if (! width) {width = 760};
	if (! height) {height = 540};

	// get browsers sizing from content + chrome
	browserWidth = width + POPUP_CHROME_WIDTH[chromeType];
	browserHeight = height + POPUP_CHROME_HEIGHT[chromeType];
	
	var clientGeometry = null;
	if (relativeToOpener) {
		clientGeometry = getClientGeometry();
	}


	// default pop-up location
	var left = SCREEN_MARGIN;
	var top = SCREEN_MARGIN;

	// if we have client geometry try to tile pop-up relative to opener, otherwise center it on screen
	if (clientGeometry) {

		// tile offest from opener
		left = clientGeometry.screenLeft + POPUP_LEFT_OFFSET;
		top = clientGeometry.screenTop + POPUP_TOP_OFFSET;
			
	} else {

		// center on screen 
				
		// reduce size of window if larger than screen
		if (browserWidth > screen.availWidth) { 
			width = screen.availWidth - 2*SCREEN_MARGIN - POPUP_CHROME_WIDTH[chromeType];
			browserWidth = width + POPUP_CHROME_WIDTH[chromeType];
		}
		if (browserHeight > screen.availHeight) {
			height = screen.availHeight - 2*SCREEN_MARGIN -  POPUP_CHROME_HEIGHT[chromeType];
			browserHeight = height + POPUP_CHROME_HEIGHT[chromeType];
		}

		// center window on screen, taking into account additional height for chrome
		left = Math.ceil((screen.availWidth/2) - (browserWidth/2));
		top = Math.ceil((screen.availHeight/2) - (browserHeight/2));

		// if requested location relative to opener, offset location from centered
		if (relativeToOpener) {
			left += POPUP_LEFT_OFFSET;
			top += POPUP_TOP_OFFSET;
		}
	}

	// make sure left,top and right,bottom are on screen, and that window at least minimum size	
	if (left < SCREEN_MARGIN) left = SCREEN_MARGIN;
	right = left + browserWidth;
	if (right > screen.availWidth - SCREEN_MARGIN) {
		if (relativeToOpener) { 
			left = left - POPUP_LEFT_OFFSET + POPUP_LEFT_OFFSET_MINIMUM;
			right = left + browserWidth;
			if (right > screen.availWidth - SCREEN_MARGIN) {
				width = screen.availWidth - left - POPUP_CHROME_WIDTH[chromeType] - SCREEN_MARGIN;
			}
		} else {
			width = screen.availWidth - left - POPUP_CHROME_WIDTH[chromeType] - SCREEN_MARGIN;
		}
	}
	if (width < minWidth) {
		width = minWidth;
		maxWidth = screen.availWidth - 2*SCREEN_MIN_MARGIN - POPUP_CHROME_WIDTH[chromeType];
		if (width > maxWidth) width = maxWidth;
		left = screen.availWidth - width - SCREEN_MARGIN - POPUP_CHROME_WIDTH[chromeType];
	}
	if (left < SCREEN_MARGIN) {
		left = SCREEN_MIN_MARGIN;
	}
	
	if (top < SCREEN_MARGIN) top = SCREEN_MARGIN;
	bottom = top + browserHeight;	
	if (bottom > screen.availHeight - SCREEN_MARGIN) {
		if (relativeToOpener) { 
			top = top - POPUP_TOP_OFFSET + POPUP_TOP_OFFSET_MINIMUM;
			bottom = top + browserHeight;
			if (bottom > screen.availHeight - SCREEN_MARGIN) {
				height = screen.availHeight - top - POPUP_CHROME_HEIGHT[chromeType] - SCREEN_MARGIN;
			}
		} else {
			height = screen.availHeight - top - POPUP_CHROME_HEIGHT[chromeType] - SCREEN_MARGIN;
		}
	}
	if (height < minHeight) { 
		height = minHeight;
		maxHeight = screen.availHeight - 2*SCREEN_MIN_MARGIN - POPUP_CHROME_HEIGHT[chromeType];
		if (height > maxHeight) height = maxHeight;
		top = screen.availHeight - height - SCREEN_MARGIN - POPUP_CHROME_HEIGHT[chromeType];
	}
	if (top < SCREEN_MARGIN) {
		top = SCREEN_MIN_MARGIN;
	}

	// create properties string
	var windowProperties = "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left;

	// popup chrome
	windowProperties += "," + POPUP_CHROME[chromeType];
	
	// popup the resource and save reference to it
 	return window.open(URL, name, windowProperties);
 	
} // popupWindow


function getClientGeometry() {

	var clientGeometry = new Object();
  
	if ( typeof( window.screenLeft ) == 'number' ) {
		clientGeometry.screenLeft = window.screenLeft;
		clientGeometry.screenTop = window.screenTop;
	} else if ( typeof( window.screenX ) == 'number' ) {
		clientGeometry.screenLeft = window.screenX;
		clientGeometry.screenTop = window.screenY;
	} else {
		return null;
	}

	return clientGeometry;
  
}  // getClientDimensions


//
//functions called from eBook main page
//

function GetTOCPageCode(pageRangesString, TOCFirstFolioStr) {

	var eBook = new EBook(pageRangesString, TOCFirstFolioStr);

	var TOCPageRange = eBook.getPageRangeFromFolio(eBook.TOCFirstFolio);
	var TOCPage = new Page(eBook.TOCFirstFolio, TOCPageRange);
	
	if (TOCPage) {
		return(TOCPage.toPageCode());
	} else {
		return 0;
	}

}


//
//functions called from eBook pages
//

function createEBook(pageRangesStrings, TOCFirstFolioStr) {
	
	sessionInfo = new SessionInfo();
	eBook = new EBook(pageRangesStrings[sessionInfo.userState], TOCFirstFolioStr);
	eBookViewer = new EBookViewer(eBook, sessionInfo);

} // createEBook


function JumpTOC() {
	eBookViewer.gotoTOC();
}

function JumpPage(folioStr) {
	
	return eBookViewer.gotoFolioStr(folioStr);

}


function ButtonJumpPage() {

	// prompt for page (folio)
    var folioStr  = prompt( getGlobalText("GT007"), "");
    if (	(folioStr == "") 
    	|| 	(folioStr == null)
    	||  (typeof(folioStr) == "undefined")
       )
	{
	
    	// do nothing

    } else {
    
		// goto page (folio)
    	var status = JumpPage(folioStr);
    	if (status != 1) {
			alert( getGlobalText("GT006") );
		}
	
	}

} // ButtonJumpPage


// 2/23/04 DC - added disabled button handling for prev/next

function PrevPage() {

	var success = 0; 
	if (document["previous"].src.indexOf("-disabled") < 0) {
		success = eBookViewer.gotoNextOrPrevPage(DIRECTION_PREV);
	}
	
	if (!success) {
		alert( getGlobalText("GT013") );
	}

} // PrevPage


function NextPage() {

	var success = 0; 
	if (document["next"].src.indexOf("-disabled") < 0) {
		success = eBookViewer.gotoNextOrPrevPage(DIRECTION_NEXT);
	}
	
	if (!success) {
		alert( getGlobalText("GT014") );
	}
	
} // NextPage


function BothPages(leftImageType, rightImageType) {
	eBookViewer.popupBothPages(leftImageType, rightImageType);
}

// 2/18/04 TS - Edited this to add back the disabled issue

function PrintPage() {

	if (document["printable2"].src.indexOf("-disabled") < 0) {
		eBookViewer.popupPrintableVersion();
	} else {
		alert( getGlobalText("GT009") );
	}

} // PrintPage


function HomeworkPage(hwcode) {

	if (document["homework"].src.indexOf("-disabled") < 0) {
		eBookViewer.popupHomework(hwcode);
	} else {
		alert( getGlobalText("GT010") );
	}
}

function EPLink(pageSpecificLink) {

	if (document["eduplace"].src.indexOf("-disabled") < 0) {
		eBookViewer.popupEPLink(pageSpecificLink);
	} else {
		alert( getGlobalText("GT012") );
	}
	
} // EPLink


helpPopupWindow = null;
function Help() {

	var HelpURL = '';
	if (eBookViewer.getEBookGrade() == 'K') {
		HelpURL = '../resources/help_k.html';
	} else {
		HelpURL = '../resources/help.html';
	}
	helpPopupWindow = popupWindow(HelpURL, POPUP_HELP_NAME, POPUP_HELP_WIDTH, POPUP_HELP_HEIGHT, POPUP_HELP_CHROME_TYPE, POPUP_LOCATION_OPENER);

} // Help


function CloseHelp() {
	if (helpPopupWindow && !helpPopupWindow.closed) {
		helpPopupWindow.close();
	}
}

function ClosePopups() {

	// close all open popups
    eBookViewer.closePopups();

} // ClosePopups

function CloseBook() {

	eBookViewer.close();

} // CloseBook

function SetPageSize(pageSize) {
	eBookViewer.setPageSize(pageSize);
}

function GetPageSize() {
	return eBookViewer.pageSize;
}

function RedisplaySmallerPage() {
	if (document["smaller2"].src.indexOf("-disabled") < 0) { 
		size--;
		eBookViewer.redisplayPage();
	} else {
		alert (getGlobalText("GT022"));
	}
}

function RedisplayLargerPage() {
	if (document["larger2"].src.indexOf("-disabled") < 0) { 
		size++;
		eBookViewer.redisplayPage();
	} else {
		alert (getGlobalText("GT021"));
	}
}



// NAV_FUNCTIONALITY SCRIPT ENDS HERE

