/***********************************************************************
Elsevier "Expansion Pane"

This object supports having a left pane that can take on any of three 
states:  

	a.  opened (to a "standard width" specified in pixels).
	b.  closed
	c.  expanded (to the full width of the browser).
	
A cookie is used to remember which of the three states the pane is currently in.

You give the constructor the html id for the dojo layoutContainer that
contains the left pane, the id for the left pane itself, the width
in pixels for the left pane when open to it's "standard" width, and
optionally the initial state to display the pane in (otherwise the
value of the cookie will be used).

Then provide buttons/links/etc. which call the methods open(), close(), 
or expand() as appropriate.

************************************************************************/	
	
function elsExpansionPane(layoutContainerId, leftPaneId, leftPaneStdWidth, initialState) {
	
	// Include the elsCookie javascript object: (for now include via page)	
	// document.write('<script type="text/javascript" src="elsCookie.js"></script>');		
		
	//////////////////////////////////////////////////////////
	// Overridable Settings:		
	
	// Is the server reading the cookie and conditionally generating
	// the page with the pane initially opened or closed?  
	// (this gives the best user experience since they don't see it
	// initially in the wrong state prior to the page load finishing) 
	this.serverReadingCookie = false;
		
	// The id of the left pane area to be opened/closed/expanded:	
	this.leftPaneId = leftPaneId;

	// The id of the dojo layoutContainer that contains the left pane:	
	this.layoutContainerId = layoutContainerId;

	// The width in pixels of the left pane when open (e.g. "300"):	
	this.leftPaneStdWidth = leftPaneStdWidth;

	// The name to use for the cookie (default is "Status"):
	this.cookieName = 'State';		
	
	// By default prefix the cookieName with the leftPaneId, to 
	// ensure uniqueness if there are multiple panes:	
	this.prefixCookieName = true;
	
	// The cookie object (normally created automatically based on the above):	
	this.elsCookie = null;	
		
	//////////////////////////////////////////////////////////
	// Not Overridable:

	// The left pane element:	
	var leftPaneElement;
	
	// The layout container element:
	var layoutContainerElement;
	
	// The current state of the left side ("opened", "closed", "expanded"):
	var currentState;
	if(initialState && initialState != 'none') {
		currentState = initialState;
	}
		
	//////////////////////////////////////////////////////////
	// Methods:			
							
	// Close the pane		
    this.close = function () {
    
		// The "wipe out" animation works fine on everything but safari (for some reason):
		if(!dojo.render.html.safari) {   
			this.hWipeOut(this.leftPaneId, 1, 150, 50, resizeLayoutContainer).play(); 
		}
		else {
			// On Safari shutting it without animating it closed works though:
			var nodes = dojo.lfx.html._byId(this.leftPaneId);
			if(nodes.length > 0) {
				nodes[0].style.width = "0px";
				this.resized();
				dojo.html.hide(nodes[0]);
			}
		}
		if(typeof(scrollFullPage) != 'undefined' && scrollFullPage){
			var rightContentPane = dojo.byId("rightContentPane");
			if(rightContentPane) rightContentPane.style.overflow = "visible";
		}	
		this.elsCookie.set("closed");
		currentState = "closed";				
	};
	
	// Open the pane to the "standard" width (as specified to our constructor)
	this.open = function () {  	
		this.hWipeIn(this.leftPaneId,this.leftPaneStdWidth, 150, 50, resizeLayoutContainer).play();
		// if it is a fullPage Scroll version then set the right content pane's default overflow as visible.
		if(typeof(scrollFullPage) != 'undefined' && scrollFullPage){
			var rightContentPane = dojo.byId("rightContentPane");
			if(rightContentPane) rightContentPane.style.overflow = "visible";
		}						
		this.elsCookie.set("opened");
		currentState = "opened";						
	}; 		
	
	// Expand the pane to full width
	this.expand = function () {  	
		this.hWipeIn(this.leftPaneId,-1, 150, 50, resizeLayoutContainer).play();
		if(typeof(scrollFullPage) != 'undefined' && scrollFullPage){
			var rightContentPane = dojo.byId("rightContentPane");
			// the overflow had to be set to 'hidden' to avoid the overlay of the contents.
			if(rightContentPane) rightContentPane.style.overflow = "hidden";
		}				
		currentState = "expanded";				
		this.elsCookie.set("expanded");				
	}; 		

	// Return whether the pane is "opened", "closed", or "expanded" width.	
	this.openState = function ()
	{
		return currentState;		
	};	
	
	
	// Is the specified state one that we understand?
	this.validState = function(state) {
		return(state == "opened" || state == "closed" || state == "expanded");
	} 
	
	// Open the pane to the specified state
	this.openTo = function(state) {
			
		if(!state) {
			return;
		}
			
		if(state == "closed") {	
			this.close();												
		}
		
		if(state == "opened") {
			this.open();
		}
		
		if(state == "expanded") {
			this.expand();
		}		
	}	
				  
	// Get the cookie name to use, according to the elsSmartPane's 
	// configuration settings:	
	this.getCookieName = function ()
	{
		var theCookieName = '';
		if(this.prefixCookieName) {
			theCookieName = this.leftPaneId;
		}
		theCookieName = theCookieName + this.cookieName;
		
		return theCookieName;		
	};	
	  
	// Horizontal wipe out (and hide) the specified nodes by animating their width	  
	this.hWipeOut = function(nodes, targetWidth, duration, easing, callback) {
		nodes = dojo.lfx.html._byId(nodes);
		var anims = [];
		dojo.lang.forEach(nodes, function (node) {
			var oprop = {};
			var anim = dojo.lfx.propertyAnimation(node, {"width":{start:function () {
				return dojo.html.getContentBox(node).width;
			}, end:targetWidth}}, duration, easing, {"beforeBegin":function () {
				oprop.overflow = node.style.overflow;
				oprop.width = node.style.width;
				with (node.style) {
					overflow = "hidden";
				}
				dojo.html.show(node);
			}, "onEnd":function () {
				dojo.html.hide(node);
				with (node.style) {
					overflow = oprop.overflow;
					width = oprop.width;
				}
				if (callback) {
					callback(node, anim);
				}
			}});
			anims.push(anim);
		});
		return dojo.lfx.combine(anims);
	};
			
	// Horizontal wipe in (and show) the specified nodes by animating their width 		
	this.hWipeIn =  function(nodes, targetWidth, duration, easing, callback) {
		
		if(targetWidth < 0) {
			targetWidth = this.getBrowserWidth() - 60;
		}
	
		nodes = dojo.lfx.html._byId(nodes);
		var anims = [];
		dojo.lang.forEach(nodes, function (node) {
			
			var oprop = {};
			var anim = dojo.lfx.propertyAnimation(node, {"width":{start:function () {
				return dojo.html.getContentBox(node).width;
			}, end:targetWidth}}, duration, easing, {"beforeBegin":function () {
						
				oprop.overflow = node.style.overflow;
				oprop.width = targetWidth;
				with (node.style) {
					overflow = "hidden";
				}
				dojo.html.show(node);
			}, "onEnd":function () {
				with (node.style) {
					overflow = oprop.overflow;
					width = oprop.width;
				}
				if (callback) {
					callback(node, anim);
				}
			}});
			anims.push(anim);
		});
		return dojo.lfx.combine(anims);
	};
		
	// Call this function to update the dojo layout container's positioning.	
	this.resized = function() {
		if(layoutContainerElement) {
			layoutContainerElement.onResized();
		}
	}		
			
	// Function called to update the dojo layout container's positioning
	// upon each step of the wipe in/wipe out animations.
	function resizeLayoutContainer(node, anim) {
	
		// Get the smart pane off the element where we've stored it
		var thePane = node.xPane; 
		if(!thePane) {
			return;
		}	
	
		thePane.resized();
	}
	
	// Get the browser width (in a cross browser compliant way)
	this.getBrowserWidth = function() {
		var browserWidth = 0;
		if (document.all) {
			browserWidth = document.body.clientWidth;
		}
		else {
			browserWidth = window.innerWidth;
		}
		
		return browserWidth;
	}	  
	   						
	// "Activate" this activation pane on the current page.	
	this.activatePane = function ()
	{	
		// Get the layout container element:	
		layoutContainerElement = dojo.widget.byId(this.layoutContainerId);
		if(layoutContainerElement) {
			layoutContainerElement.xPane = this; 
		}
		
		// Get the left pane itself:	
		leftPaneElement = dojo.byId(this.leftPaneId);
		if(leftPaneElement) {		
			leftPaneElement.xPane = this;
		}
										     											
		// Get whether we should initially be open/closed from the cookie:
		if(!this.elsCookie) {			
			if(typeof(isbn) != 'undefined' && isbn){	
				this.elsCookie = new elsCookie(this.getCookieName()+isbn,500);
			} else {
				this.elsCookie = new elsCookie(this.getCookieName(),500);
			}
		}
		
		// If the server's not generating the page based on our cookie:	
		if(!this.serverReadingCookie) {			
			// Then we need to open or close it ourselves:		
			if(!this.validState(currentState)) {
				currentState = this.elsCookie.get();			
				if(!this.validState(currentState)) {
					currentState = "opened";			
				}				
			}

			this.openTo(currentState);
		}
	};	
}

	

