'use strict';

goog.provide('Blockly.Python.wificomms');
goog.require('Blockly.Python');

Blockly.Python['wificomms_setup'] = function(block) {
    let serial_setup = "Serial.begin(9600);";
    Blockly.Python.addSetup('serial_9600', serial_setup);
    return '';
};

Blockly.Python['wificomms_sendMsg'] = function(block) {
    var checkbit = "#define SOP '<'\n" +
        "#define EOP '>'\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_checkbit", checkbit);
    var datavar = Blockly.Python.variableDB_.getName(
        block.getFieldValue('dataVar'), Blockly.Variables.NAME_TYPE);
    var length = "sizeof(" + datavar + ")/sizeof(" + datavar + "[0])";
    var dataLength = length + "+2";
    var code = "unsigned char DataOut_[" + dataLength + "];\n" +
        "DataOut_[0]= SOP;\n" +
        "DataOut_[" + length + "+1]= EOP;\n" +
        "for (int i=0; i<" + length + ";i++) {\n" +
        "  DataOut_[i+1]=" + datavar + "[i];\n" +
        "}\n" +
        "Serial.write(DataOut_, " + dataLength + ");\n";
    return code;
};

Blockly.Python['wificomms_receiveMsg'] = function(block) {
    var checkbit = "#define SOP '<'\n" +
        "#define EOP '>'\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_checkbit", checkbit);
    var MsgReceiveStatus = "bool started = false;\n" +
        "bool ended = false;\n" +
        "int index_i;\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_MsgReceiveStatus", MsgReceiveStatus);
    var datavar = Blockly.Python.variableDB_.getName(
        block.getFieldValue('dataVar'), Blockly.Variables.NAME_TYPE);
    var length = 'sizeof(' + datavar + ')/sizeof(' + datavar + '[0])' || 1;
    var dataIn_function = "int handleDataIn() {\n" +
        "  while (Serial.available() > 0) {\n" +
        "    int inChar = Serial.read();\n" +
        "    if(inChar == SOP) {\n" +
        "      index_i = 0;\n" +
        "      started = true;\n" +
        "      ended = false;\n" +
        "    } else if(inChar == EOP) {\n" +
        "      ended = true;\n" +
        "      break;\n" +
        "    }else if((index_i < " + length + ")&&started&&(!ended)) {\n" +
        "      " + datavar + "[index_i] = inChar;\n" +
        "      index_i++;\n" +
        "    }\n" +
        "  }\n" +
        "  if(started && ended) {\n" +
        "    return 1;\n" +
        "  } else {\n" +
        "    return 0;\n" +
        "  }\n" +
        "}\n";
    Blockly.Python.addFunction("mainwifi_dataIn_function", dataIn_function);
    var code = "boolean receiveMsgsuccess_ = handleDataIn();\n";
    return code;
};

Blockly.Python['wificomms_receiveMsg_isSuccessed'] = function(block) {
    var code = "receiveMsgsuccess_";
    return [code, Blockly.Python.ORDER_ATOMIC];
}

/*************************
 *       version 2       *
 *       last ve         *
 *************************/

Blockly.Python['wifiTransfer_send_old'] = function(block) {
    let serial_setup = "Serial.begin(9600);";
    Blockly.Python.addSetup('serial_9600', serial_setup);
    var dataMain = block.getFieldValue('DATAMAIN');
    var dataMain_list = "int " + dataMain + "[" + this.itemCount_ + "] = {0";
    for (var i = 1; i < this.itemCount_; i++) {
        dataMain_list += ",0";
    }
    dataMain_list += "};\n";
    Blockly.Python.addDeclaration("dataMain_list", dataMain_list);
    var checkbit = "#define SOP '<'\n" +
        "#define EOP '>'\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_checkbit", checkbit);

    var length = "sizeof(" + dataMain + ")/sizeof(" + dataMain + "[0])";
    var dataLength = length + "+2";

    var code = "";

    var item_value = '';
    for (var n = 0; n < this.itemCount_; n++) {
        item_value = Blockly.Python.valueToCode(this, 'ADD' + n,
            Blockly.Python.ORDER_NONE) || '0';
        code += dataMain + "[" + n + "] = " + item_value + ";\n";
    }
    code += "unsigned char DataOut_[" + dataLength + "];\n" +
        "DataOut_[0]= SOP;\n" +
        "DataOut_[" + length + "+1]= EOP;\n" +
        "for (int i=0; i<" + length + ";i++) {\n" +
        "  DataOut_[i+1]=" + dataMain + "[i];\n" +
        "}\n" +
        "Serial.write(DataOut_, " + dataLength + ");\n";
    return code;
}

