
ipcRenderer.on('data-message' , function(event , data){ 
    //Can Message
    if (data[2] == 0xCA) {
        updateSIMMessage(data);
    }
});

var devices = [];

var updateSIMMessage = function(data)
{
    //Flow Device
    var env = (data[13] + data[14]*256 + data[15]*256*256 + data[16]*256*256*256);
    var bytes = [];
    for (var i = 0; i < 8; i++) {
        bytes[i] = data[i + 4];
    }

    //console.log({env: env, data: bytes});
    for (var i = 1; i <= 35; i++) {
        if (updateDevice(env, bytes, i)) break;
    }
}

var updateDevice = function(env, data, idx)
{
    if (devices[idx - 1]["POWER"] == 1) {
        if (env == 0 && data[1] == 0) return updateDevice_ENV0_P0(env, data, idx);
        if (env == 0 && data[1] == 1) return updateDevice_ENV0_P1(env, data, idx);
        if (env == 0 && data[1] == 2) return updateDevice_ENV0_P2(env, data, idx);

        if (env == 3 && data[1] == 0) return updateDevice_ENV3_P0(env, data, idx);
        if (env == 3 && data[1] == 1) return updateDevice_ENV3_P1(env, data, idx);
        if (env == 3 && data[1] == 2) return updateDevice_ENV3_P2(env, data, idx);

        if (env == 4 && data[1] == 0) return updateDevice_ENV4_P0(env, data, idx);
        if (env == 4 && data[1] == 1) return updateDevice_ENV4_P1(env, data, idx);
        if (env == 4 && data[1] == 2) return updateDevice_ENV4_P2(env, data, idx);

        if (env > 10 && env < 256 && data[1] == 0) return updateDevice_ENV10_256_P0(env, data, idx);

        if (env >= 300 && env <= 3000 && data[1] == 0) return updateDevice_ENV300_3000_P0(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 1) return updateDevice_ENV300_3000_P1(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 2) return updateDevice_ENV300_3000_P2(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 3) return updateDevice_ENV300_3000_P3(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 4) return updateDevice_ENV300_3000_P4(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 5) return updateDevice_ENV300_3000_P5(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 6) return updateDevice_ENV300_3000_P6(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 7) return updateDevice_ENV300_3000_P7(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 8) return updateDevice_ENV300_3000_P8(env, data, idx);
        if (env >= 300 && env <= 3000 && data[1] == 9) return updateDevice_ENV300_3000_P9(env, data, idx);
    }
    return false;
}

var updateDevice_ENV0_P0 = function(env, data, idx)
{
    //Do nothing
    return false;
}

var updateDevice_ENV0_P1 = function(env, data, idx)
{
    devices[idx - 1]["BASE_NUMBER"] = data[4];
    devices[idx - 1]["CONFIG_BASE_NUM"] = 1;
    return false;
}

var updateDevice_ENV0_P2 = function(env, data, idx)
{
    if (data[0] == (devices[idx - 1]["BASE_NUMBER"] + devices[idx - 1]["DEVICE_ID"])) {
        if (data[6] == 6) devices[idx - 1]["RXD"] = data[2] + (data[3]*256);
        if (data[6] == 7) {
            devices[idx - 1]["TXD"] = data[2] + (data[3]*256);
            devices[idx - 1]["CONFIG_INIT"] = 1;
            sendDevice_ConfigStatus(idx, 0);
        }
        return true;
    }
    return false;
}

var updateDevice_ENV3_P0 = function(env, data, idx)
{
    if (data[0] == (devices[idx - 1]["BASE_NUMBER"] + devices[idx - 1]["DEVICE_ID"])) {
        return updateDevice_CONF_C(env, data, idx);
    } else {
        var trigger = Math.floor(data[2]/8)%8;
        if (trigger == 5) {
            updateDevice_CONF_Reset(idx);
        }
        trigger = Math.floor(data[2]/128)%2;
        if (trigger == 1) {
            updateDevice_CONF_Enter(idx);
        }
        updateDevice_CONF_Respond(env, data, idx);
        return false;
    }
}

var updateDevice_CONF_C = function(env, data, idx)
{
    var trigger = Math.floor(data[2]/128)%2;
    if (trigger == 1) {
        updateDevice_CONF_Enter(idx);
    }
    trigger = Math.floor(data[2]/4)%2;
    if (trigger == 1) {
        sendDevice_ConfigStatus(idx, 0);
        return false;
    }
    return false;
}

