//Smooth scroll for MD Consult: If scrollFullPage is true; the entire (document.body) should scroll
var scrollFullPageInBook;

///////////////////////////////////////////////////////
// Update the "content area" (right hand side) of the 
// book player with the book chapter/section indicated
// by the specified eid.
//

function initContentHistory() {

	// figure out the book content "state" string as used by the history manager:
	// Try it from the hash (the "bookmarked state"):
	var initialState = YAHOO.util.History.getBookmarkedState( "content" );

	if(!initialState) {

		// For reasons unclear to me (dcc) - the YUI History Manager is *not* reading
		// the bookmarked state properly from the hash!!  Try to workaround it here:
		initialState = getParam(window.location.hash, "content");			
		if(!initialState) {		
			// Otherwise try it from the query string:
			initialState = YAHOO.util.History.getQueryStringParameter( "eid" );
			if(initialState) {	
				// And this content could optionally have the hitTerms highlighted:
				var hitTerms = YAHOO.util.History.getQueryStringParameter( "hitTerms" );
				var type = YAHOO.util.History.getQueryStringParameter( "type" );
				var sectionEid = YAHOO.util.History.getQueryStringParameter( "sectionEid" );
				var figureEid = YAHOO.util.History.getQueryStringParameter( "figureEid" );
				var dartId = YAHOO.util.History.getQueryStringParameter( "dartId" );								
				var isbn = YAHOO.util.History.getQueryStringParameter( "isbn" );
				var displayedEid = YAHOO.util.History.getQueryStringParameter( "displayedEid" );
				if(hitTerms) {				
					// Within the state string we use ; instead of &:
					initialState = initialState + ';hitTerms=' + hitTerms;
				}
				if(type) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';type=' + type;
				}
				if(sectionEid) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';sectionEid=' + sectionEid;
				}
				if(figureEid) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';figureEid=' + figureEid;
				}	
				if(dartId) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';dartId=' + dartId;
				}					
				if(isbn) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';isbn=' + isbn;
				}	
				if(displayedEid) {
					// Within the state string we use ; instead of &:
					initialState = initialState + ';displayedEid=' + displayedEid;
				}		
			}
		}	
	}
	
	// Register our "content" module. Module registration MUST take
	// place before calling YAHOO.util.History.initialize.
	YAHOO.util.History.register( "content", initialState, 
		function( contentState ) {
			// This is called after calling YAHOO.util.History.navigate, or after the user
			// has trigerred the back/forward button. We cannot discrminate between
			// these two situations.			
			updateContentArea("bookContentPane", contentState); 					
		}
	);

	// Subscribe to this event before calling YAHOO.util.History.initialize,
	// or it may never get fired! Note that this is guaranteed to be fired
	// after the window's onload event.  Note this may occur e.g. when coming
	// from the book list, or because they've returned to this page using
	// the back button...	
	YAHOO.util.History.onLoadEvent.subscribe( 
		function() {
			// The bug under IE referred to above appears to be occurring - 
			// have tried to workaround it largely by having the server
			// deliver the content (at least when coming off the book list
			// or via a bookmarked url).			
			activateContentArea();			
		} 
	);
}

