#include "state_machine.h"
#include "stdlib.h"
#include "debug.h"

struct StateMachine {
    const State* current_state;
    void* data;
};

static inline
void internal_state_machine_set_state(StateMachine* self, const State* state) {
    self->current_state->exit(self->data);
    self->current_state = state;
    self->current_state->enter(self->data);
}

StateMachine* state_machine_init(void* data, const State* start_state) {
    StateMachine* self = malloc(sizeof(StateMachine));
    ASSERT_RETURN(self != NULL, NULL, "Failed to allocate space for StateMachine instance");
    *self = (StateMachine){
        .current_state = start_state,
        .data = data
    };

    self->current_state->enter(self->data);
    return self;
}

void state_machine_destroy(StateMachine* self) {
    self->current_state->exit(self->data);
    free(self);
}

void state_machine_update(StateMachine* self, float dt) {
    const State* next = self->current_state->update(self->data, dt);
    if(next != self->current_state)
        internal_state_machine_set_state(self, next);
}

const State* state_machine_get_current_state(StateMachine* self) {
    return self->current_state;
}