var updateDevice_CONF_Reset = function(idx)
{
    devices[idx - 1]["TXD"] = 0;
    devices[idx - 1]["RXD"] = 0;
    devices[idx - 1]["BASE_NUMBER"] = 0;
    devices[idx - 1]["DEVICE_ID"] = 0;
    devices[idx - 1]["CONFIG_MODE"] = 0;
    devices[idx - 1]["CONFIG_INIT"] = 0;
    devices[idx - 1]["CONFIG_REPLIED"] = 0;
    devices[idx - 1]["CONFIG_BASE_NUM"] = 0;
    devices[idx - 1]["CONFIG_DEVICE_NUM"] = 0;
    devices[idx - 1]["FLOW_TARGET"] = 0;
    devices[idx - 1]["FLOW_ACTUAL"] = 1000;
    devices[idx - 1]["VARIABLES_1"] = 100;
    devices[idx - 1]["VARIABLES_2"] = 100;
    devices[idx - 1]["VARIABLES_3"] = 100;
    devices[idx - 1]["GOLDEN_NUMBER"] = 0;
    devices[idx - 1]["ENGAGE"] = 0;
    devices[idx - 1]["ENGAGED"] = 0;
    devices[idx - 1]["MANUAL"] = 0;
    devices[idx - 1]["PWM"] = 0;
    devices[idx - 1]["RPM"] = 100;
    devices[idx - 1]["VOLTAGE"] = 120;
    devices[idx - 1]["AMP"] = 0;
    devices[idx - 1]["WATER"] = 0;
    devices[idx - 1]["ERROR"] = 0;
    return false;
}

var updateDevice_Init = function(idx)
{
    var type = 0xA5
    if (idx >= 33 && idx <= 34) type = 0xFC;
    else if (idx == 35) type = 0xC7;

    devices[idx - 1] = {
        "TXD":0,
        "RXD":0,
        "BASE_NUMBER":0,
        "DEVICE_ID":0,
        "CONFIG_MODE":0,
        "CONFIG_INIT":0,
        "CONFIG_REPLIED":0,
        "CONFIG_BASE_NUM":0,
        "CONFIG_DEVICE_NUM":0,
        "FLOW_TARGET":0,
        "FLOW_ACTUAL":0,
        "TYPE":type,
        "VARIABLES_1":100,
        "VARIABLES_2":0,
        "VARIABLES_3":0,
        "GOLDEN_NUMBER":0,
        "ENGAGED":0,
        "MANUAL":0,
        "RPM":100,
        "PWM":0,
        "VOLTAGE":0,
        "AMP":0,
        "WATER":0,
        "ERROR":0,
        "POWER":0,
        "LV_G":0,
        "LV_R":0,
    }
    return false;
}

var updateDevice_CONF_Enter = function(idx)
{
    updateDevice_CONF_Reset(idx);
    devices[idx - 1]["CONFIG_MODE"] = 1;
}

var updateDevice_CONF_Exit = function(env, data, idx)
{
    devices[idx - 1]["CONFIG_MODE"] = 0;
}

var updateDevice_CONF_E = function(env, data, idx)
{
    var trigger = Math.floor(data[2]/64)%4;
    if (trigger == 1) {
        updateDevice_CONF_Exit(idx);
    } else if (trigger == 3) {
        updateDevice_CONF_Enter(idx);
    }
    return false;
}

var updateDevice_CONF_Respond = function(env, data, idx)
{
    var trigger = Math.floor(data[2])%2;
    if (trigger == 1 && devices[idx - 1]["CONFIG_INIT"] == 0) {
        sendDevice_ConfigStatus(idx, 0);
        return false;
    }
}

var updateDevice_ENV3_P1 = function(env, data, idx)
{
    //Do nothing
    return false;
}

var updateDevice_ENV3_P2 = function(env, data, idx)
{
    if (devices[idx - 1]["CONFIG_REPLIED"] == 1 && devices[idx - 1]["CONFIG_INIT"] == 0 && devices[idx - 1]["CONFIG_MODE"] == 1) {
        devices[idx - 1]["DEVICE_ID"] = data[2];
        devices[idx - 1]["CONFIG_DEVICE_NUM"] = 1;
        if (devices[idx - 1]["CONFIG_BASE_NUM"] == 1) sendDevice_MayorsMessage(idx);
        return true;
    }
    return false;
}