// Handle when the user clicks on e.g. the next or prev link.
function contentAnchorSelected(evt)
{			
	// 'this' should be the actual anchor tag DOM element...							
	if(this.eid) {	

		var newContentState = this.eid;
		
		if(this.hitTerms && this.hitTerms != "") {
			newContentState = newContentState + ';hitTerms='+this.hitTerms;
		}
		
		if(this.anchorType && this.anchorType != "") {
			newContentState = newContentState + ';from='+this.anchorType;
		}
		
		if(this.hitNum && this.hitNum != "") {
			newContentState = newContentState + ';hitNum='+this.hitNum;
		}	
		
		if(this.isbn && this.isbn != "") {
			newContentState = newContentState + ';isbn='+this.isbn;
		}				
		
		// add this anchorTag property for new landing page Dart links - RJM 8/20/08
		if(this.dartId && this.dartId != "") {
			newContentState = newContentState + ';dartId='+this.dartId;
		}				
		

		if(this.type && this.type != "") {
			newContentState = newContentState + ';type='+this.type;
			if(this.type == "figurePage" || this.type == "figureFromContent") {				
				// For Full Size Image Building blocks wont return breadcrumbs to load and highlight the Toc. 
				// So we need to use the previous thumnail image breadcrumbs lower level eid (sectionEid) to highlight the Toc.
				// Note: We should not use the previous thumbnail image requested eid in the buildingblocks as sectionEid. That requested eid may not be in the Toc to gets loaded.
				var contentAreaElement = dojo.byId("bookContentPane");
				var sectionEid =  contentAreaElement.getAttribute('sectionEid');
				if(!sectionEid) sectionEid = contentAreaElement.sectionEid;	
				if(sectionEid)
				newContentState = newContentState + ';sectionEid='+sectionEid;	
			}				
		}
						
		// What was the last content eid?
		var currentContentState = YAHOO.util.History.getCurrentState( "content" );		

		// If the eid has changed
		if(newContentState != currentContentState) { 
			// Navigate to the new state in a back button friendly way:
			try {
				YAHOO.util.History.navigate( "content", newContentState );
			} catch ( e ) {
				// If the Browser History Manager was not successfuly initialized,
				// the following call to YAHOO.util.History.navigate will throw an
				// exception. We need to catch it and update the UI. The only
				// problem is that this new state will not be added to the browser
				// history.							
				updateContentArea("bookContentPane", newContentState); 		
			}
		}
		else {	
			// If the state hasn't changed, the Yahoo History Manager
			// thinks there's nothing to do, but it could be they've
			// scrolled within the current page and would like to scroll
			// back to where they've last (smooth) scrolled to:			
			updateContentArea("bookContentPane", newContentState); 			
		}

	}
		
	// Don't follow the link we're updating via Ajax.
	return false; 		
}

// Handle when the user clicks on a link that jumps within the current page
function jumpAnchorSelected()
{								
	// 'this' should be the actual anchor tag DOM element...								
	if(this.jumpTo) {
	
		// The app can define a javascript variable "webAnalyticsTracker" to call a method
		// for tracking the content changes - e.g. we have one called "trackGoogleAnalytics"
		// in bookUtils.js:
		var trackWebAnalytics;
		if((typeof(webAnalyticsTracker) != 'undefined') && webAnalyticsTracker) {
			trackWebAnalytics = webAnalyticsTracker;
		}
																
		// Find the anchor to jump to:
		var namedAnchor = findNamedAnchor(this.jumpTo, "bookContentPane");
		if(namedAnchor) {	
			// We're using a elsBookPlayerState here for it's scrolling ability only
			// (some refactoring may be in order :)
			// Note:  "undefined" for html indicates to use the current page's html.															
			var theBookPlayerState = new elsBookPlayerState(undefined,
												undefined,
												undefined,
												"main", 
												"bookContentPane",
												"PrevBtnT",
												"NextBtnT",		
												getTocTree(),
												scrollFullPageInBook,	
												undefined,	
												updateContentTools,												
												function(bookPlayerState) {	
														rememberCurrentBookPlayerUrl();
												},													
												// onUpdateComplete:
												undefined,
												// trackWebAnalytics
												trackWebAnalytics);	
																																						
			theBookPlayerState.scrollToNamedAnchor(namedAnchor);
		}		
			
		// Don't follow the link we've simply scrolled the page.
		return false; 				
	}
}

