var EXPORTED_SYMBOLS = ["onmessage", "postMessage"];
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;

Cu.import("resource://gre/modules/ctypes.jsm");

var THK = {};
THK.open = function (path) {
    this.lib = ctypes.open(path);
    this.init = this.lib.declare(
        "init", ctypes.winapi_abi, ctypes.void_t
    );
    this.initWin = this.lib.declare(
        "initWin", ctypes.winapi_abi, ctypes.void_t
    );
    this.initOpacity = this.lib.declare(
        "initOpacity", ctypes.winapi_abi, ctypes.bool,
        ctypes.bool,
        ctypes.unsigned_short,
        ctypes.bool,
        ctypes.unsigned_long
    );
    this.trayHotKey = this.lib.declare(
        "trayHotKey", ctypes.winapi_abi, ctypes.bool,
        ctypes.jschar.ptr,
        ctypes.jschar.array(256).array(),
        ctypes.uint8_t,
        ctypes.bool,
        ctypes.unsigned_long
    );
    this.setHotKey = this.lib.declare(
        "setHotKey", ctypes.winapi_abi, ctypes.bool,
        ctypes.uint8_t,
        ctypes.unsigned_long
    );
    this.setOpacity = this.lib.declare(
        "setOpacity", ctypes.winapi_abi, ctypes.void_t,
        ctypes.bool,
        ctypes.uint8_t,
        ctypes.int
    );
    this.setTray = this.lib.declare(
        "setTray", ctypes.winapi_abi, ctypes.void_t,
        ctypes.uint8_t,
        ctypes.bool
    );
    this.quit = this.lib.declare(
        "quit", ctypes.winapi_abi, ctypes.void_t
    );
    this.onWinTop = this.lib.declare(
        "onWinTop", ctypes.winapi_abi, ctypes.bool,
        ctypes.jschar.array()
    );
    this.setMinimizeToFm = this.lib.declare(
        "setMinimizeToFm", ctypes.winapi_abi, ctypes.void_t,
        ctypes.bool
    );
}

var that;
var onmessage = function (aMsg) {
    //const data = JSON.parse(aMsg.data);
    let data = aMsg;
    let state;
    let bit = 0x00;
    switch (data.name) {
        case "Init" :
            THK.open(data.value);
            THK.init();
            that = data.that;
            postMessage({"name": "InitEnd"});
            break;
        case "TrayHotKey" :
            let path = data.icoPath ? data.icoPath : '';
            //data.trayStr[4] = data.trayStr[4] ? data.trayStr : '';
            let str = ctypes.jschar.array(256).array()(data.trayStr);
            state = THK.trayHotKey(
                path, str, data.trayChecked, data.hotKeyChecked, data.keyCode
            );
            postMessage({"name": "HotKeyStatus", "value": state});
            break;
        case "InitWIN" :
            THK.initWin();
            postMessage({"name": "InitWINEND"});
            break;
        case "InitOpacity" :
            let value = data.opacityValue << 8 | data.transValue;
            state = THK.initOpacity(
                data.opacityChecked, value, data.transChecked, data.transKC
            );
            postMessage({"name": "TransStatus", "value": state});
            break;
        case "setHotKey_bool" :
            bit = 0x01;
            state = THK.setHotKey(bit, data.value);
            postMessage({"name": "HotKeyStatus", "value": state});
            break;
        case "KeyCode" :
            bit = 0x03;
            state = THK.setHotKey(bit, data.value);
            postMessage({"name": "HotKeyStatus", "value": state});
            break;
        case "setTrans_bool" :
            bit = 0x00;
            state = THK.setHotKey(bit, data.value);
            postMessage({"name": "TransStatus", "value": state});
            break;
        case "TransKeyCode" :
            bit = 0x02;
            state = THK.setHotKey(bit, data.value);
            postMessage({"name": "TransStatus", "value": state});
            break;
        case "setOpacity_bool" :
            THK.setOpacity(data.value, 255, true);
            bit = 0xFC;
            state = THK.setHotKey(bit, data.value);
            postMessage({"name": "TransStatus", "value": state});
            break;
        case "opacity_int" :
            THK.setOpacity(true, data.value, false);
            break;
        case "trans_int" :
            THK.setOpacity(false, data.value, false);
            break;
        case "alawysShowTray_bool" :
            THK.setTray(0x01, data.value);
            break;
        case "minimizeToTray_bool" :
            THK.setTray(0x02, data.value);
            break;
        case "closeToTray_bool" :
            THK.setTray(0x04, data.value);
            break;
        case "foreground" :
            THK.setTray(0x08, data.value);
            break;
        case "Quit" :
            THK.quit();
            setTimeout(function() {THK.lib.close();}, 10);
            break;
        case "WinTop" :
            return THK.onWinTop(data.value);
            break;
        case "minimizeToFm_bool" :
            THK.setMinimizeToFm(data.value);
            break;
    }
}

var postMessage = function (aMsg) {
    that.onmessage(aMsg);
}