var updateDevice_ENV4_P0 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV4_P1 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV4_P2 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV10_256_P0 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV300_3000_P0 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV300_3000_P1 = function(env, data, idx)
{
    var trigger = Math.floor(data[4]/8)%2;
    if (trigger == 1) {
        //Engaged
        devices[idx - 1]["ENGAGED"] = Math.floor(data[4]/2)%2;
    }
    trigger = Math.floor(data[4]/4)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["FLOW_TARGET"] = data[2] + (data[3]*256);
    }
    trigger = Math.floor(data[4]/16)%2;
    if (trigger == 1) {
        //Flow reply
        sendDevice_FlowReply(idx);
    }
}

var updateDevice_ENV300_3000_P2 = function(env, data, idx)
{
    devices[idx - 1]["GOLDEN_NUMBER"] = data[2] + (data[3]*256) + (data[4]*256*256) + (data[5]*256*256*256) + (data[6]*256*256*256*256);
}

var updateDevice_ENV300_3000_P3 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV300_3000_P4 = function(env, data, idx)
{
    var trigger = Math.floor(data[4]/8)%2;
    if (trigger == 1) {
        //Engaged
        devices[idx - 1]["ENGAGED"] = Math.floor(data[4]/2)%2;
    }
    trigger = Math.floor(data[4]/4)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["PRESSURE_TARGET"] = data[2] + (data[3]*256);
    }
    trigger = Math.floor(data[4]/16)%2;
    if (trigger == 1) {
        //Flow reply
        sendDevice_FCReply(idx);
    }
}

var updateDevice_ENV300_3000_P5 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV300_3000_P6 = function(env, data, idx)
{
    //Do nothing
    return true;
}

var updateDevice_ENV300_3000_P7 = function(env, data, idx)
{
    var trigger = Math.floor(data[4]/8)%2;
    if (trigger == 1) {
        //Engaged
        devices[idx - 1]["ENGAGED"] = Math.floor(data[4]/2)%2;
    }
    trigger = Math.floor(data[4]/4)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["VARIABLES_1"] = data[2] + (data[3]*256) + (data[5]*256*256);
    }
    trigger = Math.floor(data[4]/32)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["VARIABLES_2"] = data[6] + (data[7]*256);
    }
    trigger = Math.floor(data[4]/128)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["MANUAL"] = Math.floor(data[4]/64)%2;
    }
    trigger = Math.floor(data[4]/16)%2;
    if (trigger == 1) {
        //Flow reply
        sendDevice_HydrReply(idx);
    }
}

var updateDevice_ENV300_3000_P8 = function(env, data, idx)
{
    var trigger = Math.floor(data[4]/4)%2;
    if (trigger == 1) {
        //Flow
        devices[idx - 1]["PWM"] = data[2];
    }
}

var sendDevice_ConfigStatus = function(idx, push_button)
{
    var data = [];
    if (devices[idx - 1]["CONFIG_INIT"] == 1) {
        data[0] = (devices[idx - 1]["BASE_NUMBER"] + devices[idx - 1]["DEVICE_ID"]);
    } else {
        data[0] = 0x00;
    }
    data[1] = 0x01;     //Page 1

    var data_2 = 0x00;
    data_2 += (devices[idx - 1]["CONFIG_INIT"]%2);
    data_2 += ((push_button%2)*2);
    data[2] = data_2;

    data[3] = devices[idx - 1]["TYPE"];
    data[4] = 0x00;
    data[5] = 0x00;
    data[6] = 0x00;
    data[7] = 0x00;

    sendMessage(0x03, data);
}

var sendDevice_MayorsMessage = function(idx)
{
    var data = [];
    data[0] = 0x00;
    data[1] = 0x01;
    data[2] = 0x00;
    data[3] = 0x01;
    data[4] = 0x00;
    data[5] = 0x01;
    data[6] = devices[idx - 1]["TYPE"];
    data[7] = 0x00;

    sendMessage((devices[idx - 1]["DEVICE_ID"] + devices[idx - 1]["BASE_NUMBER"]), data);
}