//
// Hide or show the search hits, "action" is a keyword and can be one of:
// 	"toggle" - flip the current state from shown to hidden or vice versa.
// 	"show"   - show the highlights
// 	"hide"   - hide the highlights
//   
// Regardless of the "action", in addition to hiding/showing the search 
// hits, the button in the book player control panel *for* hiding/showing
// the hits will be hidden if there are no hits, and shown if there are 
// any hits.
//
function hideShowSearchHits(beneathElemId, action) {

	// Find the element to convert beneath:
	var beneathElem = dojo.byId(beneathElemId);
	if(!beneathElem) {
		return;
	}
	
	// Did we find any search hilights at all?
	// (don't have the show/hide button if not)
	var atLeastOneHit = false;
	
	// Find all the anchor tags beneath it:	
	var aTags = beneathElem.getElementsByTagName('a');
	if(!aTags) {
		return;
	}
	
	// For each anchor that's a search hit arrow:
	var theLastRightArrow;
	for(var no=0;no<aTags.length;no++) {	
			
		var id = aTags[no].getAttribute('id');		
		if(!id) href = aTags[no].id;
			
		if(id) {
			// Is this a jump to the next highlighted hit term link?
			if(id.indexOf("hitTermLeft") != -1 || id.indexOf("hitTermRight") != -1) {
				if(action == "hide" || 
					(action == "toggle" && aTags[no].style.display != "none")
				) {			
					aTags[no].style.display = "none";
				}
				else {
					aTags[no].style.display = "inline";				
				}
				atLeastOneHit = true;
				
				if(id.indexOf("hitTermRight") != -1) {
					// Keep track of the last right arrow we find:
					theLastRightArrow = aTags[no];
				}				
			}
		}							
	}
	
	// The BB highlighter erroneous adds a right arrow on the last hit:
	if(theLastRightArrow) {
		// So hide it!
		theLastRightArrow.style.display = "none";
	}
	
	// Find all the spans beneath it:	
	var spans = beneathElem.getElementsByTagName('span');
	if(!spans) {
		return;
	}
	
	// For each span that's a search hit highlight:
	for(var no=0;no<spans.length;no++) {	
						
		if(spans[no].className && 
			(spans[no].className == "hitTermHilite" || spans[no].className == "hitTermNoHilite")
		) {
			atLeastOneHit = true;
						
			// Flip it:
			if(action == "hide" || 
				(action == "toggle" && spans[no].className == "hitTermHilite")
			) {
				spans[no].className = "hitTermNoHilite";
			}
			else {
				spans[no].className = "hitTermHilite";			
			}
		}							
	}	
	
	// Don't have the show/hide book if no search hits!
	var showHideButton = dojo.byId("hideShowHitsButton");
	if(showHideButton) {
		if(atLeastOneHit) {
		
			var showIcon = dojo.byId("showHitsIcon");
			var hideIcon = dojo.byId("hideHitsIcon");
			// Show the appropriate icon:								
			if(action == "hide") {
				showIcon.style.display='block';
				hideIcon.style.display='none';						
			} else if(action == "show") {
				showIcon.style.display='none';
				hideIcon.style.display='block';						
			} else {
				// Flip the icon's visibilities:
				var showState = showIcon.style.display;
				var hideState = hideIcon.style.display;				
				showIcon.style.display=hideState;
				hideIcon.style.display=showState;
			}
	
			// And show the anchor tag surrounding the icons:
			showHideButton.style.display='block';					 
		}
		else {
			// Don't show this icon at all if no search hits:
			showHideButton.style.display='none';		
		}		
	}
}

// Convert all anchor tags beneath the specified element to use Ajax
function cvtAnchorsToUseAjax(beneathElemId, anchorType) {
	
	// Find the element to convert beneath:
	var beneathElem = dojo.byId(beneathElemId);
	if(!beneathElem) {
		return;
	}
	
	// Find all anchor tags beneath it:	
	var aTags = beneathElem.getElementsByTagName('a');
	
	// For each anchor:
	for(var no=0;no<aTags.length;no++) {	
		cvtAnchorToUseAjax(aTags[no], anchorType);					
	}		
}

