var Cc = Components.classes, Ci = Components.interfaces;
var Cu = Components.utils;

var windowsVersion = (function () {
    var wrk = Cc["@mozilla.org/windows-registry-key;1"]
                  .createInstance(Ci.nsIWindowsRegKey);
    wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
             "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
             wrk.ACCESS_READ
    );
    var wv = wrk.readStringValue("CurrentVersion");
    wrk.close();
    return wv;
})();

Cu.import("resource://gre/modules/Services.jsm");
var aConsole = Services.console;
// void logStringMessage(in wstring message);
var aString = Services.strings;
var proSrc  = "chrome://TrayHotKey/locale/options.properties";
var bundle  = aString.createBundle(proSrc);
var Bundle  = {};
Bundle.hotKeyEnabled   = bundle.GetStringFromName("hotKeyEnabled");
Bundle.hotKeyDisabled  = bundle.GetStringFromName("hotKeyDisabled");
Bundle.hotKeyRestart   = bundle.GetStringFromName("hotKeyRestart");
Bundle.hotKeyUndefined = bundle.GetStringFromName("hotKeyUndefined");

var aPrefs = Services.prefs;
var branch = aPrefs.getBranch("extensions.TrayHotKey.");

var hotKeyChange    = document.getElementById("hotKeyChange");
var opacityChange   = document.getElementById("opacityChange");
var transChange     = document.getElementById("transChange");
var hotKey_options  = document.getElementById("hotKey-options");
var hotKey          = document.getElementById("hotKey");
var winKey          = document.getElementById("winKey");
var minimizeToTray  = document.getElementById("minimizeToTray");
var closeToTray     = document.getElementById("closeToTray");
var alawysShowTray  = document.getElementById("alawysShowTray");
var minimizeToFm    = document.getElementById("minimizeToFm");
var opacity_options = document.getElementById("opacity-options");
var opacity         = document.getElementById("opacity");
var opacityNum      = document.getElementById("opacityNum");
var trans_options   = document.getElementById("trans-options");
var transHotKey     = document.getElementById("transHotKey");
var transWinKey     = document.getElementById("transWinKey");
var trans           = document.getElementById("trans");
var transTip        = document.getElementById("transTip");

const MOD_ALT     = 0x0001;
const MOD_CONTROL = 0x0002;
const MOD_SHIFT   = 0x0004;
const MOD_WIN     = 0x0008;
var VK = [];
VK[0x08] = 'BackSpace'; VK[0x09] = 'Tab'; VK[0x0C] = "Clear"; VK[0x0D] = 'Enter';
VK[0x10] = 'Shift'; VK[0x11] = 'Ctrl'; VK[0x12] = 'Alt'; VK[0x13] = 'Pause';
VK[0x1B] = 'Esc'; VK[0x20] = 'Space'; VK[0x21] = 'PageUp';
VK[0x22] = 'PageDown'; VK[0x23] = 'End'; VK[0x24] = 'Home'; VK[0x25] = 'Left';
VK[0x26] = 'Up'; VK[0x27] = 'Right'; VK[0x28] = 'Down'; VK[0x2D] = 'Ins';
VK[0x2E] = 'Del';// VK[0x5B] = 'LeftWindowsKey', VK[0x5C] = 'RightWindowsKey';
VK[0x5D] = 'Applications'; VK[0x6A] = 'num*'; VK[0x6B] = 'num+';
VK[0x6C] = 'Separator'; VK[0x6D] = 'num-'; VK[0x6E] = 'num.'; VK[0x6F] = 'num/';
//VK[0xBC] = ',', VK[0xBE] = '.', VK[0xBF] = '/', VK[0xC0] = '`';
//VK[0xDB] = '[', VK[0xDC] = '\\', VK[0xDD] = ']', VK[0xDE] = '\'';
//VK[0xBA] = ';' /* if keycode == 0x3b set VK[0xBA] */;
/*
for (let i = 0x30; i < 0x3A; ++i)
    VK[i] = String(i - 0x30);
for (let i = 0x41; i < 0x5B; ++i)
    VK[i] = String.fromCharCode(i);
*/
for (let i = 0x60; i < 0x6A; ++i)
    VK[i] = 'num' + (i - 0x60);
for (let i = 0x70; i < 0x88; ++i)
    VK[i] = 'F' + (i - 0x6F);

var THKUI = {
    _opacityTemp: null,
    _loadHKState: false,
    _loadTHKState: false
};

