var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");

var TrayHotKey = {
    _ID: null,
    _tooltipID: null,
    _popup: null,
    _anchor: null,
    decKeyCode: KeyboardEvent.DOM_VK_LEFT,
    _decModifier: 0x1,
    get decModifier () {
        return this._decModifier;
    },
    set decModifier (modifiers) {
        this._decModifier = this.split(modifiers);
    },
    incKeyCode: KeyboardEvent.DOM_VK_RIGHT,
    _incModifier: 0x1,
    get incModifier () {
        return this._incModifier;
    },
    set incModifier (modifiers) {
        this._incModifier = this.split(modifiers);
    },
    split: function (modifiers) {
        modifiers = modifiers.split(/\s+/);
        if (modifiers.length == 0)
            return 0;
        let modifier = 0x0;
        modifiers.forEach(function (item, index, array) {
            if (item == "alt")
                modifier |= 1;
            else if (item == "control" || item == "ctrl")
                modifier |= 2;
            else if (item == "meta")
                modifier |= 4;
            else if (item == "shift")
                modifier |= 8;
        });
        return modifier;
    }
};

TrayHotKey.observe = function (aSubject, aTopic, aData) {
    if (aTopic != "nsPref:changed") return;
    aSubject.QueryInterface(Ci.nsIPrefBranch)
            .QueryInterface(Ci.nsIPrefBranch2);
    switch (aData) {
        case "opacityDecKey" :
            this.decKeyCode = KeyboardEvent["DOM_" + aSubject.getCharPref(aData)];
            break;
        case "opacityDecModifiers" :
            this.decModifier = aSubject.getCharPref(aData);
            break;
        case "opacityIncKey" :
            this.incKeyCode = KeyboardEvent["DOM_" + aSubject.getCharPref(aData)];
            break;
        case "opacityIncModifiers" :
            this.incModifier = aSubject.getCharPref(aData);
            break;
        case "setOpacity_bool" :
            let enabled = aSubject.getBoolPref(aData);
            this._ID.disabled = !enabled;
            if (enabled)
                window.addEventListener("keypress", this, false);
            else            
                window.removeEventListener("keypress", this, false);
            break;
    }
};

TrayHotKey.init = function () {
    let aPrefs  = Services.prefs;
    this.branch = aPrefs.getBranch("extensions.TrayHotKey.");
    let aString  = Services.strings;
    let proSrc = "chrome://TrayHotKey/locale/overlay.properties";
    let bundle = aString.createBundle(proSrc);
    this.opacityDisabled = bundle.GetStringFromName("opacityDisabled");
    this._ID = document.getElementById("TrayHotKey-opacity");
    this._ID.value = this.branch.getIntPref("opacity_int");
    this._tooltipID = document.getElementById("TrayHotKey-opacity_Num");
    this._tooltipID.label = String(this._ID.value * 100 / 255 | 0) + '%';

    let opacityBool = this.branch.getBoolPref("setOpacity_bool");
    this.decKeyCode = KeyboardEvent["DOM_" + this.branch.getCharPref("opacityDecKey")];
    this.decModifier = this.branch.getCharPref("opacityDecModifiers");
    this.incKeyCode = KeyboardEvent["DOM_" + this.branch.getCharPref("opacityIncKey")];
    this.incModifier = this.branch.getCharPref("opacityIncModifiers");
    if (opacityBool) {
        window.addEventListener("keypress", this, false);
    }
    this.branch.QueryInterface(Ci.nsIPrefBranch2);
    this.branch.addObserver("", this, false);
};

TrayHotKey.crease = function (e) {
    var key = e.keyCode || e.which;
    var m = e.altKey | e.ctrlKey << 1 | e.metaKey << 2 | e.shiftKey << 3;
    if (key == this.decKeyCode && m == this.decModifier)
        var v = "decreasePage";
    else if (key == this.incKeyCode && m == this.incModifier)
        var v = "increasePage";
    else
        return;
    e.preventDefault();
    this._ID[v]();
    this._tooltipID.hidePopup();
    this.branch.setIntPref("opacity_int", this._ID.value);
};

TrayHotKey.onClick = function (e) {
    if (e.button == 0) {
        this._anchor = e.explicitOriginalTarget;
        //this.initPopup();
    } else if (e.button == this.branch.getIntPref("EventButton") && 
               this.branch.getBoolPref("ClickOpen")) {
        e.preventDefault();
        window.openDialog("chrome://TrayHotKey/content/options.xul",
                          "TrayHotKey", "chrome, dialog, modal, centerscreen");
    }
};

TrayHotKey.initPopup = function () {
    let that = this;
    /*
    this._popup = document.getElementById("TrayHotKey-ChangeTrayHotKey");
    this._popup.openPopup(this._anchor, "after_start", 0, 0, false, false);
    */
    let _opacity = this.branch.getIntPref("opacity_int");
    this._ID.value = _opacity;
    let opacityBool = this.branch.getBoolPref("setOpacity_bool");
    this._ID.setAttribute("movetoclick", opacityBool);
    if (!opacityBool) {
        this._ID.disabled = true;
        this._tooltipID.label = this.opacityDisabled;
        return;
    }
    this._tooltipID.label = String(_opacity * 100 / 255 | 0) + '%';
    this._ID.addEventListener("mousemove", function (e) {
        this.setUserData("screen", {screenX: e.screenX, screenY: e.screenY},
                         null);
        }, false
    );
    this._ID.addEventListener("change", that, false);
};

TrayHotKey.handleEvent = function (e) {
    if (e.type == "keypress") return this.crease(e);
    let aEvt = this._ID.getUserData("screen");
    this._tooltipID.label = String(this._ID.value * 100 / 255 | 0) + '%';
    if (this._tooltipID.state == "open")
        this._tooltipID.hidePopup();
    this._tooltipID.openPopupAtScreen(aEvt.screenX, aEvt.screenY, false);
    this.branch.setIntPref("opacity_int", e.explicitOriginalTarget.value);
};

TrayHotKey.unload = function () {
    let that = this;
    if (this._tooltipID)
        this._tooltipID.hidePopup();
    if (this._ID) {
        //this.branch.setIntPref("opacity_int", this._ID.value);
        this._ID.removeEventListener("change", that, false);
    }
};

window.addEventListener("load", function (e) {
    window.removeEventListener("load", arguments.callee, true);
    setTimeout(function (){
        var THK = Cc["@czcp.co.cc/TrayHotKey;1"].getService().wrappedJSObject;
        THK.initWIN();
        TrayHotKey.init();
    }, 1);
}, true);