var sendDevice_FlowReply = function(idx)
{
    var data = [];
    data[0] = 0x00;
    data[1] = 0x00;
    data[2] = (devices[idx - 1]["FLOW_ACTUAL"]%256);
    data[3] = Math.floor(devices[idx - 1]["FLOW_ACTUAL"]/(256))%256;

    var data_4 = 0x00;
    data_4 += (devices[idx - 1]["ERROR"]%2);
    data_4 += ((devices[idx - 1]["ENGAGED"]%2)*2);
    data_4 += ((devices[idx - 1]["AMP"]%2)*64);
    data_4 += ((devices[idx - 1]["WATER"]%2)*128);
    data[4] = data_4;
    data[5] = 0x00;
    data[6] = 0x00;
    data[7] = devices[idx - 1]["VOLTAGE"];

    sendMessage(devices[idx - 1]["TXD"], data);
}

var sendDevice_FCReply = function(idx)
{
    var data = [];
    data[0] = 0x00;
    data[1] = 0x03;
    data[2] = devices[idx - 1]["VARIABLES_1"]%256;
    data[3] = Math.floor(devices[idx - 1]["VARIABLES_1"]/(256))%256;

    var data_4 = 0x00;
    data_4 += (devices[idx - 1]["ERROR"]%2);
    data_4 += ((devices[idx - 1]["ENGAGE"]%2)*2);
    data_4 += 4;
    data_4 += 8;
    data_4 += ((devices[idx - 1]["AMP"]%2)*64);
    data_4 += ((devices[idx - 1]["WATER"]%2)*128);
    data[4] = data_4;
    data[5] = devices[idx - 1]["VARIABLE_2"]%256;
    data[6] = Math.floor(devices[idx - 1]["VARIABLE_2"]/(256))%256;
    data[7] = devices[idx - 1]["VOLTAGE"];

    sendMessage(devices[idx - 1]["TXD"], data);
}

var sendDevice_HydrReply = function(idx)
{
    var data = [];
    data[0] = 0x00;
    data[1] = 0x06;
    data[2] = 0x00;
    data[3] = devices[idx - 1]["AMP"];

    var data_4 = 0x00;
    data_4 += (devices[idx - 1]["ERROR"]%2);
    data_4 += ((devices[idx - 1]["ENGAGED"]%2)*2);
    data_4 += ((devices[idx - 1]["WATER"]%2)*128);
    data[4] = data_4;
    data[5] = devices[idx - 1]["RPM"];
    data[6] = Math.floor(devices[idx - 1]["RPM"]/(256));
    data[7] = devices[idx - 1]["VOLTAGE"];

    sendMessage(devices[idx - 1]["TXD"], data);
}

var sendMessage = function(env, data)
{
    var result = [0x3A];
    for (var i = 0 ; i < 8; i++) {
        result[i + 1] = data[i];
    }
    result[9] = 8;
    result[10] = Math.floor(env/(256*256))%256;
    result[11] = Math.floor(env/(256*256*256))%256;
    result[12] = Math.floor(env)%256;
    result[13] = Math.floor(env/(256))%256;
    result[14] = 13;
    //console.log(result);
    var new_result = splitArray(result);
    ipcRenderer.send('can-message', new_result);
}

var power_device = function(idx)
{
    var object = document.getElementById("diag-sim-dev-power-" + idx);

    if (object == null) return;
    if (object.className == "ai-cell ai-cell-danger") {
        object.innerText = "ON";
        object.className = "ai-cell ai-cell-success";
        devices[idx - 1]["POWER"] = 1;
    } else {
        object.innerText = "OFF";
        object.className = "ai-cell ai-cell-danger";
        devices[idx - 1]["POWER"] = 0;
    }
}

var keypad = function(key, idx)
{
    if (devices[idx - 1]["CONFIG_MODE"] == 1 && devices[idx - 1]["CONFIG_INIT"] == 0 && devices[idx - 1]["CONFIG_REPLIED"] == 0) {
        devices[idx - 1]["CONFIG_REPLIED"] = 1;
        sendDevice_ConfigStatus(idx, 1);
    }
}

