#include <stdlib.h>

#include "../include/entity.h"
#include "../include/enemy.h"
#include "../include/gate.h"
#include "../include/door.h"
#include "../include/const.h"

entity_t *entity_create(entity_e type) {
 entity_t *entity = malloc(sizeof(entity_t));
  entity->type = type;
  switch (entity->type) {
    case ENTITY_ENEMY:
      entity->is_bad = true;
      break;
    case ENTITY_GATE:
      entity->is_bad = true;
      break;
    case ENTITY_DOOR:
      entity->is_bad = false;
      break;
    case ENTITY_BOSS:
      entity->is_bad = true;
      break;
  }
  return entity;
}

void entity_update(entity_t *entity, game_t *game) {
  switch (entity->type) {
    case ENTITY_ENEMY:
      enemy_update(entity->enemy, game);
      break;
    case ENTITY_GATE:
      gate_update(entity->gate, game);
      break;
    case ENTITY_DOOR:
      door_update(entity->door, game);
      break;
    case ENTITY_BOSS:
      boss_update(entity->boss, game);
      break;
  }
}

void entity_draw(entity_t *entity, game_t *game) {
  switch (entity->type) {
    case ENTITY_ENEMY:
      enemy_draw(entity->enemy, game);
      break;
    case ENTITY_GATE:
      gate_draw(entity->gate, game);
      break;
    case ENTITY_DOOR:
      door_draw(entity->door, game);
      break;
    case ENTITY_BOSS:
      boss_draw(entity->boss, game);
      break;
  }
}

void entity_detach(entity_t *entity) {
  switch (entity->type) {
    case ENTITY_ENEMY:
      enemy_free(entity->enemy);
      break;
    case ENTITY_GATE:
      gate_free(entity->gate);
      break;
    case ENTITY_DOOR:
      door_free(entity->door);
      break;
    case ENTITY_BOSS:
      boss_free(entity->boss);
      break;
  }
}

void entity_free(entity_t *entity) {
  free(entity);
}

rect_t entity_get_rect(entity_t *entity) {
  rect_t rect;
  switch (entity->type) {
    case ENTITY_ENEMY:
      rect = rect_from_pos(entity->enemy->pos, ENEMY_WIDTH, ENEMY_HEIGHT);
      break;
    case ENTITY_GATE:
      rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);
      break;
    case ENTITY_DOOR:
      rect = rect_from_pos((pos_t) { entity->door->pos.x, entity->door->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);
      break;
    case ENTITY_BOSS:
      rect = rect_from_pos(entity->boss->pos, BOSS_WIDTH, BOSS_HEIGHT);
      break;
  }
  return rect;
}
