// GLIG - keyboard shortcuts JavaScript functions
//
// Shortcut functions borrowed from this useful page:
//    http://www.openjs.com/scripts/events/keyboard_shortcuts

//==============================================================
// Shortcuts :: glig.shortcuts
//==============================================================

var glig       = (glig ? glig : function() {});
glig.shortcuts = (glig.shortcuts ? glig.shortcuts : function() {});

glig.shortcuts.all_shortcuts = { };

glig.shortcuts.shift_nums = { };
glig.shortcuts.special_keys = { };

glig.shortcuts.initialize = function()
{
    if(glig.isset(glig.shortcuts.shift_nums))
        return;

    glig.shortcuts.shift_nums =
    {
        "`" : "~", "1" : "!", "2" : "@", "3" : "#", "4" : "$", "5" : "%",
        "6" : "^", "7" : "&", "8" : "*", "9" : "(", "0" : ")", "-" : "_",
        "=" : "+", ";" : ":", "'" : "\"", "," : "<", "." : ">", "/" : "?",
        "\\" : "|"
    };

    glig.shortcuts.special_keys =
    {
        "esc":27, "escape":27, "tab":9, "space":32, "return":13, "enter":13, "backspace":8,
        "scrolllock":145, "scroll_lock":145, "scroll":145, "capslock":20, "caps_lock":20, "caps":20,
        "numlock":144, "num_lock":144, "num":144, 
        "pause":19, "break":19,
        "insert":45, "home":36, "delete":46, "end":35,
        "pageup":33, "page_up":33, "pu":33,
        "pagedown":34, "page_down":34, "pd":34,
        "left":37, "up":38, "right":39, "down":40,
        "f1":112, "f2":113, "f3":114, "f4":115, "f5":116, "f6":117,
        "f7":118, "f8":119, "f9":120, "f10":121, "f11":122, "f12":123
    };
}

glig.shortcuts.add = function(combination, callback, options)
{
    glig.shortcuts.initialize();

    if(!options)
        options = { };

    options["type"]      = glig.arrvar(options, "type", "keydown"); 
    options["propagate"] = glig.arrvar(options, "propagate", false); 
    options["disable_in_input"] = glig.arrvar(options, "disable_in_input", false); 
    options["target"]    = glig.arrvar(options, "target", document); 
    options["keycode"]   = glig.arrvar(options, "keycode", false); 

    var target = glig.resolve_target(options["target"]);

    combination = combination.toLowerCase();

    var func = function(e)
    {
        e = e || window.event;
            
        if(options["disable_in_input"])
        {
            var element;

            if(e.target)
                element = e.target;
            else if(e.srcElement)
                element = e.srcElement;

            if(element.nodeType==3)
                element = element.parentNode;

            if(element.tagName == "INPUT" || element.tagName == "TEXTAREA")
                return;
        }
    
        if(e.keyCode)
            code = e.keyCode;
        else if (e.which)
            code = e.which;

        var character = String.fromCharCode(code).toLowerCase();
            
        if(code == 188)
            character = ",";
        if(code == 190)
            character = ".";
    
        var keys = combination.split("+");
        var kp = 0;

        for(var i = 0; k = keys[i], i < keys.length; i++)
        {
            if(k == "ctrl" || k == "control")
            {
                kp += e.ctrlKey ? 1 : 0;
            }
            else if(k == "shift")
            {
                kp += e.shiftKey ? 1 : 0;
            }
            else if(k == "alt")
            {
                kp += e.altKey ? 1 : 0;
            }
            else if(k == "meta")
            {
                kp += e.metaKey ? 1 : 0;
            }
            else if(k.length > 1)
            {
                if(glig.shortcuts.special_keys[k] == code)
                    kp++;
            }
            else if(options["keycode"])
            {
                if(options["keycode"] == code)
                    kp++;
            }
            else
            {
                if(character == k)
                {
                    kp++;
                }
                else
                {
                    if(glig.shortcuts.shift_nums[character] && e.shiftKey)
                    {
                        character = glig.shortcuts.shift_nums[character]; 

                        if(character == k)
                            kp++;
                    }
                }
            }
        }

        if(kp == keys.length)
        {
            callback(e);
    
            if(!options["propagate"])
            {
                e.cancelBubble = true;
                e.returnValue = false;
    
                if (e.stopPropagation)
                {
                    e.stopPropagation();
                    e.preventDefault();
                }
                return false;
            }
        }
    }

    glig.shortcuts.all_shortcuts[combination] =
    {
        "callback": func, 
        "target":   target, 
        "event":    options["type"]
    };

    if(target.addEventListener)
        target.addEventListener(options["type"], func, false);
    else if(target.attachEvent)
        target.attachEvent("on" + options["type"], func);
    else
        target["on" + options["type"]] = func;
}

glig.shortcuts.remove = function(combination)
{
    combination = combination.toLowerCase();

    var binding = glig.shortcuts.all_shortcuts[combination];

    delete(glig.shortcuts.all_shortcuts[combination])

    if(!binding)
        return;

    var type     = binding["event"];
    var target   = binding["target"];
    var callback = binding["callback"];

    if(target.detachEvent)
        target.detachEvent("on" + type, callback);
    else if(target.removeEventListener)
        target.removeEventListener(type, callback, false);
    else
        target["on" + type] = false;
}
