#include <stdlib.h>

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

gate_t *gate_create(pos_t pos, int enemy_max, int time) {
  gate_t *gate = malloc(sizeof(gate_t));
  gate->pos = pos;
  gate->enemy_max = enemy_max;
  gate->timer_spawn = fz_timer_create(1, time);
  gate->frozen = false;
  gate->frozen_timer = 0;
  return gate;
}

void gate_update(gate_t *gate, game_t *game) {
  if (!gate->frozen) {
    bool stunned = false;
    if (
      game->player->shooting &&
      game->player->target_entity != NULL &&
      game->player->target_entity->type == ENTITY_GATE &&
      game->player->target_entity->gate == gate
    ) {
      if (gate->frozen) {
        if (game->player->dir > 0) {
          gate->pos.x += 2.0;
        }
        else {
          gate->pos.x -= 2.0;
        }
      }
      else {
        stunned = true;
      }
    }
    // handle freezing
    if (stunned) {
      if (gate->frozen_timer >= 300) {
        gate->frozen = true;
        gate->frozen_timer = 0;
      }
      gate->frozen_timer++;
    }
    else if (gate->frozen_timer > 0) {
      gate->frozen_timer--;
    }
    // handle spawning
    fz_timer_update(gate->timer_spawn);
    int enemies_len = 0;
    for (int i = 0; i < game->entities_len; i++) {
      if(game->entities[i].type == ENTITY_ENEMY) {
        enemies_len++;
      }
    }
    if (fz_timer_check(gate->timer_spawn) && enemies_len < gate->enemy_max) {
      game->entities = realloc(game->entities, sizeof(entity_t) * (game->entities_len + 1));
      enemy_t *enemy = enemy_create((pos_t) {
        .x = gate->pos.x + (TILE_WIDTH - ENEMY_WIDTH) / 2.0,
        .y = gate->pos.y + TILE_HEIGHT - ENEMY_HEIGHT,
      }, ENEMY_TEST);
      enemy->dir = (rand() & 1) ? 1 : -1;
      game->entities[game->entities_len] = (entity_t) {
        .type = ENTITY_ENEMY,
        .enemy = enemy,
        .is_bad = true,
      };
      game->entities_len++;
    }
  }
}

void gate_draw(gate_t *gate, game_t *game) {
  DrawTextureRec(game->assets.tiles, texture_rect(0, 2, TILE_WIDTH, TILE_HEIGHT), (pos_t) { gate->pos.x, gate->pos.y - TILE_HEIGHT }, WHITE);
  DrawTextureRec(game->assets.tiles, texture_rect(0, 3, TILE_WIDTH, TILE_HEIGHT), gate->pos, WHITE);
  pos_t pos = pos_snap((pos_t) {
    .x = gate->pos.x,
    .y = gate->pos.y - (ENEMY_HEIGHT - TILE_HEIGHT),
  });
  if (gate->frozen) {
    DrawTextureRec(game->assets.entities, texture_rect(3, 2, PLAYER_WIDTH, PLAYER_HEIGHT), pos, WHITE);
  }
  if (!gate->frozen && gate->frozen_timer > 0) {
    if (gate->frozen_timer <= 100) {
      DrawTextureRec(game->assets.entities, texture_rect(0, 2, PLAYER_WIDTH, PLAYER_HEIGHT), pos, WHITE);
    }
    else if (gate->frozen_timer <= 200) {
      DrawTextureRec(game->assets.entities, texture_rect(1, 2, PLAYER_WIDTH, PLAYER_HEIGHT), pos, WHITE);
    }
    else {
      DrawTextureRec(game->assets.entities, texture_rect(2, 2, PLAYER_WIDTH, PLAYER_HEIGHT), pos, WHITE);
    }
  }
}

void gate_free(gate_t *gate) {
  free(gate->timer_spawn);
  free(gate);
}