THKUI.load = function () {
    opacity_options.disabled = (windowsVersion < 6.0) ? true : false;
    if (opacity_options.disabled) {
        document.getElementById("extra-feature").hidden = true;
        opacity_options.checked = false;
        branch.setBoolPref("setOpacity_bool", false);
    }
    if (hotKey_options.checked)
        hotKeyChange.removeAttribute("disabled");
    else
        hotKeyChange.setAttribute("disabled", true);
    if (opacity_options.checked)
        opacityChange.removeAttribute("disabled");
    else
        opacityChange.setAttribute("disabled", true);
    if (trans_options.checked && opacity_options.checked)
        transChange.removeAttribute("disabled");
    else
        transChange.setAttribute("disabled", true);
    opacity.setAttribute("movetoclick", !opacity.disabled);
    trans.setAttribute("movetoclick", !trans.disabled && !opacity.disabled);

    hotKey.value = branch.getCharPref("keyCode_string");
    transHotKey.value = branch.getCharPref("transKeyCode_string");

    opacity.value = branch.getIntPref("opacity_int");
    opacityNum.valueNumber = opacity.value * 100 / 255 | 0;
    trans.value = branch.getIntPref("trans_int");
    transTip.value = (trans.value * 100 / 255 | 0).toString() + '%';

    hotKey.setUserData("keycode", branch.getIntPref("KeyCode"), null);
    hotKey.setUserData("hotkeychanged", false, null);
    transHotKey.setUserData("keycode", branch.getIntPref("TransKeyCode"), null);
    transHotKey.setUserData("hotkeychanged", false, null);
    //hotKey.placeholder = branch.getCharPref("keyCode_string");
    function checkStatus(target, status) {
        if (status) {
            target.tooltipText = Bundle.hotKeyEnabled;
        } else {
            target.tooltipText = Bundle.hotKeyDisabled;
        }
        target.setAttribute("hotkey", status);
    }
    let hotKeyStatus = branch.getBoolPref("HotKeyStatus");
    checkStatus(hotKey, hotKeyStatus);
    let transHotKeyStatus = branch.getBoolPref("TransStatus");
    checkStatus(transHotKey, transHotKeyStatus);

    this._opacityTemp = opacity.value;
    this._loadHKState = hotKey_options.checked;
    this._loadTHKState = trans_options.checked && opacity_options.checked;
}

THKUI.onAccept = function () {
    branch.setIntPref("opacity_int", opacity.value);
    branch.setIntPref("trans_int", trans.value);
    let _keyCode_ = hotKey.getUserData("keycode");
    let _transKeyCode_ = transHotKey.getUserData("keycode");

    //opacityNum.valueNumber = opacity.value * 100 / 255 | 0;

    if (_keyCode_ != branch.getIntPref("KeyCode")) {
        branch.setCharPref("keyCode_string", hotKey.value);
        branch.setIntPref("KeyCode", _keyCode_)
    }
    if (_transKeyCode_ != branch.getIntPref("TransKeyCode")) {
        branch.setCharPref("transKeyCode_string", transHotKey.value);
        branch.setIntPref("TransKeyCode", _transKeyCode_);
    }
}
THKUI.onCancel = function () {
}

THKUI.onHotKeyChange = function (e) {
    let emt = e.explicitOriginalTarget;
    let keyCode = e._keyCode;
    if (keyCode == 0x12 || keyCode == 0x11 || keyCode == 0x10
       || keyCode == 0x5B || keyCode == 0x5C) return;
    let alt = e.altKey ? MOD_ALT : 0;
    let ctrl = e.ctrlKey ? MOD_CONTROL : 0;
    let shift = e.shiftKey ? MOD_SHIFT : 0;
    let _VKModifiersTemp = alt | ctrl | shift;
    let _VKCodeTemp = (keyCode == 0x3B) ? 0xBA : keyCode;
    let kc = _VKCodeTemp << 16 | _VKModifiersTemp;
    emt.setUserData("keycode", kc, null);
    emt.setUserData("hotkeychanged", true, null);
    let keyChar = VK[_VKCodeTemp] ? VK[_VKCodeTemp] : (e.charCode ? String.fromCharCode(e.charCode) : null);
    emt.value = keyChar ? (e.altKey ? 'ALT + ' : '')
                        + (e.ctrlKey ? 'CTRL + ' : '')
                        + (e.shiftKey ? 'SHIFT + ' : '')
                        + keyChar
                        : Bundle.hotKeyUndefined;
}

