import Blockly from 'blockly';

Blockly.JavaScript['flag_start'] = () => {
  return `--FUNCTION--\n`;
};

Blockly.JavaScript['say'] = block => {
  const text = block.getFieldValue('text');
  // エスケープ処理
  const escaped = text.replace(/\\/g, '\\\\').replace(/\n/g, '\\\n').replace(/"/g, '\\"');
  // print関数はグルーコードとして getCode 関数で定義しています
  return `print("${escaped}");\n`;
};

function defLoop(name: string, inputBlock: boolean) {
  Blockly.JavaScript[name] = block => {
    const i = Blockly.JavaScript.nameDB_.getDistinctName('i', Blockly.VARIABLE_CATEGORY_NAME);
    const program = Blockly.JavaScript.statementToCode(block, 'program');
    const arg0 = inputBlock ? Blockly.JavaScript.valueToCode(block, 'arg0', Blockly.JavaScript.ORDER_RELATIONAL) : block.getFieldValue('arg0');
    const end = arg0 ? arg0 : '0';
    return `for (uint32_t ${i} = 0; ${i} < ${end}; ++${i}) {\n${program}}\n`;
  };
}
defLoop('loop-field', false);
defLoop('loop-block', true);

function defBinaryOperator(name: string, op: string, order: number) {
  Blockly.JavaScript[name] = block => {
    const arg0 = Blockly.JavaScript.valueToCode(block, 'arg0', order);
    const arg1 = Blockly.JavaScript.valueToCode(block, 'arg1', order);
    return [`${arg0} ${op} ${arg1}`, order];
  };
}
defBinaryOperator('add', '+', Blockly.JavaScript.ORDER_ADDITION);
defBinaryOperator('sub', '-', Blockly.JavaScript.ORDER_SUBTRACTION);
defBinaryOperator('mul', '*', Blockly.JavaScript.ORDER_MULTIPLICATION);
defBinaryOperator('div', '/', Blockly.JavaScript.ORDER_DIVISION);

Blockly.JavaScript['number'] = block => {
  const x = block.getFieldValue('arg0');
  return [x.toString(), Blockly.JavaScript.ORDER_ATOMIC];
};