// Convert the given anchor tag to use Ajax
function cvtAnchorToUseAjax(anchorTag, anchorType) {

	if(!anchorTag) {
		return;
	}

	var href = anchorTag.getAttribute('href');		
	if(!href) href = anchorTag.href;
		
	if(href) {
	
		// A hyperlink can stop us from treating it as ajax by adding "ajax=false":
		if(href.indexOf("ajax=false") != -1) {
		   return;
		}

		// Is this a "book.do"/"book.dx" url?
		if(href.indexOf("book.d") != -1) {

			// And is the method "getContent"
			var method = getQueryParam(href, "method");
			if(method == "getContent" || method == "display") {
				anchorTag.onclick = contentAnchorSelected;	
				
				anchorTag.eid = getQueryParam(href, "eid");
				anchorTag.hitTerms = getQueryParam(href, "hitTerms");
				anchorTag.hitNum = getQueryParam(href, "hitNum");
				if(anchorType) {
					anchorTag.anchorType = anchorType;
				}
	
				// Change the href to ensure that it's *never* followed
				// (otherwise it's terribly confusing when a javascript 
				// error occurs and it gets followed!)
				//anchorTag.href = "#";									
				
				// add this anchorTag property for new landing page Dart links - RJM 8/20/08
				anchorTag.dartId = getQueryParam(href, "dartId");
			}
		}
		
		//Is this a "linkTo" url?
		if(href.indexOf("linkTo") != -1) {	
			// And is the type should not be null
			var type = getQueryParam(href, "type");			
			if(type) {
			
				// If it's a journal article link
				if(type == "journalArticle" && 
					// And the app has defined and onClick handler and
					// given it a value:
					(typeof(onClickOfJournalArticle) != 'undefined')
						 && onClickOfJournalArticle) {
					
					// Call the app specific handler when they click it:
					anchorTag.onclick = onClickOfJournalArticle;
					
					// The following two params are currently all we have for
					// the journal articles - this will likely be expanded in
					// the future to support point at MDC journals, etc.
					anchorTag.journalArticleTitle = getQueryParam(href, "title");
					anchorTag.journalArticleAuthor = getQueryParam(href, "author");															
					anchorTag.journalArticleShortTitle = getQueryParam(href, "shortTitle");
					anchorTag.journalArticleDate = getQueryParam(href, "date");
					anchorTag.journalArticleVolume = getQueryParam(href, "volume");
					anchorTag.journalArticleIssue = getQueryParam(href, "issue");
					anchorTag.journalArticlePage = getQueryParam(href, "firstPage");
				}
				else if(type == "external") {	
					// Do external links pop up in their own window? (default to yes)
					var popupExternal = true;						
					if(typeof(popupExternalLinks) != 'undefined' && !popupExternalLinks) {
						popupExternal = false;			
					}
					if(popupExternal) {
						// Yup pop them up
						// Note:  If they don't popup, the linkTo url is redirected server side, so
						//        that the app is able to track when the user has clicked off site.						
						anchorTag.onclick = popupAnchor;						
					} 
				}				
				else {								
					if((type == "figurePage" || type == "figureFromContent") && 
						typeof(popupFigurePage) != 'undefined' && popupFigurePage) {
						// TBD The popupFigure function is yet to be written!
						// (currently, no apps are popping up figures)  
						anchorTag.onclick = popupFigure;				
					} 
					else {
						anchorTag.onclick = contentAnchorSelected;
					}
										
					anchorTag.eid = getQueryParam(href, "eid");
					anchorTag.sectionEid = getQueryParam(href, "sectionEid");
					anchorTag.isbn = getQueryParam(href, "isbn");
					anchorTag.hitTerms = getQueryParam(href, "hitTerms");
					anchorTag.hitNum = getQueryParam(href, "hitNum");
					//Here type will be either bookPage or figurePage or figureFromContent
					anchorTag.type = getQueryParam(href, "type");
					anchorTag.className = "reference-link";										
					if(anchorType) {
						anchorTag.anchorType = anchorType;
					}
					
					// add this anchorTag property for new landing page Dart links - RJM 8/20/08
					anchorTag.dartId = getQueryParam(href, "dartId");
					
				}
				// Change the href to ensure that it's *never* followed
				// (otherwise it's terribly confusing when a javascript 
				// error occurs and it gets followed!)
				//anchorTag.href = "#";									
			}
		}
		
		// Is this a "search.do"/"search.dx" url?
		if(href.indexOf("search.d") != -1) {	
			// And is the search method?
			var method = getQueryParam(href, "method");				
			if(method == "search") {
				anchorTag.onclick = searchAnchorSelected;
				anchorTag.searchType = getQueryParam(href, "searchType");			
				anchorTag.searchScope = getQueryParam(href, "searchScope");
				anchorTag.searchQuery = unescape(getQueryParam(href, "searchQuery"));						
				anchorTag.eid = getQueryParam(href, "eid");
				anchorTag.textSearchPage = getQueryParam(href, "textSearchPage", 1);	
				
				// Change the href to ensure that it's *never* followed
				anchorTag.href = "#";											
			}
		}
		
		// Is this a jump to the next high-lighted hit term link?
		if(href.indexOf("#hit") != -1) {
	
			var hitParts = href.split("#");
			if(hitParts.length > 1) {
				var jumpTo = hitParts[1];
				if(jumpTo) {
					anchorTag.onclick = jumpAnchorSelected;	
					anchorTag.jumpTo = jumpTo;
					 
					// Change the href to ensure that it's *never* followed
					anchorTag.href = "#";					
				}
			}
		}											
	}					
}

