/**
 * Object and functions used for the My List Library Cart features.
 *
 * *** *** This script is used both client-side and server-side *** ***
 *
 * Author: David Nordlund
 * Date: August 14-18, 2006
 */

/**
 * Constructor/model for LibraryCart objects
 */
function LibraryCart( cookieID )
{
	// data members:
	this.length = 0;
	this.items = new Array();
	this.cookieName = cookieID ? cookieID : "LibraryCart";
	this.cookiePath = '/';
	this.cookieSep = '*';
	this.dirty = false;

	// methods:

	/**
	 * LibraryCart.has
	 * return: true if the item is in the user's list, false otherwise.
	 */
	this.has = function( itemID )
	{
		for(var i in this.items)
			if(this.items[i] == itemID)
				return true;
		//this.report("has(" + itemID + ") == no");
		return false;
	}
	/**
	 * LibraryCart.find
	 * return the index of the array where itemID can be found, or -1 if not found.
	 */
	this.find = function( itemID )
	{
		var idx = 0;
		for(var i in this.items)
		{
			if(this.items[i] == itemID)
				return idx;
			idx++;
		}
		//this.report("find(" + itemID + ") == not found");
		return -1;
	}

	/**
	 * LibraryCart.add
	 * add an item to a library cart, if it is not already in the cart.
	 * return true if the item was added, false if it was already there.
	 */
	this.add = function( itemID )
	{
		//this.report("Attempting to add '" + itemID + "'");
		if( this.validateItemID( itemID ) == false )
			return false;
		if( this.has( itemID ) )
			return false;
		this.items.push( itemID );
		this.length++;
		this.dirty = true;
		return true;
	}
	
	/**
	 * LibraryCart.remove
	 * remove an item from a LibraryCart
	 * return true if the item was removed, false if it wasn't even in the cart.
	 */
	this.remove = function( itemID )
	{
		//this.report("Attempting to remove '" + itemID + "'");
		var idx = this.find( itemID );
		if(idx == -1)
			return false;
		this.items.splice(idx, 1);
		this.length--;
		this.dirty = true;
		return true;
	}
	
	/**
	 * LibraryCart.removeAll
	 * remove every item in the LibraryCart
	 */
	this.removeAll = function()
	{
		if(this.length == 0)
			return;
		delete this.items;
		this.items = new Array();
		this.length = 0;
		this.dirty = true;
	}

	/**
	 * LibraryCart.toString
	 * convert the contents of the library cart to a single string,
	 * used for setting the cookie.
	 */
	this.toString = function()
	{
		var cookie = new Array();
		for(var i in this.items)
			cookie.push( this.items[i] );
		return this.cookieSep + cookie.join( this.cookieSep );
	}
	
	/**
	 * LibraryCart.parseCookie
	 * Decode a cookie string and load the items into the cart.
	 */
	this.parseCookie = function( cookieString )
	{
		var cs = String(cookieString);
		if( (cs == '') || (cs == 'undefined') || (cs == 'null') )
			return false;
		// check cookie format.  either document.cookie with cookie embeded, or just encoded data.
		var cookieCutter = new RegExp(this.cookieName + '=([^;]+)');  // document.cookie format
		var match = cookieCutter.exec(cs); // cut out just the data from the matched cookie
		if(match != null)
			cs = String(match[1]);
		var char1 = cs.charAt(0);
		if(char1 == '%')
			cs = unescape( cs );
		else if(char1 != this.cookieSep)
		{
			//this.report("parseCookie: cookie format unrecognized '" + cs + "', [0]=='" + cs.charAt(0) + "'");
			return false;
		}
		var cookie = cs.substring(1).split( this.cookieSep );
		if( cookie.length < 1 )
			return false;
		this.removeAll();
		for( var i in cookie )
			this.add( cookie[i] );
		this.length = this.items.length;
		return true;
	}
	
	/**
	 * LibraryCart.setCookieName
	 * set the name of the cookie to use with the user's web browser.
	 */
	this.setCookieName = function( cname )
	{
		this.cookieName = cname;
	}
	
	/**
	 * LibraryCart.getCookieName
	 * get the name of the cookie to use with the user's web browser.
	 */
	this.getCookieName = function()
	{
		return this.cookieName;
	}
	
	/** LibraryCart.loadCookie
	 * Get the cookie string from the users browser and then parse it.
	 * return true if a cookie was found and successfully parsed, false otherwise.
	 */
	this.loadCookie = function()
	{
		var cookieString = '';
		if( this.isClientSide() )
			cookieString = document.cookie;
		else
			cookieString = Request.Cookies( this.cookieName );
		//this.report("loadCookie: cookieString = [" + cookieString + "]<br />");		
		var loaded = this.parseCookie( cookieString );
		this.dirty = !loaded;
		return loaded;
	}
	
	/**
	 * LibraryCart.saveCookie
	 * Save the contents of the library cart to a cookie
	 * This must be called prior to the output of any html.
	 */
	this.saveCookie = function()
	{
	//	this.report("Saving cookie: '" + this.toString() + "'");
		if( this.isClientSide() )
			document.cookie = this.cookieName + '=' + this.toString() + '; path=' + this.cookiePath;
		else
		{
			Response.Cookies( this.cookieName ) = this.toString();
			Response.Cookies( this.cookieName ).Path = this.cookiePath;
		}
		this.dirty = false;
	}
	
	/**
	 * LibraryCart.get
	 * Get an itemID by index number.
	 */
	this.getItemID = function( idx )
	{
		if( ( idx < 0 ) || ( idx >= this.length ) )
			return null;
		return this.items[idx];
	}
	
	/**
	 * LibraryCart.validateItemID
	 * return true if the itemID is a valid on, false otherwise.
	 */
	this.validateItemID = function( itemID )
	{
		var check = new RegExp('^[a-z0-9_]+$', 'i');
		var passed = true;
		if( (!itemID) || (typeof(itemID) == 'undefined') || (itemID==null) )
			passed = false;
		else if( check.exec( itemID ) == null )
			passed = false;
		if(!passed)
			//this.report( 'validateItemID( ' + itemID + ' ) == ' + passed );
		return passed;
	}
	
	/**
	 * Determine if the script is running client-side or server-side
	 */
	this.isClientSide = function()
	{
		if( typeof(Server) == 'undefined' )
			return true;
		return false;
	}
	
	/// This is used to print out debug info
	this.report = function( data )
	{
		if( this.isClientSide() )
			alert(data);
		else
			Response.write("<div class='debuginfo'>" + data + "</div>\n");
	}
	
	/**
	 * return true if the cookie in memory is in sync with the cookie
	 */
	this.isClean = function()
	{
		return !this.dirty;
	}
}

/**
 * mylistRestyle
 * add/remove a css class to/from an element, if a condition is true/false.
 */
function libraryCartRestyle( elementID, condition, cssclass )
{
	if(!document.getElementById)
		return;
	var element = document.getElementById(elementID);
	if(!element)
		return;
	var classAttributeName = "class";  // *sigh*, except IE, which renames it className
	var eclass = element.getAttribute(classAttributeName);
	if(!eclass) // must be MSIE...
	{
		classAttributeName = "className";
		eclass = element.getAttribute(classAttributeName);
	}
	if(condition)
	{
		eclass += ' ' + cssclass;
	} else {
		eclass = eclass.split(' ', 1);
	}
	element.setAttribute(classAttributeName, eclass);
}