Blockly.Python['wifiTransfer_receive_old'] = function(block) {
    let serial_setup = "Serial.begin(9600);";
    Blockly.Python.addSetup('serial_9600', serial_setup);
    var dataMain = block.getFieldValue('DATAMAIN') || '_wifi_transfer';
    var list_length = block.getFieldValue("LENGTH");
    var dataMain_list = "int " + dataMain + "[" + list_length + "] = {0";
    for (var i = 1; i < list_length; i++) {
        dataMain_list += ",0";
    }
    dataMain_list += "};\n";
    Blockly.Python.addDeclaration("dataMain_list", dataMain_list);
    var checkbit = "#define SOP '<'\n" +
        "#define EOP '>'\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_checkbit", checkbit);
    var MsgReceiveStatus = "bool started = false;\n" +
        "bool ended = false;\n" +
        "int index_i;\n";
    Blockly.Python.addDeclaration("wifi_dataTransfer_MsgReceiveStatus", MsgReceiveStatus);
    var length = 'sizeof(' + dataMain + ')/sizeof(' + dataMain + '[0])' || 1;
    var dataIn_function = "int handleDataIn() {\n" +
        "  while (Serial.available() > 0) {\n" +
        "    int inChar = Serial.read();\n" +
        "    if(inChar == SOP) {\n" +
        "      index_i = 0;\n" +
        "      started = true;\n" +
        "      ended = false;\n" +
        "    } else if(inChar == EOP) {\n" +
        "      ended = true;\n" +
        "      break;\n" +
        "    }else if((index_i < " + length + ")&&started&&(!ended)) {\n" +
        "      " + dataMain + "[index_i] = inChar;\n" +
        "      index_i++;\n" +
        "    }\n" +
        "  }\n" +
        "  delay(10);\n" +
        "  if(started && ended) {\n" +
        "    return 1;\n" +
        "  } else {\n" +
        "    return 0;\n" +
        "  }\n" +
        "}\n";
    Blockly.Python.addFunction("mainwifi_dataIn_function", dataIn_function);
    var code = "boolean receiveMsgsuccess_ = handleDataIn();\n" +
        "if (!receiveMsgsuccess_) {\n" +
        "  Serial.println(\"Error: Fail to receive data!\");\n" +
        "  return;\n" +
        "}\n";
    return code;
}

Blockly.Python['wifiTransfer_receive_getValue_old'] = function(block) {
    var dataMain = block.getFieldValue('DATAMAIN') || '_wifi_transfer';
    var list_length = block.getFieldValue("INDEX");
    var code = "" + dataMain + "[" + list_length + "]";
    return [code, Blockly.Python.ORDER_ATOMIC];
}


/*************************
 *       version 3       *
 *       current         *
 *************************/