// A Dojo Ajax handler 
// (Dojo defines this parameter signature) 
function handleContentUpdate(type, html, xhrObject, ioRequest) {

	// The app can define a javascript variable "webAnalyticsTracker" to call a method
	// for tracking the content changes - e.g. we have one called "trackGoogleAnalytics"
	// in bookUtils.js:
	var trackWebAnalytics;
	if((typeof(webAnalyticsTracker) != 'undefined') && webAnalyticsTracker) {
		trackWebAnalytics = webAnalyticsTracker;
	}
															
	// alert("got ajax reply!")									
	ioRequest.bookPlayerState = new elsBookPlayerState(ioRequest.displayedEid,
													ioRequest.dartId,
													html,
													ioRequest.layoutContainerId, 
													ioRequest.areaDivId,
													ioRequest.prevAnchorId,
													ioRequest.nextAnchorId,		
													ioRequest.tocTree,
													scrollFullPageInBook,	
													ioRequest.contentAreaType,	
													updateContentTools,
													// onContentChange:												
													function(bookPlayerState) {
														// Add onclick methods on the anchors in this content:
														cvtAnchorsToUseAjax(bookPlayerState.contentAreaDivId, "content");
														
														// Add onclick methods on the anchors in this content:
														if (typeof(breadCrumbLinks) != 'undefined' && breadCrumbLinks) {
															cvtAnchorsToUseAjax(breadCrumbLinks, "content");
														}
																																										
														rememberCurrentBookPlayerUrl();	
														
														// Don't display the hide/show search hits button if there's no search hits.
														hideShowSearchHits('bookContentPane', 'show');																										
													},
													// onUpdateComplete:
													undefined,
													// trackWebAnalytics
													trackWebAnalytics);
													
	// Convey the url we'd requested to the onContentChange function (see above).
	ioRequest.bookPlayerState.ajaxURL = ioRequest.url;	
														
	// If the left pane is expanded to full width open it to standard width:												
	if(ioRequest.xPane && ioRequest.xPane.openState() == "expanded") {
		// and do so using the ajax history manager:
		navigateLeftPaneTo("opened");
		changeImage('LeftSide');
	}				
	
	// If the left pane is closed, then Hidden pane should be highlighted.
	if(ioRequest.xPane && ioRequest.xPane.openState() == "closed") {
		changeImage('Hidden');
	}
		
	// Hide the ajax activity spinner:
	hideAjaxSpinner(ioRequest.areaDivId);	
			
	// Update the content area, fading in the new content
	// and calling passed in "content change" method which
	// will scan the new content and convert the anchors to
	// use ajax:  																																			
	ioRequest.bookPlayerState.updateContentArea();
	
	// After the content is received the Right content Pane and Left pane
	// should be adjusted to fits inside the browser window regardless of width
	if( typeof(sizePlayer) != 'undefined' && sizePlayer) {
		var thetimer;
		var myString = 'sizePlayer()';
		thetimer=setTimeout(myString,420);			
	}					
}

// A Dojo Ajax handler 
// (Dojo defines this parameter signature) 
function handleAjaxError(type, data, xhrObject, ioRequest) {
//  Owing to the automatic ajax retries more often than not, when 
//  this error occurs, the new content is getting displayed anyway!
//  So it turns out this message provides no benefit to the users at
//  all (and we are getting this one occasion). 
//	displayErrorMsg(ioRequest.areaDivId, 
//							"System error: " + data.message);
		
	handleContentUpdate(type, xhrObject.responseText, xhrObject, ioRequest);
}	

// A Dojo Ajax handler 
// (Dojo defines this parameter signature) 
function handleAjaxTimeout(type, data, xhrObject, ioRequest) {

	displayErrorMsg(ioRequest.areaDivId, 
							"System timeout: " + data.message);
}