hotKey.addEventListener("focus", function () {
    this.setUserData("keystring", this.value, null);
    this.readOnly = true;
    this.value = '';
}, false);
hotKey.addEventListener("blur", function () {
    let keycode = branch.getIntPref("KeyCode");
    let hotkeystatus = branch.getBoolPref("HotKeyStatus");
    let tooltipText = hotkeystatus ? Bundle.hotKeyEnabled
                                   : Bundle.hotKeyDisabled;
    if (this.value == '') {
        this.value = this.getUserData("keystring");
    } else {
        this.setUserData("keystring", this.value, null);
    }
    if (this.getUserData("keycode") == keycode && THKUI._loadHKState) {
        this.setAttribute("hotkey", hotkeystatus);
        this.tooltipText = tooltipText;
    } else {
        this.removeAttribute("hotkey");
        this.tooltipText = Bundle.hotKeyRestart;
    }
}, false);
hotKey.addEventListener("keydown", function (e) {
    e.preventDefault();
    let keycode = this.getUserData("keycode");
    winKey.checked ? (keycode |= MOD_WIN) : (keycode &= 0xFFFFFFF7);
    this._keyCode = e.keyCode;
    this.setUserData("keycode", keycode, null);
}, true);
hotKey.addEventListener("keypress", function (e) {
    e.preventDefault();
    e._keyCode = this._keyCode;
    THKUI.onHotKeyChange(e);
}, true);
opacity.addEventListener("change", function () {
    opacityNum.valueNumber = this.value * 100 / 255 | 0;
}, false);
opacityNum.addEventListener("input", function () {
    opacity.value = this.valueNumber * 255 / 100 | 0;
}, false);
opacityNum.addEventListener("change", function () {
    opacity.value = this.valueNumber * 255 / 100 | 0;
}, false);
trans.addEventListener("change", function () {
    transTip.value = (this.value * 100 / 255 | 0).toString() + '%';
}, false);
transHotKey.addEventListener("focus", function () {
    this.setUserData("keystring", this.value, null);
    this.readOnly = true;
    this.value = '';
}, false);
transHotKey.addEventListener("blur", function () {
    let keycode = branch.getIntPref("TransKeyCode");
    let transtatus = branch.getBoolPref("TransStatus");
    let tooltipText = transtatus ? Bundle.hotKeyEnabled
                                 : Bundle.hotKeyDisabled;
    if (this.value == '')
        this.value = this.getUserData("keystring");
    else
        this.setUserData("keystring", this.value, null);
    if (this.getUserData("keycode") == keycode && THKUI._loadTHKState) {
        this.setAttribute("hotkey", transtatus);
        this.tooltipText = tooltipText;
    } else {
        this.removeAttribute("hotkey");
        this.tooltipText = Bundle.hotKeyRestart;
    }
}, false);
transHotKey.addEventListener("keydown", function (e) {
    e.preventDefault();
    let keycode = this.getUserData("keycode");
    transWinKey.checked ? (keycode |= MOD_WIN) : (keycode &= 0xFFFFFFF7);
    this._keyCode = e.keyCode;
    this.setUserData("keycode", keycode, null);
}, true);
transHotKey.addEventListener("keypress", function (e) {
    e.preventDefault();
    e._keyCode = this._keyCode;
    THKUI.onHotKeyChange(e);
}, true);
hotKey_options.addEventListener("CheckboxStateChange", function () {
    if (this.checked) {
        if (!THKUI._loadHKState)
            hotKey.removeAttribute("hotkey");
        hotKeyChange.removeAttribute("disabled");
    } else {
        hotKeyChange.setAttribute("disabled", true);
    }
}, false);
opacity_options.addEventListener("CheckboxStateChange", function () {
    if (this.checked) {
        if (!THKUI._loadTHKState)
            transHotKey.removeAttribute("hotkey");
        opacityChange.removeAttribute("disabled");
    } else {
        opacityChange.setAttribute("disabled", true);
    }
    if (trans_options.checked && this.checked)
        transChange.removeAttribute("disabled");
    else
        transChange.setAttribute("disabled", true);
    opacity.setAttribute("movetoclick", !opacity.disabled);
    trans.setAttribute("movetoclick", !trans.disabled && !opacity.disabled);
}, false);
trans_options.addEventListener("CheckboxStateChange", function () {
    if (this.checked) {
        if (!THKUI._loadTHKState)
            transHotKey.removeAttribute("hotkey");
        transChange.removeAttribute("disabled");
    } else {
        transChange.setAttribute("disabled", true);
    }
    trans.setAttribute("movetoclick", !trans.disabled && !opacity.disabled);
}, false);
winKey.addEventListener("CheckboxStateChange", function () {
    let keycode = hotKey.getUserData("keycode");
    let hotkeychanged = hotKey.getUserData("hotkeychanged");
    let hotkey = hotKey.getAttribute("hotkey");
    this.checked ? (keycode |= MOD_WIN) : (keycode &= 0xFFFFFFF7);
    if (hotkey == '' && keycode == branch.getIntPref("KeyCode")
            && THKUI._loadHKState)
        hotKey.setAttribute("hotkey", branch.getBoolPref("HotKeyStatus"));
    else
        hotKey.removeAttribute("hotkey");
    hotKey.setUserData("keycode", keycode, null);
}, false);
transWinKey.addEventListener("CheckboxStateChange", function () {
    let keycode = transHotKey.getUserData("keycode");
    let hotkey = transHotKey.getAttribute("hotkey");
    this.checked ? (keycode |= MOD_WIN) : (keycode &= 0xFFFFFFF7);
    if (hotkey == '' && keycode == branch.getIntPref("TransKeyCode")
            && THKUI._loadTHKState)
        transHotKey.setAttribute("hotkey", branch.getBoolPref("TransStatus"));
    else
        transHotKey.removeAttribute("hotkey");
    transHotKey.setUserData("keycode", keycode, null);
}, false);

window.addEventListener("load", function () { THKUI.load(); }, false);
