/* See license.txt for terms of usage */

define([
    "firebug/chrome/module",
    "firebug/lib/object",
    "firebug/firebug",
    "firebug/chrome/firefox",
    "firebug/firefox/customizeShortcuts",
],
function(Module, Obj, Firebug, Firefox, CustomizeShortcuts) {

// ********************************************************************************************* //
// Constants

Components.utils.import("resource://gre/modules/Services.jsm");

var KeyEvent = window.KeyEvent;

// ********************************************************************************************* //

/**
 * ShortcutsModel object implements keyboard shortcuts logic.
 */
Firebug.ShortcutsModel = Obj.extend(Module,
{
    dispatchName: "shortcuts",

    initializeUI: function()
    {
        if (FBTrace.DBG_SHORTCUTS)
            FBTrace.sysout("shortcuts.initializeUI; Shortcuts module initialization.");

        this.initShortcuts();
    },

    initShortcuts: function()
    {
        var branch = Services.prefs.getBranch("extensions.firebug.key.shortcut.");
        var shortcutNames = branch.getChildList("", {});

        // We need to touch keyset to apply keychanges without restart
        this.keysets = [];
        this.resetDisabledKeys();

        shortcutNames.forEach(this.initShortcut, this);

        this.keysets.forEach(function(keyset) {
            keyset.parentNode.insertBefore(keyset, keyset.nextSibling);
        });

        this.keysets = null;
    },

    initShortcut: function(element, index, array)
    {
        var branch = Services.prefs.getBranch("extensions.firebug.key.");
        var shortcut = branch.getCharPref("shortcut." + element);
        var tokens = shortcut.split(" ");
        var key = tokens.pop();
        var modifiers = tokens.join(",");

        var keyElem = document.getElementById("key_firebug_" + element);
        if (!keyElem)
        {
            // If key is not defined in xul, add it
            keyElem = document.createElement("key");
            keyElem.className = "fbOnlyKey";
            keyElem.id = "key_firebug_" + element;
            keyElem.command = "cmd_firebug_" + element;
            document.getElementById("mainKeyset").appendChild(keyElem);
        }

        // invalidAttr needed in case default shortcut uses key rather than keycode
        var attr = "key";
        var invalidAttr = "key";

        // Choose between key or keycode attribute
        if (key.length <= 1)
        {
            invalidAttr = "keycode";
        }
        else if (KeyEvent["DOM_"+key])
        {
            attr = "keycode";
        }
        else
        {
            // Only set valid keycodes
            return;
        }

        keyElem.setAttribute("modifiers", modifiers);
        keyElem.setAttribute(attr, key);
        keyElem.removeAttribute(invalidAttr);

        if (this.keysets.indexOf(keyElem.parentNode) == -1)
            this.keysets.push(keyElem.parentNode);

        // Modify shortcut for global key, if it exists
        var keyElem = Firefox.getElementById("key_firebug_" + element);
        if (!keyElem)
            return;

        if (FBTrace.DBG_SHORTCUTS)
        {
            FBTrace.sysout("Firebug.ShortcutsModel.initShortcut; global shortcut",
                {key: key, modifiers: modifiers, command: "cmd_firebug_" + element});
        }

        // Disable existing global shortcuts
        var selector = ":-moz-any(key[" + attr + "='" + key + "'], key[" + attr + "='" +
            key.toUpperCase() + "'])[modifiers='" + modifiers + "']" +
            ":not([id='key_firebug_" + element + "']):not([disabled='true'])";

        var existingKeyElements = keyElem.ownerDocument.querySelectorAll(selector);
        for (var i=existingKeyElements.length-1; i>=0; i--)
        {
            var existingKeyElement = existingKeyElements[i];
            existingKeyElement.setAttribute("disabled", "true");
            this.disabledKeyElements.push(existingKeyElement);
        }

        keyElem.setAttribute("modifiers", modifiers);
        keyElem.setAttribute(attr, key);
        keyElem.removeAttribute(invalidAttr);

        if (this.keysets.indexOf(keyElem.parentNode) == -1)
            this.keysets.push(keyElem.parentNode);
    },

    resetDisabledKeys: function()
    {
        if (this.disabledKeyElements)
        {
            for (var i=0; i<this.disabledKeyElements.length; i++)
            {
                var elem = this.disabledKeyElements[i];
                elem.removeAttribute("disabled");
            }
        }

        this.disabledKeyElements = [];
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // UI Commands

    customizeShortcuts: function()
    {
        // Open the "customize shortcuts" dialog.
        window.openDialog("chrome://firebug/content/firefox/customizeShortcuts.xul", "",
            "chrome,centerscreen,dialog,modal,resizable=yes", new CustomizeShortcuts());
    }
});

// ********************************************************************************************* //
// Registration

Firebug.registerModule(Firebug.ShortcutsModel);

return Firebug.ShortcutsModel;

// ********************************************************************************************* //
});

@@ -3371,16 +3371,429 @@
 ortcuts%0A
+        disableExistingShortcuts(keyElem.ownerDocument, attr, key, modifiers);%0A%0A        keyElem.setAttribute(%22modifiers%22, modifiers);%0A        keyElem.setAttribute(attr, key);%0A        keyElem.removeAttribute(invalidAttr);%0A%0A        if (this.keysets.indexOf(keyElem.parentNode) == -1)%0A            this.keysets.push(keyElem.parentNode);%0A    %7D,%0A%0A    disableExistingShortcuts: function(doc, attr, key, modifiers)%0A    %7B%0A
         
@@ -3969,37 +3969,18 @@
 (%5Bid
+*
 ='
-key_
 firebug
-_%22 + element + %22
 '%5D):
@@ -4039,37 +4039,19 @@
 ments = 
-keyElem.ownerDocument
+doc
 .querySe
@@ -4089,17 +4089,19 @@
 r (var i
-=
+ = 
 existing
@@ -4122,15 +4122,19 @@
 ngth
--
+ - 
 1; i
+ 
 %3E=
+ 
 0; i
@@ -4163,69 +4163,8 @@
     
-var existingKeyElement = existingKeyElements%5Bi%5D;%0A            
 exis
@@ -4177,16 +4177,20 @@
 yElement
+s%5Bi%5D
 .setAttr
@@ -4272,24 +4272,28 @@
 ngKeyElement
+s%5Bi%5D
 );%0A        %7D
@@ -4296,262 +4296,8 @@
    %7D
-%0A%0A        keyElem.setAttribute(%22modifiers%22, modifiers);%0A        keyElem.setAttribute(attr, key);%0A        keyElem.removeAttribute(invalidAttr);%0A%0A        if (this.keysets.indexOf(keyElem.parentNode) == -1)%0A            this.keysets.push(keyElem.parentNode);
 %0A   

Put disabling existing shortcuts into its own function (related to issue 6991)