// This is the main function to update the content area via either
// Ajax or by simply jumping within the already displayed page.
// The contentState parameter describes the "state" of the content 
// area, and can be either an eid alone, or an eid optionally with
// hitTerms to highlight, e.g. "<eid>;hitTerms=tumor|tumour" 
function updateContentArea(areaDivId, contentState, alreadyOpening) {

	// Remember the current url in a cookie for returning to the book
	// player when they leave and go to supplemental content pages: 
	rememberCurrentBookPlayerUrl();

	var stateParts = contentState.split(";");
	var contentAreaEid = stateParts[0];
	var hitTerms;
	var from;
	var hitNum;
	var type = "bookPage";	
	var sectionEid;
	var figureEid;
	var dartId;	
	var isbn;
	var displayedEid;
	for(var statePartNum = 1; statePartNum < stateParts.length; statePartNum++) {
		var statePartNVP = stateParts[statePartNum].split("=");
		if(statePartNVP.length > 1) {
			if(statePartNVP[0] == "hitTerms") {
				hitTerms = statePartNVP[1];
			}
			if(statePartNVP[0] == "from") {
				from = statePartNVP[1];
			}	
			if(statePartNVP[0] == "hitNum") {
				hitNum = statePartNVP[1];
			}	
			if(statePartNVP[0] == "type") {
				type = statePartNVP[1];
			}			
			if(statePartNVP[0] == "sectionEid") {								
				sectionEid = statePartNVP[1];
			}	
			if(statePartNVP[0] == "figureEid") {								
				figureEid = statePartNVP[1];
			}
			if(statePartNVP[0] == "dartId") {								
				dartId = statePartNVP[1];
			}				
			if(statePartNVP[0] == "isbn") {								
				isbn = statePartNVP[1];
			}
			if(statePartNVP[0] == "displayedEid") {								
				displayedEid = statePartNVP[1];
			}									
		}
	}

	// Is the section being requested the same as the one already displayed?
	var contentAreaElement = dojo.byId("bookContentPane");
	var currentEid;				
	if(contentAreaElement && contentAreaElement.requestedEid) {
		currentEid = contentAreaElement.requestedEid;
	}
	//Fix for section not scrolled in the right side but it stays in the top of page (page level) only for non ajax request.
	// For non Ajax request linkTo url, for particular section Eid if the page Eid is different from requested Section Eid, then we need to get
	// requested section Eid through displayed Eid parameter from the redirected url to scroll down the section content in the right side.
	// For Ajax request we will get the section Eid through ioRequest.displayedEid. We are saving contentAreaEid as displayedEid before attempting linkTo Ajax request
	// This condition will be passed only for non ajax linkTo url only if pageEid is different from requested Eid.
	if(displayedEid) {
		contentAreaEid = displayedEid;
	}	
	// What was the last content state?	
	var priorContentState =  contentAreaElement.getAttribute('priorContentState');		
	if(!priorContentState) priorContentState = contentAreaElement.priorContentState;
	
	// Does this eid already exist as a named anchor on the current page?
	var namedAnchor = findNamedAnchor(contentAreaEid, areaDivId);
	
	if(priorContentState != contentState &&  (type == "figurePage" || type == "figureFromContent" || !namedAnchor)) {
		// Nope pull the new content down via Ajax:
		updateContentAreaViaAjax(areaDivId, contentAreaEid, hitTerms, from, hitNum, type, sectionEid, figureEid, isbn, dartId); 				
	}else if(hitTerms!='' && hitTerms != null){
	// This else if has been added to fix Mantis 1905
	updateContentAreaViaAjax(areaDivId, contentAreaEid, hitTerms, from, hitNum, type, sectionEid, figureEid, isbn, dartId); 
	
	}
	else {	
			
		// If the left pane is expanded to full width open it to standard width:
		var xPane = getElsExpansionPane();														
		if(xPane && xPane.openState() == "expanded") {
			if(!alreadyOpening) {
				// and do so using the ajax history manager:
				navigateLeftPaneTo("opened");
			}
			
			// There's a problem where the jump/scroll within miscomputes
			// the position because the size of the content area is wrong,
			// so wait till this thing is really opened...
			var recurse = 'updateContentArea(\'' + areaDivId + '\', \'' + contentState + '\', true);';		
			setTimeout(recurse, 250);
		}		
		// If the left pane is closed, then Hidden pane should be highlighted.
		if(xPane && xPane.openState() == "closed") {
			changeImage('Hidden');
		}
		
		// The app can define a javascript variable "webAnalyticsTracker" to call a method
		// for tracking the content changes - e.g. we have one called "trackGoogleAnalytics"
		// in bookUtils.js:
		var trackWebAnalytics;
		if((typeof(webAnalyticsTracker) != 'undefined') && webAnalyticsTracker) {
			trackWebAnalytics = webAnalyticsTracker;
		}			
	
		// We build a state object analogous to that which would have
		// been created if we actually did hit the server...
		// Note:  "undefined" for html indicates to use the current page's html.																	
		var theBookPlayerState = new elsBookPlayerState(contentAreaEid,
											dartId,
											null,
											"main", 
											areaDivId,
											"PrevBtnT",
											"NextBtnT",		
											getTocTree(),
											scrollFullPageInBook,	
											type,	
											updateContentTools,														
											function(bookPlayerState) {	
											
													// Add onclick methods on the anchors in this content:
													if (typeof(breadCrumbLinks) != 'undefined' && breadCrumbLinks) {
														cvtAnchorsToUseAjax(breadCrumbLinks, "content");
													}
													
													rememberCurrentBookPlayerUrl();
											},												
											// onUpdateComplete:
											undefined,
											// trackWebAnalytics
											trackWebAnalytics);
																																					
		theBookPlayerState.updateContentArea();	
		
		userActivity(); // the user's done something!																					
	}
	
	// Remember the contentState:
	contentAreaElement.priorContentState = contentState;
				
}	

