/* Status Manager
 *
 * Requirements:
 *   - jQuery 1.2 or newer
 */

var ext_qs = '';

function StatusManagerSingleton() {
    var initvalues = this.getInitValues();
    for (var i in initvalues){
        if (i != 'current_tab') this.set( i, initvalues[i], -1 ); 
    }
}

StatusManagerSingleton.prototype.getInitValues = function() {
    // TODO - Read from the cookie(s)

    // Read from the query string
    var	qs = location.search.substring(1);
    var qsdict = this.strToDict(qs);
    // Read from the hash path
    var	hash = location.hash.substring(1) + ext_qs;
    this.hashdict = this.strToDict(hash);
    this.redirect = false;
    // Move any history variables to the hash dict
    for (var key in qsdict) {
        if (qsdict[key] != null && this.hashdict[key] == null) {
            this.redirect = true;
            this.hashdict[key] = qsdict[key];
            qsdict[key] = null;
        }
    }
    if (this.hashdict['current_tab'] == 'registration') this.redirect = false;
    return this.hashdict;
}

/* ------------------------------------------------------------------------ */
StatusManagerSingleton.prototype.hashdict = new Object();
StatusManagerSingleton.prototype.redirect = new Boolean(false);
StatusManagerSingleton.prototype.components = new Array();
StatusManagerSingleton.prototype.handlers = new Object();
StatusManagerSingleton.prototype.variables = new Object();

/*
 * basePageLoad()
 * FOR NOW THIS FUNCTION HAS BEEN DEPRECATED - NO LONGER REWRITING INITIAL URL
 * Let's remove any campaign related query string data
 */
StatusManagerSingleton.prototype.basePageLoad = function(){

    if (this.redirect) {
        // Any were moved.  Redirect.
        var url = location.pathname;
        var i = 0;
        for (var key in this.hashdict) {
            if (key == null || this.hashdict[key] == null) continue;
            url += (i++ > 0) ? "&" : "#";
            url += key + "=" + escape(this.hashdict[key]);
        }
        //location.href = url;
    }
}

/*
 * registerNewComponent()
 * Registers a component with the status manager.
 */
StatusManagerSingleton.prototype.registerNewComponent = function(comp) {
    var name = comp.name;

    if ( !this.verifyComponent(comp) ) {
        this.log("Failure verifying component: " + name);
        return;
    }

    // Make sure the component isn't already registered
    for (var i = 0; i < this.components.length; i++)
        if (this.components[i].name == name)
            return;

    this.components[this.components.length] = comp;

    // Set the "registered_components" variable
    this.set('registered_components', this.components.length);
}

/*
 * verifyComponent()
 * Make sure all of the necessary parts of the component exist
 */
StatusManagerSingleton.prototype.verifyComponent = function(comp) {
    // TODO - What should we check for? 
    return 1;
}

/*
 * addHandler( status_variable_name, method )
 * Adds a handler for the given variable name
 */
StatusManagerSingleton.prototype.addHandler = function(svarname, method) {
    if (! this.handlers[svarname]) {
        this.handlers[svarname] = new Array();
    }

    // Make sure the handler isn't already registered
    for (var i = 0; i < this.handlers[svarname].length; i++)
        if (this.handlers[svarname][i] == method)
            return;

    this.handlers[svarname][this.handlers[svarname].length] = method

    // If there's a value to the variable, fire the handler immediately
    if (this.variables[svarname]) {
        method( this.variables[svarname], null, svarname );
    }
}

/* ------------------------------------------------------------------------ */

/*
 * get( status_variable_name )
 * Returns the current value of the variable
 */
StatusManagerSingleton.prototype.get = function(svarname) {
    if (this.variables[svarname]){
        return this.variables[svarname]
    }
    return
}

/*
 * set( status_variable_name, value )
 * Sets the value of the variable and calls every registered handler for it,
 * passing three arguments: new value, old value, name of the variable
 */
StatusManagerSingleton.prototype.set = function(svarname, value, setDefault) {
    if (! this.variables[svarname] || this.variables[svarname] != value) {
        var oldValue = this.variables[svarname];
        this.variables[svarname] = value;
        // Call all of the handlers
        if (this.handlers[svarname]) {
            for (var i = 0; i < this.handlers[svarname].length; i++)
                this.handlers[svarname][i]( value, oldValue, svarname );
        }

        if (setDefault != -1) {
        var hv = this.get('history_variables');
          if (svarname == "history_variables" || svarname == "current_tab" ||
            (hv && jQuery && jQuery.inArray(svarname, hv) != -1)) {
            this.setHistory(setDefault);
          }
        }
    }
}

/*
 * setHistory()
 * Uses the history variables to set the current url for back button and
 * permalinking
 */
StatusManagerSingleton.prototype.setHistory = function(setDefault) {
    var url = "";
    var hv = this.get('history_variables');
    if (!hv || hv == undefined) hv = new Array();

    var tab = this.get("current_tab");
    if (tab) url += tab;

    for (var key in this.variables) {
        if (jQuery.inArray(key, hv) != -1) {
            var val = this.get(key);
            if (val != null) {
                url += (url != "") ? "&" : "";
                url += escape(key) + "=" + escape(val);
            }
        } else {
            // XXX - Remove it?
        }
    }
     
    if (url != "" && location.hash != "#" + url) {
        location.hash = url;
    }
    window.scrollTo(0,0);
}

/*
 * strToDict(str)
 * Splits 'foo=bar&baz=qux' pairs into a { foo => bar } hash
 */
StatusManagerSingleton.prototype.strToDict = function(str) {
    var rv = new Object();
    str = str.replace(/\+/g,' ');
    var args = str.split('&')
    
    for (var i = 0; i < args.length; ++i) {
        if (args[i] == "") continue;
        var pair = args[i].split('=');
        var next = (i+1<args.length?args[i+1]:'');
        var name = unescape(pair[0]);
        var value = unescape(pair[1]);
        if (next && next.indexOf('=') < 0) {
            value += '&' + unescape(next);
            i++;
        }

        if (pair.length >= 2)
            rv[name] = value;
        else if (i == 0) // initial current_tab doesn't have name=val
            rv["current_tab"] = name;
    }

    return rv;
}

/*
 * log( text )
 * Adds arbitrary text to the debugging log
 */
StatusManagerSingleton.prototype.log = function(text) {
    $("#log").append("<p>" + text + "</p>\n");
}

/* ------------------------------------------------------------------------ */

// Create the Status Manager when the document is "ready"
$(document).ready(function() {
    if (typeof StatusManager == 'undefined') StatusManager = new StatusManagerSingleton();
})


/*###############Copyright##################
 *####   Copyright 2008 Texterity, Inc  ####
 *###############Copyright##################
 */
