/**
 * HistoryStack
 *
 * A JavaScript object for storing resources or identifiers in a
 * history stack.  The history lasts as long as the browser is 
 * open (i.e. session cookie).
 *
 * Written by Mike Brittain for IBM developerWorks.
 */

/**
 * Constructor
 */
function HistoryStack (){
    /** Current stack loaded in memory, which will also be
        cached to cookies. */
    this.stack = new Array();
    
    /** Pointer to current location in the history stack. */         
    this.current = -1;
    
    /** Max size of the history stack. */
    this.stack_limit = 15;
}


/**
 * Return the name of the current resource in the
 * history stack.
 */
HistoryStack.prototype.getCurrent = function (){
    return this.stack[this.current];
};


/**
 * Add the resource to the next position after the "current" pointer.
 * If there are items existing past current, they will first be cut 
 * off the end of the stack.  The stack will also be truncated to 
 * "stack_limit" if it has grown to large.
 */
HistoryStack.prototype.addResource = function(resource){
    if (this.stack.length > 0) {
        this.stack = this.stack.slice(0, this.current + 1);
    }
    this.stack.push(resource);
    while (this.stack.length > this.stack_limit) {
        this.stack.shift();
    }
    this.current = this.stack.length - 1;
    //this.save();
};


/**
 * Handle navigation within the history stack.  Any negative argument
 * will go backwards in the stack and positive arguments will go 
 * forward.  If zero is passed to the method, the page will be 
 * reloaded. 
 */
HistoryStack.prototype.go = function(increment){
    // Go back...
    if (increment < 0) {
        this.current = Math.max(0, this.current + increment);
    
    // Go forward...
    } else if (increment > 0) {
        this.current = Math.min(this.stack.length - 1, 
            this.current + increment);
    
    // Reload...
    } else {
        //Modified 10/02/2009
        //location.reload();
        //Do nothing. Mantain the present resource
    }
    
    this.save();
};


/**
 * Returns boolean value whether there is a previous 
 * entry in the history stack.
 */
HistoryStack.prototype.hasPrev = function(){
    return (this.current > 0);
};

/**
 * Returns boolean value whether there is a suceeding 
 * entry in the history stack.
 */
HistoryStack.prototype.hasNext = function()
{
    return (this.current < this.stack.length - 1 
        && this.current > -1);
};


/**
 * Save the current history stack and pointer to cookies
 */
HistoryStack.prototype.save = function(){
    this.setCookie('CHStack', this.stack.toString());
    this.setCookie('CHCurrent', this.current);
};

/**
 * Load the history stack and pointer from cookies.
 */
HistoryStack.prototype.load = function(){
    var tmp_stack = this.getCookie('CHStack');
    if (tmp_stack != '') {
        this.stack = tmp_stack.split(',');
    }
    
    var tmp_current = parseInt(this.getCookie('CHCurrent'));
    if (tmp_current >= -1) {
        this.current = tmp_current;
    }
};



/**
 * Save a name/value pair as a browser cookie, to expire at 
 * end of session.
 */
HistoryStack.prototype.setCookie = function(name, value){
    var cookie_str = name + "=" + escape(value);
    document.cookie = cookie_str;
};

/**
 * Retrieve a cookie value by the given name.
 */
HistoryStack.prototype.getCookie = function(name){
    if (!name) return '';
    
    var raw_cookies, tmp, i;
    var cookies = new Array();
	
    raw_cookies = document.cookie.split('; ');
    for (i=0; i < raw_cookies.length; i++) {
        tmp = raw_cookies[i].split('=');
        cookies[tmp[0]] = unescape(tmp[1]);
    }

    if (cookies[name] != null) {
        return cookies[name];
    } else {
        return '';
    }
};