function updateContentAreaViaAjax(areaDivId, contentAreaEid, hitTerms, from, hitNum, type, sectionEid, figureEid, isbn, dartId) {

	//getBookPageURL defined in the header fragment to support for the muliple/single application
	var url = getBookPageURL;
			
	// The struts action receives the type of request, the eid that was used to request
	// the content, and (if it's a full size figure request) the figureEid and section 
	// containing the figure thumbnail. 
	if(type) {
		url = url + "&type=" + type;
	}
	var displayedEid;
	if(contentAreaEid) {
		url = url + "&eid=" + contentAreaEid;
		displayedEid = contentAreaEid;
	}		

	if(type == "figurePage" || type == "figureFromContent") {
		//Bookmark url (serverFriendlyUrl) contains "figureEid" parameter, Other url doesnt contain figureEid. 
		// Bookmark url doesnt contain sectionEid(Toc Highlighting eid) as we are setting sectionEid to eid while creating serverFriendly url in "bookUtils.js" */
		if(figureEid) {
			url = url + "&figureEid=" + figureEid;
		}
		else {
			//For Ajax request "book.dx?method=getContent" url we need to use contentAreaEid to get the full size image. As we are coming through
			//the thumbnail page, Toc is already highlighted, so no need to take care of Toc highlighting stuff here. 			 
			
			url = url + "&figureEid=" + contentAreaEid;	
		}
	
		if(sectionEid) {
			//But after Full Size Image except its parent if we try some other content page and use "back" button to Full Size Image,
			// Toc remains same it wont highlight the section corresponding to Full Size Image. So in order to handle this, use "sectionEid" from 
			// bookContentPane as "displayedEid" to elsBookPlayerState.
			
			url = url + "&sectionEid=" + sectionEid;
			displayedEid = sectionEid;			
		}
	}
	
	if(isbn) {
		url = url + "&isbn=" + isbn;
	}	
	if(hitTerms) {
		url = url + "&hitTerms=" + hitTerms; 
	}	
	if(from) {
		url = url + "&from=" + from; 
	}
	if(hitNum) {
		url = url + "&hitNum=" + hitNum; 
	}			
	// Encode the URL with the uniq id for the browser cache updated content to display.
	url = url + '&uniq=' + uniq;
	
	// Append sid in the URL to show the highlighted terms if it exists.
	if(typeof(sid) != 'undefined' && sid) {
		url = url + "&sid=" + sid;
	}
		

	// Allow that left pane might not be there: 
	var xPane = getElsExpansionPane(); 
	var smartTabs = getElsSmartTabs(); 
	var contentAreaType = type;
	var ioRequest = {

		method: "GET",

		url: url,
		
		//Data for use once we have data for an elsBookPlayerState object
		layoutContainerId: "main",
		prevAnchorId: "PrevBtnT",
		nextAnchorId: "NextBtnT",	
		xPane: xPane,	
		smartTabs: smartTabs,			
		areaDivId: areaDivId,
		contentAreaType: contentAreaType,
		displayedEid: displayedEid,		
		tocTree: getTocTree(),
		dartId: dartId,
		
		//A holder for the book player state object.
		//It will be created once we have a response from the bind request.
		bookPlayerState: null,
		
		//To use the browser cache, set useCache to true
		useCache: true,	

		load: handleContentUpdate,
	
		error: handleAjaxError,	
				
		timeoutSeconds: 180,
		timeout: handleAjaxTimeout
	};
	
	// Display the ajax activity spinner:
	displayAjaxSpinner(areaDivId);
	
	// alert("starting the ajax call!");
	userActivity(); // the user's done something!			
	dojo.io.bind(ioRequest);	
	
}

function displayAjaxSpinner(overAreaId) {
	
	if(typeof(ajaxSpinnerInBookContentPane) != 'undefined' && ajaxSpinnerInBookContentPane) {
		 if(dojo.render.html.ie70 || dojo.render.html.safari) {
		 	document.documentElement.scrollTop = 0;
		 } else {
			document.body.scrollTop = 0;
		 }
		var contentAreaElement = dojo.byId("bookContentPane");		
		contentAreaElement.innerHTML = "<div id='bookContentPaneSpinner'  class='bookcontrolspinner'><img src='"+ajaxSpinnerURLPrefix+"bookContentPaneSpinner.gif' align=absmiddle>&nbsp;&nbsp;<span style='vertical-align:middle; font-size: 12pt;'><b>loading...</b></span></img></div>";	
	}
	var spinnerElem = dojo.byId(overAreaId + "Spinner");
	if(spinnerElem) {
		spinnerElem.style.visibility = "visible";
	}
			
	return;
}

