import Blockly from 'blockly';
import { pythonGenerator } from "blockly/python";
import CategoryColors from './define_color'

Blockly.Python = pythonGenerator

// math
Blockly.math = {
    HUE: "#5472ea"
}
/* additional math */
Blockly.Blocks['math_degrad'] = {
    init: function () {
        this.appendValueInput("convert")
            .setCheck(null)
            .appendField(new Blockly.FieldDropdown([
                [Blockly.Msg.math_degrad_rad, "radians"],
                [Blockly.Msg.math_degrad_deg, "degrees"]
            ]), "rad_deg");
        this.setOutput(true, null);
        this.setColour("#5472ea");
        // this.setTooltip("");
        this.setHelpUrl("");

        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('rad_deg');
            var TOOLTIPS = {
                'radians': Blockly.Msg.Math_Degrad_RAD_TOOLTIP,
                'degrees': Blockly.Msg.Math_Degrad_DEG_TOOLTIP
            };
            return TOOLTIPS[mode];
        });
    }
};

Blockly.Blocks.math_angle = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            helpUrl: "",
            tooltip: "",
            message0: "%1",
            args0: [{
                name: "angle",
                type: "field_angle"
            }]
        })
    }
};


Blockly.Blocks.math_keep_decimal = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.MATH_KEEP_DECIMAL_HELPURL,
            tooltip: Blockly.Msg.MATH_KEEP_DECIMAL_TOOLTIP,
            message0: Blockly.Msg.MATH_KEEP_DECIMAL_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "NUM"
            }, {
                check: "Number",
                type: "input_value",
                name: "PLACE"
            }]
        })
    }
};
Blockly.Blocks.math_division_consult = {
    init: function () {
        this.jsonInit({
            message0: Blockly.Msg.MATH_DIVISION_CONSULT_TITLE,
            args0: [{
                type: "input_value",
                name: "DIVIDEND",
                check: "Number"
            }, {
                type: "input_value",
                name: "DIVISOR",
                check: "Number"
            }],
            inputsInline: !0,
            output: "Number",
            colour: Blockly.math.HUE,
            tooltip: Blockly.Msg.MATH_DIVISION_CONSULT_TOOLTIP,
            helpUrl: Blockly.Msg.MATH_DIVISION_CONSULT_HELPURL
        })
    }
};
Blockly.Blocks.labplus_mapping = {
    init: function () {
        this.jsonInit({
            colour: 230,
            args0: [{
                name: "inputNum",
                type: "input_value",
                check: "Number"
            }, {
                name: "bMin",
                type: "input_value",
                check: "Number"
            }, {
                name: "bMax",
                type: "input_value",
                check: "Number"
            }, {
                name: "cMin",
                type: "input_value",
                check: "Number"
            }, {
                name: "cMax",
                type: "input_value",
                check: "Number"
            }],
            output: "Number",
            message0: Blockly.Msg.labplus_mapping_MESSAGE0,
            tooltip: Blockly.Msg.labplus_mapping_TOOLTIP,
            helpUrl: Blockly.Msg.labplus_mapping_HELPURL
        })
    }
};

