//populate JSON book object
var tocJson = {
isbn: "9780062083029",
startPg: 0,
pages:
[
{ pGrp: "Outside Front Cover", pNum: 1, pLoc: "97800620830291", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Inside Front Cover", pNum: 2, pLoc: "195601241660584", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Author's Note", pNum: 3, pLoc: "293401862490879", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Dedication", pNum: 4, pLoc: "391202483321176", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Title Page", pNum: 5, pLoc: "489003104151475", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Chapter 1", pNum: 7, pLoc: "684604345812079", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "", pNum: 8, pLoc: "782404966642384", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "", pNum: 9, pLoc: "880205587472691", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "", pNum: 10, pLoc: "9780062083029100", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "", pNum: 11, pLoc: "10758068291332021", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "", pNum: 12, pLoc: "11736074499634944", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Inside Back Cover", pNum: 35, pLoc: "34230217290602725", imgW: 501, imgH: 750, isLoaded: false },
{ pGrp: "Outside Back Cover", pNum: 36, pLoc: "35208223498905696", imgW: 501, imgH: 750, isLoaded: false }
]
};
var oBook = eval(tocJson);
// get DOM references to buttons
var btnFitToWindow = document.getElementById("btnFitToWindow");
//var btnZoomOut = document.getElementById("btnZoomOut");
//var btnZoomIn = document.getElementById("btnZoomIn");
var btnMoveHand = document.getElementById("btnMoveHand");
var btnSkipFirst = document.getElementById("btnSkipFirst");
var btnSkipLast = document.getElementById("btnSkipLast");
var btnNext = document.getElementById("btnNext");
var btnPrev = document.getElementById("btnPrev");
var navButtons = document.getElementById("navButtons");
var arrButtons = navButtons.getElementsByTagName("img");
var btnWidget = document.getElementById("btnWidget");
var btnEmail = document.getElementById("btnEmail");
var btnFeedback = document.getElementById("btnFeedback");
var headButtons = document.getElementById("headButtons");
var arrHeadButtons = headButtons.getElementsByTagName("img");
var pageNumber = document.getElementById("pageNumber");
//get DOM references to TOC elements
var toc = document.getElementById("toc");
var btnToc = document.getElementById("btnToc");
var tocStage = document.getElementById("tocStage");
var upArrow = document.getElementById("tocUp");
var downArrow = document.getElementById("tocDown");
var tocPanel = document.getElementById("tocPanel");
var arrTocRows = tocPanel.getElementsByTagName("div");
// get DOM references for Stage
var biHeader = document.getElementById("biHeader");
var sidebar = document.getElementById("sidebar");
var toolbar = document.getElementById("toolbar");
var biLoading = document.getElementById("biLoading");
//set cursor style
if (is_ie) {
biStage.style.cursor = "url(/images/grab.cur)";
} else if (is_fx) {
if (is_major >= 2) { biStage.style.cursor = "-moz-grab"; } else { biStage.style.cursor = "move"; }
} else {
biStage.style.cursor = "move";
}
//XML HTTP REQUEST
function BiPageRequest(pgOrder, curZoom) {
this.pgOrder = pgOrder;
if (oBook.pages[this.pgOrder].pLoc.indexOf("getError") > -1) {
this.pageURL = oBook.pages[this.pgOrder].pLoc + "&reqtype=0";
} else {
this.pageURL = "/Services/GetPage.aspx?isbn13=" + oBook.isbn + "&pageguid=" + oBook.pages[this.pgOrder].pLoc + "&reqtype=0";
}
this.isSearchImg = false;
this.curZoom = curZoom;
this.req = null;
this.hasLoaded = false;
if ((typeof(results) !== "undefined") && (results)) {
for (i=0; i < results.pages.length; i++) {
if (results.pages[i].sequence === oBook.pages[this.pgOrder].pNum) {
this.pageURL = "/Services/GetSearchPage.aspx?isbn13=" + oBook.isbn + "&keyword=" + keyword + "&pageGuid=" + results.pages[i].pageGuid;
this.isSearchImg = true;
}
}
}
}
BiPageRequest.prototype.getPageImage = function() {
var loader;
this.req = getXMLHTTPRequest();
if (this.req) {
addRequest();
loader = this;
this.req.onreadystatechange = function() {
loader.onReadyState.call(loader);
};
this.req.open("GET", this.pageURL, true);
this.req.send(null);
}
};
BiPageRequest.prototype.onReadyState = function() {
var req = this.req;
var oPageResult;
if (req.readyState === 4) {
if (req.status === 200) {
if (!this.isSearchImg) {
oPageResult = eval("(" + req.responseText + ")");
arrBookPages[this.pgOrder].innerHTML = "";
} else {
arrBookPages[this.pgOrder].innerHTML = "
";
arrSearchedPages.push(this.pgOrder);
}
oBook.pages[this.pgOrder].isLoaded = true;
this.hasLoaded = true;
} else {
alert("There was a problem with the web server. Please try again later.");
biLoading.style.visibility = "hidden";
}
} else {
window.status = "Loading";
}
};
//create global requests array to control the number of http request objects
var arrPageRequests = [];
var totalRequests = 0;
function addRequest() { totalRequests++; checkLoadingRequests(); }
function removeRequest() { totalRequests--; checkLoadingRequests(); }
function checkLoadingRequests() {
if (totalRequests > 0) { biLoading.style.visibility = "visible"; } else { biLoading.style.visibility = "hidden"; }
}
function pageError(theImage) {
removeRequest();
theImage.width = "496";
theImage.height = "750";
theImage.src = "/images/bi_noimage.gif";
}
//FOR SEARCH / IMAGE HIGHLIGHTING
var arrSearchedPages = [];
function resetSearchedPages(){
//loop through all pages of the book
for (i=0; i < oBook.pages.length; i++) {
//check to see if the page was loaded already
if (oBook.pages[i].isLoaded) {
//it has been loaded already, so now loop through the results object
for (z=0; z < results.pages.length; z++) {
//and look to see if this particular page is viewable
//and the results page sequence matches with this book page
if ((results.pages[z].viewable) && (results.pages[z].sequence === oBook.pages[i].pNum)) {
//if it does match, it means this page should be reloaded when it is in view
//so reset its loaded flag to false
oBook.pages[i].isLoaded = false;
}
}
}
}
//now wipe clean any previous searched pages
for (i=0; i < arrSearchedPages.length; i++) {
oBook.pages[parseInt(arrSearchedPages[i],0)].isLoaded = false;
//clear the current page if it was a highlighted in a previous search
if (arrSearchedPages[i] === curPage) {
arrPageRequests[curPage] = new BiPageRequest(curPage, curZoomPerc);
arrPageRequests[curPage].getPageImage();
}
}
//loop through the new results object
for (z=0; z < results.pages.length; z++) {
//if the results page is viewable and its sequence matches that of the current page
if ((results.pages[z].viewable) && (results.pages[z].sequence === oBook.pages[curPage].pNum)) {
//then reload the current page
arrPageRequests[curPage] = new BiPageRequest(curPage, curZoomPerc);
arrPageRequests[curPage].getPageImage();
}
}
//clear out the requests and search queues
arrPageRequests.length = 0;
arrSearchedPages.length = 0;
}
//START VIEWPORT
//global event handlers
window.onresize = windowResize;
document.onmousemove = windowMouseMove;
//disable right-click
biStage.oncontextmenu = rightClick;
function rightClick(ev) { return false; }
//prevent text selection
document.getElementsByTagName("body")[0].setAttribute("unselectable", "on");
document.getElementsByTagName("body")[0].onselectstart = preventSelection;
function preventSelection(ev) {
var targ;
ev = ev || window.event;
if (ev.target) { targ = ev.target; }
else if (ev.srcElement) { targ = ev.srcElement; }
if (targ.nodeType === 3) { // defeat Safari bug
targ = targ.parentNode;
}
//HACK: txtSiteSearchId is defined as a js variable in the navbar control
// the global search box is a server txtbox control with a server id - this was only way to get the id
if ( ((typeof(txtSiteSearchId) !== "undefined") && (targ.id === txtSiteSearchId)) || (targ.id === "txtEmail") || (targ.id === "txtSearch") ) {
return true;
} else {
return false;
}
}
//handle keypress
function disableCtrlKeyCombination(e) {
var forbiddenKeys = ["a", "c", "x"];
var key, isCtrl;
if(window.event) {
key = window.event.keyCode; //IE
if(window.event.ctrlKey) { isCtrl = true; } else { isCtrl = false; }
} else {
key = e.which; //firefox
if(e.ctrlKey) { isCtrl = true; } else { isCtrl = false; }
}
//if ctrl is pressed check if other key is in forbidenKeys array
if(isCtrl) {
for(i=0; i < forbiddenKeys.length; i++) {
if(forbiddenKeys[i].toLowerCase() === String.fromCharCode(key).toLowerCase()) { return false; }
}
}
return true;
}
document.onkeydown = disableCtrlKeyCombination;
document.onkeypress = disableCtrlKeyCombination;
//set up global variables
var isMouseDown = false;
var startY = null;
var startX = null;
var globalXPos = null;
var globalYPos = null;
var stageTop = findPos(biStage)[1];
var stageLeft = findPos(biStage)[0];
var sidebarWidth = 298; //hardcode this because in ff width value changes with scrollbar, even though visible area does not
var toolBarHeight = 34;
//var stageWidth = document.getElementsByTagName("body")[0].clientWidth - sidebarWidth;
var stageWidth=bodyWidthValue(6);
var stageHeight = document.getElementsByTagName("body")[0].clientHeight - stageTop;
//set width and height of viewport to fix 100% height misinterpretation issue in Firefox
biStage.style.width = stageWidth + "px";
biStage.style.height = stageHeight + "px";
//ie is using 100% height for sidebar, but set it for all other browsers
if (!is_ie) {
sidebarHeight = document.getElementsByTagName("body")[0].clientHeight - stageTop + toolBarHeight;
sidebar.style.height = sidebarHeight + "px";
}
// global zoom variables
var curZoomLevel = 4;
var arrZoomInc = [0.6, 0.7, 0.8, 0.9, 1, 1.1];
var curZoomPerc = arrZoomInc[curZoomLevel];
//set position of toc button
if ( (findPos(fitToWindow)[0]-220) > stageLeft ) {
toc.style.left = (findPos(fitToWindow)[0]-205) + "px";
} else {
//if it is trying to appear before start of stageLeft, catch it
toc.style.left = stageLeft + "px";
}
//set position of navigation buttons
if ((findPos(fitToWindow)[0]-390) > (stageLeft)) {
//navButtons.style.left = (findPos(fitToWindow)[0]-390) + "px";
navButtons.style.left = ((findPos(fitToWindow)[0])/2)+298-182 + "px";
} else {
navButtons.style.left = stageLeft;
}
//for firefox scrollwheel support
if ( (window.addEventListener) && (is_fx) ) {
window.addEventListener("DOMMouseScroll", windowMouseWheel, false);
}
//get the body width including sidebarWidth
function body_width()
{
var body_width;
if ($.browser.msie)
{
body_width=$("#main_container").width();
return body_width;
}else{
body_width=$("#main_container").width();
return body_width;
}
}
var body_width;
function bodyWidthValue(siteIDValueFromIndexASPX){
var rightSectionWidth;
if(siteIDValueFromIndexASPX==13 || siteIDValueFromIndexASPX==14 || siteIDValueFromIndexASPX==1 || siteIDValueFromIndexASPX==9)
{
rightSectionWidth=document.getElementsByTagName("body")[0].clientWidth - sidebarWidth;
return rightSectionWidth;
}
else{ //siteID's other than 13,14,1,9
if (!is_ie){body_width=1003;}else{body_width=983;}
if(document.getElementsByTagName("body")[0].clientWidth < body_width)
{
rightSectionWidth=document.getElementsByTagName("body")[0].clientWidth - sidebarWidth;
return rightSectionWidth;
}else{
rightSectionWidth = body_width - sidebarWidth;
return rightSectionWidth;
}//close of if condition
}//close of if..else condition
}
function windowResize(ev){
//recalculate stage width/height
stageTop = findPos(biStage)[1];
//Below code is for unknown body with resolution - if you want this you can uncomment this one
//stageWidth = document.getElementsByTagName("body")[0].clientWidth - sidebarWidth;
stageWidth = bodyWidthValue(6);
stageHeight = document.getElementsByTagName("body")[0].clientHeight - stageTop;
if (stageWidth >= 0) {
biStage.style.width = stageWidth + "px";
}
if (stageHeight >= 0) {
biStage.style.height = stageHeight + "px";
}
//ie is using 100% height for sidebar, but set it for all other browsers
if (!is_ie) {
sidebarHeight = document.getElementsByTagName("body")[0].clientHeight - stageTop + toolBarHeight;
sidebar.style.height = sidebarHeight + "px";
}
//set position of toc button
if ( (findPos(fitToWindow)[0]-220) > stageLeft ) {
toc.style.left = (findPos(fitToWindow)[0]-205) + "px";
} else {
//if it is trying to appear before start of stageLeft, catch it
toc.style.left = stageLeft + "px";
}
//set position of navigation buttons
if ( (findPos(fitToWindow)[0]-390) > (stageLeft) ) {
navButtons.style.left = (findPos(fitToWindow)[0]-390) + "px";
} else {
navButtons.style.left = stageLeft;
}
//if fit to window is depressed, release it on resize
if (isFitToWindowSelected) {
isFitToWindowSelected = false;
btnFitToWindow.src = "/images/btnFitToWindow.gif";
btnFitToWindow.style.cursor = "pointer";
}
// jQuery snippet to remove inline styles and apply custom styles
var siteIDFromIndex=6;
if(siteIDFromIndex==2 || siteIDFromIndex==5 || siteIDFromIndex==6)
{
if ($.browser.msie) {
$("#toc").removeAttr("style").attr("style", "float:left;margin-left:40px;position:absolute;");
$("#main_container").attr("style", "margin:0 auto; width:983px; text-align: left;");
} else {
$("#toc").removeAttr("style").attr("style", "float:left;margin-left:440px;position:absolute;");
$("#main_container").attr("style", "margin:0 auto; width:1003px; text-align: left;");
}
$("#navButtons").removeAttr("style").attr("style", "float:left;position:static");
$("#fitToWindow").removeAttr("style");
}else{
/* var toolbarfullwidth_in_js;
var rightColumnWidth=$(window).width() - 298;
if(rightColumnWidth>450){toolbarfullwidth_in_js=rightColumnWidth;}else{toolbarfullwidth_in_js=800;}
if ($.browser.msie) {
$("#toc").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + (toolbarfullwidth - 508) + "px;");
$("#navButtons").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + ((toolbarfullwidth / 2) - 339) + "px;");
$("#fitToWindow").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + (toolbarfullwidth - 298) + "px;");
}else{
$("#toc").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + (toolbarfullwidth_in_js-250) + "px;");
$("#navButtons").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + ((toolbarfullwidth_in_js/2)-100) + "px;");
$("#fitToWindow").removeAttr("style").attr("style", "float:left;position:absolute;margin-left:" + (toolbarfullwidth_in_js-40) + "px;")
}*/
}
//$("#ctl00_ContentPlaceHolder1_biStage").css({ width: '100%' });
// End of jQuery snippet
}
function windowMouseMove(ev) {
ev = ev || window.event;
globalXPos = ev.clientX;
globalYPos = ev.clientY;
}
function windowMouseWheel(ev) {
var delta = 0;
ev = ev || window.event;
if (ev.wheelDelta) { //ie/opera
delta = ev.wheelDelta/120;
if (window.opera) { delta = -delta; } //opera
} else if (ev.detail) { //mozilla
delta = -ev.detail/3;
}
//handles Firefox auto scrollwheel when moused over biStage
if ( (delta) && (globalYPos >= stageTop) && (globalXPos >= stageLeft) ) {
biStage.scrollTop = biStage.scrollTop - (delta*100);
biScroll();
}
//handles Firefox auto scrollwheel when moused over left sidebar
if ( (delta) && (globalYPos >= stageTop) && (globalXPos < stageLeft) ) {
sidebar.scrollTop = sidebar.scrollTop - (delta*100);
}
if (ev.preventDefault) {
ev.preventDefault();
}
ev.returnValue = false;
}
var arrBookPages = biStage.getElementsByTagName("div");
var arrBookImages = biStage.getElementsByTagName("img");
//build array of scroll heights
var arrPageHeight = [oBook.pages.length];
arrPageHeight[0] = 0;
for (i=0; i < oBook.pages.length; i++) {
if (i===0) {
arrPageHeight[i+1] = oBook.pages[i].imgH + 30;
} else {
arrPageHeight[i+1] = oBook.pages[i].imgH + 30 + arrPageHeight[i];
}
}
// global pagination variables
var curPage = 0;
var startPage = 0;
var endPage = arrBookImages.length-1;
//Browse Inside specific event handlers
biStage.onmousedown = biMouseDown;
biStage.onmouseup = biMouseUp;
biStage.onmousemove = biMouseMove;
biStage.onscroll = biScroll;
function biMouseDown(ev){
isMouseDown = true;
ev = ev || window.event;
startY = ev.clientY;
startX = ev.clientX;
//prevent not being able to click biStage into focus in IE
if (is_ie) { this.focus(); }
//prevent text selection Firefox
if (typeof ev.preventDefault !== "undefined") { ev.preventDefault(); }
}
function biMouseMove(ev){
ev = ev || window.event;
if ((isMouseDown) && (startY < stageTop + stageHeight) && (startY >= stageTop) && (startX < stageLeft + stageWidth-17)) {
biStage.scrollTop += startY - ev.clientY;
biStage.scrollLeft += startX - ev.clientX;
startY = ev.clientY;
startX = ev.clientX;
//firefox does not trigger scroll event so call it explicitly
if (is_fx) { biScroll(); }
}
}
function biMouseUp(ev) {
isMouseDown = false;
}
function biScroll(ev) {
checkLoadingRequests();
//if current page is not last page of book,
//and scroll is greater than or equal to start of next page,
//and the next page has not been loaded yet,
//load in next image
if ( (curPage < endPage) && (biStage.scrollTop >= (arrPageHeight[curPage+1]-stageHeight)) && (!oBook.pages[curPage+1].isLoaded) && (!arrPageRequests[curPage+1]) ) {
arrPageRequests[curPage+1] = new BiPageRequest(curPage+1, curZoomPerc);
arrPageRequests[curPage+1].getPageImage();
}
//if current page is not start of book,
//and scroll is less than end of previous page
//and previous page has not been loaded yet
//load in prevous image
if ( (curPage > 0) && (biStage.scrollTop < (arrPageHeight[curPage]-30)) && (!oBook.pages[curPage-1].isLoaded) && (!arrPageRequests[curPage-1]) ) {
arrPageRequests[curPage-1] = new BiPageRequest(curPage-1, curZoomPerc);
arrPageRequests[curPage-1].getPageImage();
}
//add to page number at next 50% mark
if ( (curPage < endPage) && (biStage.scrollTop >= (arrPageHeight[curPage]+(stageHeight*0.50))) ) {
curPage++;
//page numbering commented out for launch because data is out of synch
//pageNumber.innerHTML = "Page " + oBook.pages[curPage].pNum;
}
//subtract from page number if scroll is above current 50%
if ((curPage > 0) && (biStage.scrollTop < (arrPageHeight[curPage]-(stageHeight*0.50))) ) {
curPage--;
//page numbering commented out for launch because data is out of synch
//pageNumber.innerHTML = "Page " + oBook.pages[curPage].pNum;
}
if ((curPage === 0) && (prevButtonsEnabled)) { disablePrevButtons(); }
if ((curPage > 0) && (!prevButtonsEnabled)) { enablePrevButtons(); }
if ((curPage === endPage) && (nextButtonsEnabled)) { disableNextButtons(); }
if ((curPage < endPage) && (!nextButtonsEnabled)) { enableNextButtons(); }
}
function initScroll(){
if ( (biStage.scrollTop >= (arrPageHeight[curPage]-stageHeight)) && (!oBook.pages[curPage].isLoaded) && (!arrPageRequests[curPage]) ) {
arrPageRequests[curPage] = new BiPageRequest(curPage, curZoomPerc);
arrPageRequests[curPage].getPageImage();
}
//page numbering commented out for launch because data is out of synch
//pageNumber.innerHTML = "Page " + oBook.pages[curPage].pNum;
}
function findPos(obj) {
var curleft = 0; curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
}
return [curleft,curtop];
}
// START TOC
//create rows in table of contents
for (y=0; y < oBook.pages.length; y++) {
if (oBook.pages[y].pGrp !== "") {
tocPanel.innerHTML += "