Blockly.Python['wifiTransfer_send'] = function(block) {
    Blockly.Python.addDeclaration("Serial_sendState", "int serialSendState = 0;");
    Blockly.Python.addSetup('serial', "Serial.begin(9600);");

    var serial_SendData = 'void serialSendData() {\n'+
        '   int serialDataLength = serialDataPackage().length() + 1;\n'+
        '   char serialDataBuf[serialDataLength];\n'+
        '   serialDataPackage().toCharArray(serialDataBuf, serialDataLength);\n'+
        '    if ( serialSendState == 0 ) {\n'+
        '        Serial.write(serialDataBuf);\n'+
        '    }\n'+
        '    if ( (millis() / 100) % 4 == 3 && serialSendState == 0) {\n'+
             // Send data set to WiFi Module.\n
        '        Serial.write(serialDataBuf);\n'+
        '        serialSendState = 1;\n'+
        '    } else if ( (millis() / 100) % 4 == 1) {\n'+
        '        serialSendState = 0;\n'+
        '    }\n'+
        '}\n';
    Blockly.Python.addFunction("SerialSendData",serial_SendData);


    var item_value = ''
    var serial_DataPackage = 'String serialDataPackage() { \n'+
        '  String data = "";\n'+
        '  data += "SOF";\n'              // Set up a "SOF" initializer for data validation usage.
    for (var n = 0; n < this.itemCount_; n++) {
        item_value = Blockly.Python.valueToCode(this, 'ADD' + n,
            Blockly.Python.ORDER_NONE) || '0';
        // item_value = item_value.replace(/\"/g,'');
        serial_DataPackage += '  data += "|";\n  data += '+ item_value + ';\n'
    }
    serial_DataPackage += '  data += "|";\n  data += "\\r\\n";\n  '+
        '  return data;\n}\n';
    Blockly.Python.addFunction("SerialDataPackage",serial_DataPackage);

    var code = "";
    code += "  serialSendData();\n";
    return code;
}

Blockly.Python['wifiTransfer_receive'] = function(block) {
    Blockly.Python.addSetup('serial_trans', "Serial.begin(9600);\n  Serial.setTimeout(20);");
    Blockly.Python.addDeclaration("serialDataReceived", 'String serialDataReceived;\n');

    var serial_DataFilter = 'int serialDataFilter() {\n'+
        '  if (Serial.available() > 0) {\n'+
        '    serialDataReceived = Serial.readStringUntil(\'\\r\\n\');\n'+
        '  }\n'+
        '  if (getSerialDataValue(serialDataReceived, \'|\', 0) == "SOF") {\n'+
        '    return 1;\n'+
        '  } else {\n'+
        '    return 0;\n'+
        '  }\n'+
        '}\n'
    Blockly.Python.addFunction("serialDataFilter", serial_DataFilter);

    var serial_getDataValue = 'String getSerialDataValue(String data, char separator, int index)\n'+
        '{\n'+
        '  int found = 0;\n'+
        '  int strIndex[] = {0, -1};\n'+
        '  int maxIndex = data.length() - 1;\n'+
        '  for (int i = 0; i <= maxIndex && found <= index; i++) {\n'+
        '    if (data.charAt(i) == separator || i == maxIndex) {\n'+
        '      found++;\n'+
        '      strIndex[0] = strIndex[1] + 1;\n'+
        '      strIndex[1] = (i == maxIndex) ? i + 1 : i;\n'+
        '    }\n'+
        '  }\n'+
        '  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";\n'+
        '}\n'
    Blockly.Python.addFunction("getSerialDataValue", serial_getDataValue);


    var code =  'boolean serialReceiveCheck_ = serialDataFilter();\n'+
        '  if (!serialReceiveCheck_) {\n'+
        '    Serial.println("Error receiving data from Main Module.");\n'+
        '    return;\n'+
        '  }\n'
    return code;
}

Blockly.Python['wifiTransfer_receive_getValue'] = function(block) {
    var index = parseInt(block.getFieldValue("INDEX")) +1;
    var type = block.getFieldValue("TYPE")
    var code = "getSerialDataValue(serialDataReceived, '|', "+ index +")"+ type;
    return [code, Blockly.Python.ORDER_ATOMIC];
}