﻿function NavigationHandler(name, callback)
{
    var m_ParamNames = new Array();
    var m_ParamValues = new Array();
    
    var m_ParamList = null;
    
    this.GetName = function() { return name; }
    
    this.ClearParams = function()
    {
        m_ParamNames = new Array();
        m_ParamValues = new Array();
    }
    
    this.SetParamValue = function(param_name, param_value)
    {
        // look for existing param with the given name and update it
        for(var i = 0; i < m_ParamNames.length; i++) {
            if(m_ParamNames[i] == param_name) {
                m_ParamValues[i] = param_value;
                return;
            }
        }
        
        // add new param
        var i = m_ParamNames.length;
        m_ParamNames[i] = param_name;
        m_ParamValues[i] = param_value;
    }
    
    this.GetParamValue = function(param_name)
    {
        // look for param with the given name and return its value
        for(var i = 0; i < m_ParamNames.length; i++) {
            if(m_ParamNames[i] == param_name)
                return m_ParamValues[i];
        }
        
        return null;
    }
    
    this.BuildParamList = function()
    {
        var s = "";
        
        for(var i = 0; i < m_ParamNames.length; i++) {
            if(m_ParamValues[i] == null)
                continue;
                
            if(s.length > 0)
                s += ";";
            
            s += name + "_" + m_ParamNames[i] + "=" + escape(m_ParamValues[i]);
        }
        
        return s;
    }
    
    this.DoCallback = function()
    {
        if(callback == null)
            return;
            
        if(this.BuildParamList() == m_ParamList)
            return;
        
        callback();
    }
    
    this.SaveParamList = function()
    {
        m_ParamList = this.BuildParamList();
    }
}

function Navigation()
{
    var m_Interval = null;
    var m_Hash = "";
    
    var m_Handlers = new Array();
    
    this.CreateHandler = function(name, callback)
    {
        var handler = new NavigationHandler(name, callback);
        m_Handlers.push(handler);
        
        return handler;
    }
    
    function construct()
    {
        m_Interval = setInterval(CheckHash, 25);
    }
    
    function CheckHash()
    {
        // return if there's no change since the last check
        if(document.location.hash == m_Hash)
            return;
        
        m_Hash = document.location.hash;
        ParseHash(m_Hash.substring(1));
    }
    
    function GetHandlerWithName(name)
    {
        for(var i = 0; i < m_Handlers.length; i++) {
            if(m_Handlers[i].GetName() == name)
                return m_Handlers[i];
        }
        
        return null;
    }
    
    function ParseHash(hash)
    {
        var pairs = hash.split(';');
        
        for(var i = 0; i < m_Handlers.length; i++)
            m_Handlers[i].ClearParams();
        
        for(var i = 0; i < pairs.length; i++) {
            // get index of first '=' character to split
            // the string into name/value parts
            var tmp = pairs[i].indexOf('=');
            if(tmp == -1)
                continue;
                
            var name_part = pairs[i].substring(0, tmp);
            var value_part = pairs[i].substring(tmp + 1);
            
            var name = name_part.split('_');
            if(name.length != 2)
                continue;
                
            var handler = GetHandlerWithName(name[0]);
            if(handler == null)
                continue;

            handler.SetParamValue(name[1], unescape(value_part));
        }
        
        for(var i = 0; i < m_Handlers.length; i++)
            m_Handlers[i].DoCallback();
    }
    
    this.UpdateHash = function()
    {
        var hash = "";
        
        for(var i = 0; i < m_Handlers.length; i++) {
            var tmp = m_Handlers[i].BuildParamList();
            
            if(hash.length > 0 && tmp.length > 0)
                hash += ";";
                
            hash += tmp;
        }
        
        document.location.hash = hash;
    }
    
    construct();
}

var Nav = new Navigation();


