import { EventKeyboard, Input, KeyCode, input } from "cc";

export type TAction = 'left' | 'right' | 'up' | 'down' | 'jump';

const defaultMap: Record<TAction, boolean> = {
  left: false,
  right: false,
  up: false,
  down: false,
  jump: false
}

class ActionEvent {
  private _pressedMap: Record<TAction, boolean> = {...defaultMap};
  private _justPressedMap: Record<TAction, boolean> = {...defaultMap};
  private _justReleasedMap: Record<TAction, boolean> = {...defaultMap};

  constructor() {
    input.on(Input.EventType.KEY_DOWN, (e: EventKeyboard) => {
      let type: TAction;
      switch (e.keyCode) {
        case KeyCode.KEY_A:
          type = 'left';
          break;
        case KeyCode.KEY_W:
          type = 'up';
          break;
        case KeyCode.KEY_S:
          type = 'down';
          break;
        case KeyCode.KEY_D:
          type = 'right';
          break;
        case KeyCode.KEY_J:
          type = 'jump';
          break;
      }
      if (!type) return;
      this.setPressedStatus(type, true);
      this.setReleasedStatus(type, false);
    }, this);

    input.on(Input.EventType.KEY_UP, (e: EventKeyboard) => {
      let type: TAction;
      switch (e.keyCode) {
        case KeyCode.KEY_A:
          type = 'left';
          break;
        case KeyCode.KEY_W:
          type = 'up';
          break;
        case KeyCode.KEY_S:
          type = 'down';
          break;
        case KeyCode.KEY_D:
          type = 'right';
          break;
        case KeyCode.KEY_J:
          type = 'jump';
          break;
      }
      if (!type) return;
      this.setPressedStatus(type, false);
      this.setReleasedStatus(type, true);
    })
  }

  public setPressedStatus(action: TAction, status: boolean) {
    if (status !== false && this._pressedMap[action]) {
      return;
    }
    this._pressedMap[action] = status;
    this._justPressedMap[action] = status;
  }

  public setReleasedStatus(action: TAction, status: boolean) {
    this._justReleasedMap[action] = status;
  }

  isActionPressed(action: TAction): boolean {
    return this._pressedMap[action]
  }

  isActionJustPressed(action: TAction): boolean {
    const status = this._justPressedMap[action];
    this._justPressedMap[action] = false;
    return status;
  }

  isActionJustReleased(action: TAction): boolean {
    const status = this._justReleasedMap[action];
    this._justReleasedMap[action] = false;
    return status;
  }
}

const actionEvent = new ActionEvent()

export default actionEvent