Blockly.Blocks.math_random_randrange = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.MATH_RANDOM_RANDRANGE_HELPURL,
            tooltip: Blockly.Msg.MATH_RANDOM_RANDRANGE_TOOLTIP,
            message0: Blockly.Msg.MATH_RANDOM_RANDRANGE_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "start"
            }, {
                check: "Number",
                type: "input_value",
                name: "stop"
            }, {
                check: "Number",
                type: "input_value",
                name: "step"
            }]
        })
    }
};
Blockly.Blocks['math_random_float'] = {
  /**
   * Block for random fraction between 0 and 1.
   * @this Blockly.Block
   */
  init: function() {
    this.jsonInit({
      "message0": Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM,
      "output": "Number",
      "colour": CategoryColors.Math,
      "tooltip": Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP,
      "helpUrl": Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL
    });
  }
};
Blockly.Blocks.math_convert = {
    init: function () {
        this.jsonInit({
            message0: Blockly.Msg.MATH_CONVERT_MESSAGE0,
            args0: [{
                type: "field_dropdown",
                options: [["int", "int"], ["float", "float"]],
                name: "TYPE0"
            }, {
                type: "input_value",
                name: "INPUT0",
                check: ["Number", "String"]
            }],
            output: "Number",
            colour: CategoryColors.Math,
            tooltip: Blockly.Msg.MATH_CONVERT_TOOLTIP,
            helpUrl: Blockly.Msg.MATH_CONVERT_HELPURL
        })
    }
};
Blockly.Blocks.math_number_bits_ops = {
    init: function () {
        this.jsonInit({
            message0: Blockly.Msg.MATH_NUMBER_BITS_OPS_MESSAGE0,
            args0: [{
                type: "input_value",
                name: "A",
                check: "Number"
            }, {
                type: "field_dropdown",
                options: [["|", " | "], ["&", " & "], ["^", " ^ "], ["<<", " << "], [">>", " >> "]],
                name: "OP"
            }, {
                type: "input_value",
                name: "B",
                check: "Number"
            }],
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            tooltip: Blockly.Msg.MATH_NUMBER_BITS_OPS_TOOLTIP,
            helpUrl: Blockly.Msg.MATH_NUMBER_BITS_OPS_HELPURL
        })
    }
};
Blockly.Blocks.bit_inversion = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.BIT_INVERSION_HELPURL,
            tooltip: Blockly.Msg.BIT_INVERSION_TOOLTIP,
            message0: Blockly.Msg.BIT_INVERSION_MESSAGE0,
            args0: [{
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_ten_convert_to = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "String",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_TEN_CONVERT_TO_HELPURL,
            // tooltip: Blockly.Msg.CocoRobo_TEN_CONVERT_TO_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_TEN_CONVERT_TO_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "int_num"
            }, {
                options: [
                    [Blockly.Msg.CocoRobo_BIN, "bin"],
                    [Blockly.Msg.CocoRobo_OCT, "oct"],
                    [Blockly.Msg.CocoRobo_HEX, "hex"]
                ],
                type: "field_dropdown",
                name: "ten_convert_to"
            }]
        });
        var thisBlock = this;
        this.setTooltip(function () {
            return Blockly.Msg.CocoRobo_TEN_CONVERT_TO_TOOLTIP.replace('%2',
                thisBlock.getFieldValue('ten_convert_to'));
        });
    }
};
Blockly.Blocks.CocoRobo_convert_to_ten = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_CONVERT_TO_TEN_HELPURL,
            // tooltip: Blockly.Msg.CocoRobo_CONVERT_TO_TEN_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_CONVERT_TO_TEN_MESSAGE0,
            args0: [{
                options: [
                    [Blockly.Msg.CocoRobo_BIN, "2"],
                    [Blockly.Msg.CocoRobo_OCT, "8"],
                    [Blockly.Msg.CocoRobo_HEX, "16"]
                ],
                type: "field_dropdown",
                name: "convert_choice"
            }, {
                check: "String",
                type: "input_value",
                name: "convert_str"
            }]
        });
        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('convert_choice');
            var TOOLTIPS = {
                '2': Blockly.Msg.CocoRobo_CONVERT_TO_TEN_TOOLTIP.replace('%2', "bin"),
                '8': Blockly.Msg.CocoRobo_CONVERT_TO_TEN_TOOLTIP.replace('%2', "oct"),
                '16': Blockly.Msg.CocoRobo_CONVERT_TO_TEN_TOOLTIP.replace('%2', "hex")
            };
            return TOOLTIPS[mode];
        });
    }
};
Blockly.Blocks.CocoRobo_high_low = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Pin,
            helpUrl: Blockly.Msg.CocoRobo_HIGH_LOW_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_HIGH_LOW_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_HIGH_LOW_MESSAGE0,
            args0: [{
                options: [
                    ["HIGH", "1"],
                    ["LOW", "0"]
                ],
                type: "field_dropdown",
                name: "high_low"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_start_new_thread = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            nextStatement: null,
            previousStatement: null,
            colour: CategoryColors.Event,
            helpUrl: Blockly.Msg.CocoRobo_START_NEW_THREAD_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_START_NEW_THREAD_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_START_NEW_THREAD_MESSAGE0,
            args0: [{
                options: [
                    ["1", "1"],
                    ["2", "2"],
                    ["3", "3"],
                    ["4", "4"]
                ],
                type: "field_dropdown",
                name: "thread_name"
            }]
        });
        this.appendStatementInput("DO").appendField(Blockly.Msg.CONTROLS_REPEAT_INPUT_DO)
    }
};
Blockly.Blocks.CocoRobo_lock_object_acquire_lock = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            nextStatement: null,
            previousStatement: null,
            colour: CategoryColors.Event,
            helpUrl: Blockly.Msg.CocoRobo_LOCK_OBJECT_ACQUIRE_LOCK_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_LOCK_OBJECT_ACQUIRE_LOCK_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_LOCK_OBJECT_ACQUIRE_LOCK_MESSAGE0,
            args0: [{
                type: "field_input",
                name: "thread_lock_object",
                text: "lock"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_ten_converted_to_bytes = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_TEN_CONVERTED_TO_BYTES_HELPURL,
            // tooltip: Blockly.Msg.CocoRobo_TEN_CONVERTED_TO_BYTES_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_TEN_CONVERTED_TO_BYTES_MESSAGE0,
            args0: [{
                options: [
                    ["2", "'\x3cH'"],
                    ["4", "'\x3cL'"]
                ],
                type: "field_dropdown",
                name: "convert_choice"
            }, {
                check: "Number",
                type: "input_value",
                name: "convert_num"
            }]
        });
        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('convert_choice');
            var TOOLTIPS = {
                "'\x3cHH'": Blockly.Msg.CocoRobo_TEN_CONVERTED_TO_BYTES_TOOLTIP.replace('%1', "2"),
                "'\x3cLL'": Blockly.Msg.CocoRobo_TEN_CONVERTED_TO_BYTES_TOOLTIP.replace('%1', "4")
            };
            return TOOLTIPS[mode];
        });
    }
};
Blockly.Blocks.CocoRobo_int_to_chr = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "String",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_INT_TO_CHR_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_INT_TO_CHR_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_INT_TO_CHR_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "convert_num"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_hcsr04_obj = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            nextStatement: null,
            previousStatement: null,
            colour: CategoryColors.General,
            helpUrl: Blockly.Msg.CocoRobo_HCSR04_OBJ_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_HCSR04_OBJ_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_HCSR04_OBJ_MESSAGE0,
            args0: [{
                text: "hcsr04",
                type: "field_input",
                name: "hcsr04_name"
            }, {
                check: "Number",
                type: "input_value",
                name: "trigger"
            }, {
                check: "Number",
                type: "input_value",
                name: "echo"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_hcsr04_distance = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.General,
            helpUrl: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_MESSAGE0,
            args0: [{
                text: "hcsr04",
                type: "field_input",
                name: "hcsr04_name"
            }, {
                options: [
                    ["mm", "mm"],
                    ["cm", "cm"]
                ],
                type: "field_dropdown",
                name: "unit"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_hcsr04_distance_mm = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.Pin,
            helpUrl: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_MM_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_MM_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_HCSR04_DISTANCE_MM_MESSAGE0,
            args0: [{
                text: "hcsr04",
                type: "field_input",
                name: "hcsr04_name"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_pm2_5_MIC = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.General,
            helpUrl: Blockly.Msg.CocoRobo_PM2_5_MIC_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_PM2_5_MIC_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_PM2_5_MIC_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "rx"
            }, {
                options: [
                    ["PM1.0ug/m3", "_pm_data[0]"],
                    ["PM2.5ug/m3", "_pm_data[1]"],
                    ["PM10ug/m3", "_pm_data[2]"]
                ],
                type: "field_dropdown",
                name: "unit"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_pm2_5_LitresAir = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "Number",
            colour: CategoryColors.General,
            helpUrl: Blockly.Msg.CocoRobo_PM2_5_LitresAir_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_PM2_5_LitresAir_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_PM2_5_LitresAir_MESSAGE0,
            args0: [{
                check: "Number",
                type: "input_value",
                name: "rx"
            }, {
                options: [
                    ["0.3um", "_pm_data[3]"],
                    ["0.5um", "_pm_data[4]"],
                    ["1um", "_pm_data[5]"],
                    ["2.5um", "_pm_data[6]"],
                    ["5um", "_pm_data[7]"],
                    ["10um", "_pm_data[8]"]
                ],
                type: "field_dropdown",
                name: "unit"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_mac_address = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "String",
            colour: "X" == SOFTWARE_KEY ? CategoryColors.System : CategoryColors.Wifi,
            helpUrl: Blockly.Msg.CocoRobo_MAC_ADDRESS_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_MAC_ADDRESS_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_MAC_ADDRESS_MESSAGE0
        })
    }
};
Blockly.Blocks.CocoRobo_ujson_loads = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Text,
            helpUrl: Blockly.Msg.CocoRobo_UJSON_LOADS_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_UJSON_LOADS_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_UJSON_LOADS_MESSAGE0,
            args0: [{
                check: "String",
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_code_annotation = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            nextStatement: null,
            previousStatement: null,
            // output: null,
            colour: CategoryColors.Text,
            helpUrl: Blockly.Msg.CocoRobo_code_annotation_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_code_annotation_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_code_annotation_MESSAGE0,
            args0: [{
                check: "String",
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_ujson_dumps = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "String",
            colour: CategoryColors.Text,
            helpUrl: Blockly.Msg.CocoRobo_UJSON_DUMPS_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_UJSON_DUMPS_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_UJSON_DUMPS_MESSAGE0,
            args0: [{
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_base64_to_data = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_BASE64_TO_DATA_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_BASE64_TO_DATA_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_BASE64_TO_DATA_MESSAGE0,
            args0: [{
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_data_to_base64 = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_DATA_TO_BASE64_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_DATA_TO_BASE64_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_DATA_TO_BASE64_MESSAGE0,
            args0: [{
                type: "input_value",
                name: "data"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_hex_to_bin_str = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_HEX_TO_BIN_STR_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_HEX_TO_BIN_STR_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_HEX_TO_BIN_STR_MESSAGE0,
            args0: [{
                check: "String",
                type: "input_value",
                name: "convert_chr"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_str_to_hex = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: null,
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_STR_TO_HEX_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_STR_TO_HEX_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_STR_TO_HEX_MESSAGE0,
            args0: [{
                check: "String",
                type: "input_value",
                name: "convert_chr"
            }]
        })
    }
};
Blockly.Blocks.CocoRobo_chr_to_int = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            output: "String",
            colour: CategoryColors.Math,
            helpUrl: Blockly.Msg.CocoRobo_CHR_TO_INT_HELPURL,
            tooltip: Blockly.Msg.CocoRobo_CHR_TO_INT_TOOLTIP,
            message0: Blockly.Msg.CocoRobo_CHR_TO_INT_MESSAGE0,
            args0: [{
                check: "String",
                type: "input_value",
                name: "convert_chr"
            }]
        })
    }
};
Blockly.Blocks['math_single'] = {
    /**
     * Block for advanced math operators with single operand.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": "%1 %2",
            "args0": [
                {
                    "type": "field_dropdown",
                    "name": "OP",
                    "options": [
                        [Blockly.Msg.MATH_SINGLE_OP_ROOT, 'ROOT'],
                        [Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE, 'ABS'],
                        // ['degrees', 'DEGRAD_DEG'],
                        // ['radians', 'DEGRAD_RAD'],
                        ['-', 'NEG'],
                        ['ln', 'LN'],
                        ['log10', 'LOG10'],
                        ['e^', 'EXP'],
                        ['10^', 'POW10']
                    ]
                },
                {
                    "type": "input_value",
                    "name": "NUM",
                    "check": "Number"
                }
            ],
            "output": "Number",
            "colour": CategoryColors.Math,
            "helpUrl": Blockly.Msg.MATH_SINGLE_HELPURL
        });
        // Assign 'this' to a variable for use in the tooltip closure below.
        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('OP');
            var TOOLTIPS = {
                'ROOT': Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT,
                'ABS': Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS,
                'NEG': Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG,
                'LN': Blockly.Msg.MATH_SINGLE_TOOLTIP_LN,
                'LOG10': Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10,
                'EXP': Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP,
                'POW10': Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10
            };
            return TOOLTIPS[mode];
        });
    }
};

Blockly.Blocks['math_number'] = {
    /**
     * Block for numeric value.
     * @this Blockly.Block
     */
    init: function () {
        this.setHelpUrl(Blockly.Msg.MATH_NUMBER_HELPURL);
        this.setColour(CategoryColors.Math);
        this.appendDummyInput()
            .appendField(new Blockly.FieldNumber('0'), 'NUM');
        this.setOutput(true, 'Number');
        // Assign 'this' to a variable for use in the tooltip closure below.
        var thisBlock = this;
        // Number block is trivial.  Use tooltip of parent block if it exists.
        this.setTooltip(function () {
            var parent = thisBlock.getParent();
            return (parent && parent.getInputsInline() && parent.tooltip) ||
                Blockly.Msg.MATH_NUMBER_TOOLTIP;
        });
    }
};

Blockly.Blocks['math_arithmetic'] = {
    /**
     * Block for basic arithmetic operator.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": "%1 %2 %3",
            "args0": [
                {
                    "type": "input_value",
                    "name": "A",
                    "check": ["Number", "String"]
                },
                {
                    "type": "field_dropdown",
                    "name": "OP",
                    "options":
                        [[Blockly.Msg.MATH_ADDITION_SYMBOL, 'ADD'],
                        [Blockly.Msg.MATH_SUBTRACTION_SYMBOL, 'MINUS'],
                        [Blockly.Msg.MATH_MULTIPLICATION_SYMBOL, 'MULTIPLY'],
                        [Blockly.Msg.MATH_DIVISION_SYMBOL, 'DIVIDE'],
                        [Blockly.Msg.MATH_POWER_SYMBOL, 'POWER'],
                            // ['%', 'MODULO']
                        ]
                },
                {
                    "type": "input_value",
                    "name": "B",
                    "check": ["Number", "String"]
                }
            ],
            "inputsInline": true,
            "output": "Number",
            "colour": CategoryColors.Math,
            "helpUrl": Blockly.Msg.MATH_ARITHMETIC_HELPURL
        });
        // Assign 'this' to a variable for use in the tooltip closure below.
        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('OP');
            var TOOLTIPS = {
                'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
                'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
                'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
                'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
                'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER,
                'MODULO': 'Computes the remainder of division.'
            };
            return TOOLTIPS[mode];
        });
    }
};

Blockly.Blocks['math_trig'] = {
    /**
     * Block for trigonometry operators.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": "%1 %2",
            "args0": [
                {
                    "type": "field_dropdown",
                    "name": "OP",
                    "options": [
                        [Blockly.Msg.MATH_TRIG_SIN, 'SIN'],
                        [Blockly.Msg.MATH_TRIG_COS, 'COS'],
                        [Blockly.Msg.MATH_TRIG_TAN, 'TAN'],
                        [Blockly.Msg.MATH_TRIG_ASIN, 'ASIN'],
                        [Blockly.Msg.MATH_TRIG_ACOS, 'ACOS'],
                        [Blockly.Msg.MATH_TRIG_ATAN, 'ATAN']
                    ]
                },
                {
                    "type": "input_value",
                    "name": "NUM",
                    "check": "Number"
                }
            ],
            "output": "Number",
            "colour": CategoryColors.Math,
            "helpUrl": Blockly.Msg.MATH_TRIG_HELPURL
        });
        // Assign 'this' to a variable for use in the tooltip closure below.
        var thisBlock = this;
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('OP');
            var TOOLTIPS = {
                'SIN': Blockly.Msg.MATH_TRIG_TOOLTIP_SIN,
                'COS': Blockly.Msg.MATH_TRIG_TOOLTIP_COS,
                'TAN': Blockly.Msg.MATH_TRIG_TOOLTIP_TAN,
                'ASIN': Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN,
                'ACOS': Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS,
                'ATAN': Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN
            };
            return TOOLTIPS[mode];
        });
    }
};

Blockly.Blocks['math_constant'] = {
    /**
     * Block for constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": "%1",
            "args0": [
                {
                    "type": "field_dropdown",
                    "name": "CONSTANT",
                    "options": [
                        ['\u03c0', 'PI'],
                        ['e', 'E'],
                        ['\u03c6', 'GOLDEN_RATIO'],
                        ['sqrt(2)', 'SQRT2'],
                        ['sqrt(\u00bd)', 'SQRT1_2'],
                        ['\u221e', 'INFINITY']
                    ]
                }
            ],
            "output": "Number",
            "colour": CategoryColors.Math,
            "tooltip": Blockly.Msg.MATH_CONSTANT_TOOLTIP,
            "helpUrl": Blockly.Msg.MATH_CONSTANT_HELPURL
        });
    }
};

Blockly.Blocks['math_number_property'] = {
    /**
     * Block for checking if a number is even, odd, prime, whole, positive,
     * negative or if it is divisible by certain number.
     * @this Blockly.Block
     */
    init: function () {
        var PROPERTIES =
            [[Blockly.Msg.MATH_IS_EVEN, 'EVEN'],
            [Blockly.Msg.MATH_IS_ODD, 'ODD'],
            [Blockly.Msg.MATH_IS_PRIME, 'PRIME'],
            [Blockly.Msg.MATH_IS_WHOLE, 'WHOLE'],
            [Blockly.Msg.MATH_IS_POSITIVE, 'POSITIVE'],
            [Blockly.Msg.MATH_IS_NEGATIVE, 'NEGATIVE'],
            [Blockly.Msg.MATH_IS_DIVISIBLE_BY, 'DIVISIBLE_BY']];
        this.setColour(CategoryColors.Math);
        this.appendValueInput('NUMBER_TO_CHECK')
            .setCheck('Number');
        var dropdown = new Blockly.FieldDropdown(PROPERTIES, function (option) {
            var divisorInput = (option == 'DIVISIBLE_BY');
            this.sourceBlock_.updateShape_(divisorInput);
        });
        this.appendDummyInput()
            .appendField(dropdown, 'PROPERTY');
        this.setInputsInline(true);
        this.setOutput(true, 'Boolean');
        this.setTooltip(Blockly.Msg.MATH_IS_TOOLTIP);
    },
    /**
     * Create XML to represent whether the 'divisorInput' should be present.
     * @return {Element} XML storage element.
     * @this Blockly.Block
     */
    mutationToDom: function () {
        var container = document.createElement('mutation');
        var divisorInput = (this.getFieldValue('PROPERTY') == 'DIVISIBLE_BY');
        container.setAttribute('divisor_input', divisorInput);
        return container;
    },
    /**
     * Parse XML to restore the 'divisorInput'.
     * @param {!Element} xmlElement XML storage element.
     * @this Blockly.Block
     */
    domToMutation: function (xmlElement) {
        var divisorInput = (xmlElement.getAttribute('divisor_input') == 'true');
        this.updateShape_(divisorInput);
    },
    /**
     * Modify this block to have (or not have) an input for 'is divisible by'.
     * @param {boolean} divisorInput True if this block has a divisor input.
     * @private
     * @this Blockly.Block
     */
    updateShape_: function (divisorInput) {
        // Add or remove a Value Input.
        var inputExists = this.getInput('DIVISOR');
        if (divisorInput) {
            if (!inputExists) {
                this.appendValueInput('DIVISOR')
                    .setCheck('Number');
            }
        } else if (inputExists) {
            this.removeInput('DIVISOR');
        }
    }
};

Blockly.Blocks['math_round'] = {
    /**
     * Block for rounding functions.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": "%1 %2",
            "args0": [
                {
                    "type": "field_dropdown",
                    "name": "OP",
                    "options": [
                        [Blockly.Msg.MATH_ROUND_OPERATOR_ROUND, 'ROUND'],
                        [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP, 'ROUNDUP'],
                        [Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, 'ROUNDDOWN']
                    ]
                },
                {
                    "type": "input_value",
                    "name": "NUM",
                    "check": "Number"
                }
            ],
            "output": "Number",
            "colour": CategoryColors.Math,
            "tooltip": Blockly.Msg.MATH_ROUND_TOOLTIP,
            "helpUrl": Blockly.Msg.MATH_ROUND_HELPURL
        });
    }
};

Blockly.Blocks['math_on_list'] = {
    /**
     * Block for evaluating a list of numbers to return sum, average, min, max,
     * etc.  Some functions also work on text (min, max, mode, median).
     * @this Blockly.Block
     */
    init: function () {
        var OPERATORS =
            [[Blockly.Msg.MATH_ONLIST_OPERATOR_SUM, 'SUM'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_MIN, 'MIN'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_MAX, 'MAX'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE, 'AVERAGE'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN, 'MEDIAN'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_MODE, 'MODE'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV, 'STD_DEV'],
            [Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM, 'RANDOM']];
        // Assign 'this' to a variable for use in the closures below.
        var thisBlock = this;
        this.setHelpUrl(Blockly.Msg.MATH_ONLIST_HELPURL);
        this.setColour(CategoryColors.Math);
        this.setOutput(true, 'Number');
        var dropdown = new Blockly.FieldDropdown(OPERATORS, function (newOp) {
            thisBlock.updateType_(newOp);
        });
        this.appendValueInput('LIST')
            .setCheck('Array')
            .appendField(dropdown, 'OP');
        this.setTooltip(function () {
            var mode = thisBlock.getFieldValue('OP');
            var TOOLTIPS = {
                'SUM': Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM,
                'MIN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN,
                'MAX': Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX,
                'AVERAGE': Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE,
                'MEDIAN': Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN,
                'MODE': Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE,
                'STD_DEV': Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV,
                'RANDOM': Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM
            };
            return TOOLTIPS[mode];
        });
    },
    /**
     * Modify this block to have the correct output type.
     * @param {string} newOp Either 'MODE' or some op than returns a number.
     * @private
     * @this Blockly.Block
     */
    updateType_: function (newOp) {
        if (newOp == 'MODE') {
            this.outputConnection.setCheck('Array');
        } else {
            this.outputConnection.setCheck('Number');
        }
    },
    /**
     * Create XML to represent the output type.
     * @return {Element} XML storage element.
     * @this Blockly.Block
     */
    mutationToDom: function () {
        var container = document.createElement('mutation');
        container.setAttribute('op', this.getFieldValue('OP'));
        return container;
    },
    /**
     * Parse XML to restore the output type.
     * @param {!Element} xmlElement XML storage element.
     * @this Blockly.Block
     */
    domToMutation: function (xmlElement) {
        this.updateType_(xmlElement.getAttribute('op'));
    }
};
Blockly.Blocks['math_modulo'] = {
    /**
     * Block for remainder of a division.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": Blockly.Msg.MATH_MODULO_TITLE,
            "args0": [
                {
                    "type": "input_value",
                    "name": "DIVIDEND",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "DIVISOR",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "output": "Number",
            "colour": CategoryColors.Math,
            "tooltip": Blockly.Msg.MATH_MODULO_TOOLTIP,
            "helpUrl": Blockly.Msg.MATH_MODULO_HELPURL
        });
    }
};
Blockly.Blocks['math_constrain'] = {
    /**
     * Block for constraining a number between two limits.
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": Blockly.Msg.MATH_CONSTRAIN_TITLE,
            "args0": [
                {
                    "type": "input_value",
                    "name": "VALUE",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "LOW",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "HIGH",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "output": "Number",
            "colour": CategoryColors.Math,
            "tooltip": Blockly.Msg.MATH_CONSTRAIN_TOOLTIP,
            "helpUrl": Blockly.Msg.MATH_CONSTRAIN_HELPURL
        });
    }
};

Blockly.Blocks['labplus_mapping'] = {
    init: function () {
        this.jsonInit({
            inputsInline: !0,
            colour: CategoryColors.Math,
            args0: [{
                name: "inputNum",
                type: "input_value",
                check: "Number"
            }, {
                name: "bMin",
                type: "input_value",
                check: "Number"
            }, {
                name: "bMax",
                type: "input_value",
                check: "Number"
            }, {
                name: "cMin",
                type: "input_value",
                check: "Number"
            }, {
                name: "cMax",
                type: "input_value",
                check: "Number"
            }],
            output: "Number",
            message0: Blockly.Msg.labplus_mapping_MESSAGE0,
            tooltip: Blockly.Msg.labplus_mapping_TOOLTIP,
            helpUrl: Blockly.Msg.labplus_mapping_HELPURL
        })
    }
};

Blockly.Blocks['math_random_int'] = {
    /**
     * Block for random integer between [X] and [Y].
     * @this Blockly.Block
     */
    init: function () {
        this.jsonInit({
            "message0": Blockly.Msg.MATH_RANDOM_INT_TITLE,
            "args0": [
                {
                    "type": "input_value",
                    "name": "FROM",
                    "check": "Number"
                },
                {
                    "type": "input_value",
                    "name": "TO",
                    "check": "Number"
                }
            ],
            "inputsInline": true,
            "output": "Number",
            "colour": CategoryColors.Math,
            "tooltip": Blockly.Msg.MATH_RANDOM_INT_TOOLTIP,
            "helpUrl": Blockly.Msg.MATH_RANDOM_INT_HELPURL
        });
    }
};

Blockly.Blocks.math_convert = {
    init: function () {
        this.jsonInit({
            message0: Blockly.Msg.MATH_CONVERT_MESSAGE0,
            args0: [{
                type: "field_dropdown",
                options: [["int", "int"], ["float", "float"]],
                name: "TYPE0"
            }, {
                type: "input_value",
                name: "INPUT0",
                check: ["Number", "String"]
            }],
            output: "Number",
            colour: CategoryColors.Math,
            tooltip: Blockly.Msg.MATH_CONVERT_TOOLTIP,
            helpUrl: Blockly.Msg.MATH_CONVERT_HELPURL
        })
    }
};
export default Blockly