struct PlayerInputs {
  struct engine_input_Signal pause;
  struct engine_input_Signal left;
  struct engine_input_Signal right;
  struct engine_input_Signal up;
  struct engine_input_Signal down;
  struct engine_input_Signal mouse_position;
  struct engine_input_Signal mouse_left_up;
  struct engine_input_Signal mouse_left_down;
  struct engine_input_Signal mouse_right_up;
  struct engine_input_Signal mouse_right_down;
};

ENGINE_DECLARE_COMPONENT(PlayerControlMovement, {
  uint32_t player_index;
  uint32_t input_index;
  alias_ecs_EntityHandle target;
  struct PlayerInputs *inputs;
})

static void _player_control_movement_init(void *ud, alias_ecs_Instance *instance, alias_ecs_EntityHandle entity,
                                          void **data) {
  struct PlayerControlMovement *player_control = (struct PlayerControlMovement *)data[0];

  struct PlayerInputs *inputs = alias_malloc(NULL, sizeof(*inputs), alignof(*inputs));
  player_control->inputs = inputs;

  inputs->pause = ENGINE_INPUT_SIGNAL_UP(Binding_Pause);
  inputs->left = ENGINE_INPUT_SIGNAL_UP(Binding_PlayerLeft);
  inputs->right = ENGINE_INPUT_SIGNAL_UP(Binding_PlayerRight);
  inputs->up = ENGINE_INPUT_SIGNAL_UP(Binding_PlayerUp);
  inputs->down = ENGINE_INPUT_SIGNAL_UP(Binding_PlayerDown);
  inputs->mouse_position = ENGINE_INPUT_SIGNAL_VIEWPORT_POINT(Binding_MouseX, Binding_MouseY, 0);
  inputs->mouse_left_up = ENGINE_INPUT_SIGNAL_UP(Binding_LeftClick);
  inputs->mouse_left_down = ENGINE_INPUT_SIGNAL_DOWN(Binding_LeftClick);
  inputs->mouse_right_up = ENGINE_INPUT_SIGNAL_UP(Binding_RightClick);
  inputs->mouse_right_down = ENGINE_INPUT_SIGNAL_DOWN(Binding_RightClick);

  player_control->input_index = engine_input_addFrontend(player_control->player_index, &inputs->pause, 10);
}

static void _player_control_movement_cleanup(void *ud, alias_ecs_Instance *instance, alias_ecs_EntityHandle entity,
                                             void **data) {
  struct PlayerControlMovement *player_control = (struct PlayerControlMovement *)data[0];

  engine_input_removeFrontend(player_control->player_index, player_control->input_index);

  alias_free(NULL, player_control->inputs, sizeof(*player_control->inputs), alignof(*player_control->inputs));
}

ENGINE_COMPONENT(PlayerControlMovement, .num_required_components = 1,
                 .required_components = (alias_ecs_ComponentHandle[]){Movement_component()},
                 .init = {_player_control_movement_init, NULL}, .cleanup = {_player_control_movement_cleanup, NULL})