import Blockly, { FieldAngle, FieldDropdown, FieldNumber, FieldTextInput } from 'blockly';
import { def } from './utils';

def('flag-start', {
  init() {
    this.appendDummyInput().appendField('タスク開始').appendField(new Blockly.FieldTextInput('タスク名'), 'name');
    this.setNextStatement(true, 'code');
    this.setTooltip('ここからプログラムを始めます');
    this.setColour(130);
    this.suppressPrefixSuffix = true;
  },
});

function defNoInput(name: string, text: string, colour: number, tooltip?: string) {
  def(name, {
    init() {
      this.appendDummyInput().appendField(text);
      this.setPreviousStatement(true, 'code');
      this.setNextStatement(true, 'code');
      this.setColour(colour);
      if (tooltip) {
        this.setTooltip(tooltip);
      }
    },
  });
}

function defSingleField(
  name: string,
  text1: string,
  fieldGen: () => Blockly.Field,
  text2: string,
  colour: number,
  tooltip?: string
) {
  def(name, {
    init() {
      this.appendDummyInput().appendField(text1).appendField(fieldGen(), 'arg').appendField(text2);
      this.setPreviousStatement(true, 'code');
      this.setNextStatement(true, 'code');
      this.setColour(colour);
      if (tooltip) {
        this.setTooltip(tooltip);
      }
    },
  });
}

defSingleField('println', '', () => new FieldTextInput('Hello World!'), 'を表示', 230);
defNoInput('capture-camera', 'カメラをキャプチャする', 230);
defNoInput('print-sensor', 'センサを表示', 230);

defSingleField(
  'move-moter',
  'モーターを',
  () => new FieldAngle(0, (value: number) => (value >= 270 ? 0 : Math.max(180, Math.round(value)))),
  '°の位置に動かす',
  330
);
def('move-moter2', {
  init() {
    this.appendDummyInput().appendField('モーターを');
    this.appendValueInput('arg');
    this.appendDummyInput().appendField('度の位置に動かす');
    this.setPreviousStatement(true, 'code');
    this.setNextStatement(true, 'code');
    this.setColour(330);
  },
});

defNoInput('stop-buzzer', '音を止める', 330);
def('buzzer', {
  init() {
    const f = new FieldDropdown([
      ['ド', 'C4'],
      ['レ', 'D4'],
      ['ミ', 'E4'],
      ['ファ', 'F4'],
      ['ソ', 'G4'],
      ['ラ', 'A4'],
      ['シ', 'B4'],
      ['ド2', 'C5'],
    ]);
    this.appendDummyInput().appendField(f, 'arg').appendField('の音を鳴らす');
    this.setPreviousStatement(true, 'code');
    this.setNextStatement(true, 'code');
    this.setColour(330);
  },
});

def('buzzer-hz', {
  init() {
    const f = new FieldNumber(261, 0, undefined, 1);
    this.appendDummyInput().appendField(f, 'arg').appendField('[Hz]の音を鳴らす');
    this.setPreviousStatement(true, 'code');
    this.setNextStatement(true, 'code');
    this.setColour(330);
  },
});

defSingleField('delay', '', () => new FieldNumber(1, 0), '秒待つ', 180);
function defLoop(name: string, inputBlock: boolean) {
  def(name, {
    init() {
      let dummy: Blockly.Input;
      if (inputBlock) {
        this.appendValueInput('arg0');
        dummy = this.appendDummyInput();
      } else {
        dummy = this.appendDummyInput();
        dummy.appendField(new Blockly.FieldNumber(5, 0, 4294967295), 'arg0');
      }
      dummy.appendField('回繰り返す');
      this.appendStatementInput('program').setCheck('code');
      this.setPreviousStatement(true, 'code');
      this.setNextStatement(true, 'code');
      this.setColour(180);
      this.setTooltip('指定した回数繰り返します');
    },
  });
}
defLoop('loop-field', false);
defLoop('loop-block', true);
def('for-ever', {
  init() {
    this.appendDummyInput().appendField('ずっと繰り返す');
    this.appendStatementInput('program').setCheck('code');
    this.setPreviousStatement(true, 'code');
    this.setNextStatement(false);
    this.setColour(180);
    this.setTooltip('無限に繰り返します');
  },
});

function defBinaryOperator(name: string, op: string, colour: number) {
  def(name, {
    init() {
      this.appendValueInput('arg0');
      this.appendDummyInput().appendField(op);
      this.appendValueInput('arg1');
      this.setColour(colour);
      this.setOutput(true, 'Integer');
    },
  });
}
defBinaryOperator('add', '+', 200);
defBinaryOperator('sub', '-', 200);
defBinaryOperator('mul', '*', 200);
defBinaryOperator('div', '/', 200);

def('number', {
  init() {
    this.appendDummyInput().appendField(new Blockly.FieldNumber(0), 'arg0');
    this.setColour(300);
    this.setOutput(true, 'Integer');
  },
});

function defIfLeGt(name: string, le: boolean) {
  def(name, {
    init() {
      this.appendDummyInput().appendField('もし');
      this.appendValueInput('arg0');
      this.appendDummyInput()
        .appendField('が')
        .appendField(new FieldNumber(), 'arg1')
        .appendField(le ? '未満なら' : 'より大なら');
      this.appendStatementInput('program').setCheck('code');
      this.setPreviousStatement(true, 'code');
      this.setNextStatement(true, 'code');
      this.setColour(180);
    },
  });
}

defIfLeGt('if-le', true);
defIfLeGt('if-gt', false);
