$(document).ready(function() {
    var menu = $('#main_menu');

    function Operations() {
        var that = this;
        var registered_ops = {};
        var num_ops = 0;
        
        this.register = function(f, name) {
            if (name == null) {
                name = num_ops;
            }
            if (registered_ops[name] != null) {
                throw new Error("Already registered: " + name);
            }
            registered_ops[name] = f;
            f.op_name = name;
            num_ops += 1;
        };
        
        this.serialize = function(f, args) {
            if (typeof(f.op_name) == 'undefined') {
                this.register(f);
            }
            var closure = [f.op_name, args];
            var result = null;
            try {
                result = encodeURIComponent(JSON.stringify(closure));
            } catch (e) {
                throw new Error("Could not create closure: " + e.message());
            }
            return result;
        };
        
        this.deserialize = function(s) {
            var result = null;
            try {
                result = window["eval"]("(" + decodeURIComponent(s) + ")");
            } catch (e) {
                throw e;
            }
            return result;
        };
        
        this.callSerialized = function(s) {
            var v = that.deserialize(s);
            var op = registered_ops[v[0]];
            var result = null;
            try {
                result = op.apply(op, v[1]);
            } catch (e) {
                // console.log("Can't apply operation: " + e);
            }
            return result;
        };
    };
    var ops = new Operations();
    
    // Valid page-manipulation operations:
    function loadTab(index, url) {
        // FRAGILE:  Try to discover the current URL for the indexed tab.
        // Depends on undocumented jquery UI tabs implementation.
        var a = $('a', menu).eq(index)[0];
        var currURL = $.data(a, 'load.tabs');

        menu.tabs('select', index);
        // Load the new URL only if it differs from currURL
        if (url != currURL) {
            menu.tabs('url', index, url);
            menu.tabs('load', index);
        }
    };
    ops.register(loadTab);
    
    function historyCB(hash) {
        if (hash) {
            ops.callSerialized(hash);
        } else if (!hash) {
            // console.log("    Should go back to the original page...");
        }
    };

    menu.tabs({
        load: function(event, ui) {
            var url = $.data(ui.tab, 'load.tabs');
            $.history.load(ops.serialize(loadTab, [ui.index, url]));
        }
    });
    menu.css({'display': 'block'});
    
    // menu.tabs will automatically load the default tab.  Initialize
    // history after initializing tabs, so tabs load does not overwrite
    // any tab hash which might be present at initial page load.
    $.history.init(historyCB);
});