function hideAjaxSpinner(overAreaId) {

	var spinnerElem = dojo.byId(overAreaId + "Spinner");
	if(spinnerElem) {
		spinnerElem.style.visibility = "hidden";
	}
	
	return;
}

// Activate the content area of the page by doing some initialization.	
function activateContentArea() {
   if(typeof(yahooHistoryInitialized)!= 'undefined' && yahooHistoryInitialized) {
		//Smooth scroll for MD Consult: If scrollFullPage is true; the entire (document.body) should scroll
		if(typeof(scrollFullPage) != 'undefined' && scrollFullPage)
		scrollFullPageInBook = scrollFullPage;
			
		// Get the div tag surrounding the right hand side content:		
		var contentAreaElement = dojo.byId("bookContentPane");
		
		// Have we already activated?
		if(contentAreaElement && contentAreaElement.activated) {
			// Yup - don't do it twice!
			return;
		}		
		
		// Remember that we've activated:		
		contentAreaElement.activated = true;
				
		// Tell the print button to call our print preview function		
		var printElement = dojo.byId("printButton");	
		if(printElement) {
			printElement.onclick = printPreview;		
		}	
		
		// Don't display the hide/show search hits button if there no search hits.
		hideShowSearchHits('bookContentPane', 'show');		
		
		// One time only (after the page has loaded), install the javascript 
		// handlers for the next and previous buttons/links:
		cvtAnchorToUseAjax(dojo.byId("PrevBtnT"), "prev");	
		cvtAnchorToUseAjax(dojo.byId("NextBtnT"), "next");
		
		cvtAnchorsToUseAjax(contentAreaElement, "content");		
			
		// We only "activate" when we've gotten a full page refresh
		// directly from the server, where the server prepopulates the
		// content so that we don't need to go back via Ajax.  Let 
		// updateContentArea know what eid the server's given us:
		var eid = getQueryParam(window.location.href, "eid");	
		var type = getQueryParam(window.location.href, "type");			
		if (eid) {
			if(contentAreaElement) {			
				contentAreaElement.requestedEid = eid;				
			}
			if(type && (type == "figurePage" || type == "figureFromContent")) {
				var figureEid = getQueryParam(window.location.href, "figureEid");
				contentAreaElement.figureEid = figureEid;
			}		
		}
		
		// We *must* have the contents tree activated before we call updateContentArea
		initContentsTree();				
		
		// But (as an Yahoo history manager onload handler) we're
		// also being called when the user comes back to our page using the 
		// back button, in which case the "content" eid in the hash might
		// not match the "eid" query parameter in the url as seen by the
		// server.  Depending on the scenario, updateContentArea may now
		// hit the server for the proper content via Ajax, or may simply
		// sync up the TOC with the content correctly generated off the
		// server:
		var currentState = YAHOO.util.History.getCurrentState( "content" );		
		var newisbn = getQueryParam(window.location.href, 'isbn');
		var isbn;
		if(currentState) {			
			if(contentAreaElement && window.location.hash == "") {
				// We don't want to hit the server via ajax since
				// we've gotten the content from the server initially			
				contentAreaElement.priorContentState = currentState;				
			}
	
			// Yet currently we still have to do parts of what
			// updateContentArea provides (e.g. highlighting the TOC).
			var stateParts = currentState.split(";");			
			for(var statePartNum = 1; statePartNum < stateParts.length; statePartNum++) {
				var statePartNVP = stateParts[statePartNum].split("=");
				if(statePartNVP.length > 1) {			
					if(statePartNVP[0] == "isbn") {								
						isbn = statePartNVP[1];
					}								
				}
			}
			if(isbn == newisbn)
			updateContentArea("bookContentPane", currentState); 	
		}	
		
		// Start the grace period/inactivity timeout(s):
		initInactivityGracePeriod();	
	} else {
      setTimeout('activateContentArea();', 300);
 	}
}

// activateContentArea is normally called because we 
// register it with YAHOO.util.History.onLoadEvent.subscribe.
// Unfortunately in IE (only) there seems to be a bug preventing
// it from being called there (at least sometimes).  So give it
// some time to initialize, and then call our activate function,
// which we've set up to no-op if called more than once:	
dojo.addOnLoad(activateContentArea);				