var light_invert = function(light, idx)
{
    if (light == 1) {
        var object = document.getElementById("diag-sim-dev-red-led-" + idx);

        if (object == null) return;

        if (object.className == "ai-cell ai-cell-danger") {
            object.className = "ai-cell ai-cell-secondary-1";
        } else {
            object.className = "ai-cell ai-cell-danger";
        }
    } else {
        var object = document.getElementById("diag-sim-dev-green-led-" + idx);

        if (object == null) return;

        if (object.className == "ai-cell ai-cell-success") {
            object.className = "ai-cell ai-cell-secondary-1";
        } else {
            object.className = "ai-cell ai-cell-success";
        }
    }
}

var light_switch = function(light, mode, idx)
{
    if (light == 1) {
        var object = document.getElementById("diag-sim-dev-red-led-" + idx);

        if (object == null) return;

        if (mode == 0) {
            object.className = "ai-cell ai-cell-secondary-1";
        } else {
            object.className = "ai-cell ai-cell-danger";
        }
    } else {
        var object = document.getElementById("diag-sim-dev-green-led-" + idx);

        if (object == null) return;

        if (mode == 0) {
            object.className = "ai-cell ai-cell-secondary-1";
        } else {
            object.className = "ai-cell ai-cell-success";
        }
    }
}

setInterval(function() {
    //Lights
    for (var i = 1; i <= 35; i++) {
        if (devices[i - 1]["LV_G"] == 0) light_switch(0, 0, i);
        else if (devices[i - 1]["LV_G"] == 1) light_invert(0, i);
        else if (devices[i - 1]["LV_G"] == 3) light_switch(0, 1, i);

        if (devices[i - 1]["LV_R"] == 0) light_switch(1, 0, i);
        else if (devices[i - 1]["LV_R"] == 1) light_invert(1, i);
        else if (devices[i - 1]["LV_R"] == 3) light_switch(1, 1, i);
    }
}, 500);

setInterval(function() {
    //Flow control
    for (var i = 1; i <= 32; i++) {
        if (devices[i - 1]["POWER"] == 1) {
            devices[i - 1]["FLOW_ACTUAL"] = devices[i - 1]["FLOW_TARGET"] + Math.floor(Math.random()*200) - 100;
        }
    }
    for (var i = 1; i <= 35; i++) {
        //Light mode
        if (devices[i - 1]["POWER"] == 0) {
            devices[i - 1]["LV_G"] = 0;
            devices[i - 1]["LV_R"] = 0;
        } else {
            if (devices[i - 1]["CONFIG_MODE"] == 0) {
                if (devices[i - 1]["CONFIG_INIT"]) {
                    devices[i - 1]["LV_G"] = 3;
                    devices[i - 1]["LV_R"] = 0;
                } else {
                    devices[i - 1]["LV_G"] = 2;
                    devices[i - 1]["LV_R"] = 0;
                }
            } else {
                if (devices[i - 1]["CONFIG_INIT"]) {
                    devices[i - 1]["LV_G"] = 0;
                    devices[i - 1]["LV_R"] = 3;
                } else if (devices[i - 1]["CONFIG_REPLIED"]) {
                    devices[i - 1]["LV_G"] = 0;
                    devices[i - 1]["LV_R"] = 1;
                } else {
                    devices[i - 1]["LV_G"] = 0;
                    devices[i - 1]["LV_R"] = 2;
                }
            }
        }
        //Lights
        if (devices[i - 1]["LV_G"] == 2) light_invert(0, i);
        if (devices[i - 1]["LV_R"] == 2) light_invert(1, i);
    }
}, 100);

var splitArray = function(arr)
{
    var new_arr = "";
    new_arr += String.fromCharCode(0x7F);
    for (var i = 0; i < arr.length; i++) {
        new_arr += String.fromCharCode(Math.floor(arr[i]/16)%16 + 0x30);
        new_arr += String.fromCharCode(arr[i]%16 + 0x30);
    }
    return new_arr;
}

var power_on_init = function()
{
    for (var i = 1; i <= 20; i++) {
        power_device(i);
    }
    for (var i = 33; i <= 34; i++) {
        power_device(i);
    }
    power_device(35);
}

for (var i = 1; i <= 35; i++) {
    updateDevice_Init(i);
}

power_on_init();

var FCUpdateEngage = function(engaged)
{
    var idx = 33;
    if (engaged != devices[idx]["ENGAGE"]) {
        devices[idx]["ENGAGE"] = engaged;
        sendDevice_FCReply(idx);
    }
}