#include "player.h"
#include "debug.h"
#include "game_world.h"

static inline void InternalPlayerInitInput(Player* self)
{
    // HORIZONTAL
    playerinput_add(self->input, CompositeAxis1D_as_InputAxis(compositeaxis1d_new(KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_A)), KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_D)), InputEvent_Float)), (InputDelegateFn)PlayerInputHorizontal);

    // VERTICAL
    playerinput_add(self->input, CompositeAxis1D_as_InputAxis(compositeaxis1d_new(KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_S)), KeyBind_as_InputAxis(keybind_new(SDL_SCANCODE_W)), InputEvent_Float)), (InputDelegateFn)PlayerInputVertical);
}

Player* MakePlayer()
{
    Player* self = malloc(sizeof(Player));
    ASSERT_RETURN(self != NULL, NULL, "Could not allocate enough space for Player instance");

    Spritesheet* walk = spritesheet_load("assets/sprites/player/player_walk.png", IVectorFrom(512));
    Spritesheet* idle = spritesheet_load("assets/sprites/player/player_walk.png", IVectorFrom(512));

    *self = (Player) {
        .transform = IdentityTransform,

        .input = playerinput_new(self, -1),
        .input_direction = ZeroVector,

        .faceDirection = 0,

        .animationStateMachine = NULL,

        .idle = animation_sprite_new(idle, 4.0f),
        .walk = animation_sprite_new(walk, 4.0f),

        .current_anim = self->idle
    };

    self->animationStateMachine = state_machine_init(self, PlayerIdle());

    return self;
}

Player* SpawnPlayer(Vector location)
{
    Player* self = MakePlayer();
    self->transform.position = location;
    game_world_add_entity(Player_as_BehaviourEntity(self));
    return self;
}

void PlayerStart(Player* self) { }

void PlayerUpdate(Player* self, float deltaTime)
{
    state_machine_update(self->animationStateMachine, deltaTime);
}

void PlayerDestroy(Player* self)
{
    state_machine_destroy(self->animationStateMachine);

    animation_sprite_destroy(self->idle);
    animation_sprite_destroy(self->walk);
}

void PlayerDraw(Player* self)
{
    animation_sprite_draw(self->current_anim, &self->transform);
}

void PlayerInputHorizontal(Player* self, InputEvent event) { }

void PlayerInputVertical(Player* self, InputEvent event) { }

Transform* PlayerGetTransform(Player* self)
{
    return &self->transform;
}

void PlayerAnimationExit(Player* self) { }

void PlayerIdleEnter(Player* self)
{
    self->current_anim = self->idle;
    animation_sprite_play_from(self->current_anim, 0.f);
}

const State* PlayerIdleUpdate(Player* self, float deltaTime)
{
    return PlayerIdle();
}
