#include <stdlib.h>
#include <math.h>

#include "../include/boss.h"
#include "../include/const.h"
#include "../include/entity.h"
#include "../include/effect.h"

boss_t *boss_create(pos_t pos, boss_e type) {
  boss_t *boss = malloc(sizeof(boss_t));
  *boss = (boss_t) {
    .pos = pos,
    .type = type,
    .dir = 1,
    .float_timer = 0,
    .is_angry = false,
  };
  return boss;
}

void boss_update(boss_t *boss, game_t *game) {
  pos_t player_origin = {
    .x = game->player->pos.x + PLAYER_WIDTH / 2.0,
    .y = game->player->pos.y + PLAYER_HEIGHT / 2.0,
  };
  pos_t boss_origin = {
    .x = boss->pos.x + BOSS_WIDTH / 2.0,
    .y = boss->pos.y + BOSS_HEIGHT / 2.0,
  };
  float dx = player_origin.x - boss_origin.x;
  float dy = player_origin.y - boss_origin.y;
  float distance = sqrtf(dx * dx + dy * dy);
  boss->is_angry = distance < BOSS_RANGE && distance > BOSS_HEIGHT / 2.0;
  if (boss->is_angry) {
    float norm_dx = dx / distance;
    float norm_dy = dy / distance;
    boss->pos.x += norm_dx * BOSS_SPEED;
    boss->pos.y += norm_dy * BOSS_SPEED;
    boss->dir = (norm_dx > 0) ? 1 : -1;
  }
  else {
    if (boss->float_timer == BOSS_FLOAT_TIME) {
      boss->float_timer = 0;
    }
    boss->float_timer++;
    boss->pos.y += 0.4 * sin((2 * PI) / BOSS_FLOAT_TIME * boss->float_timer);
  }
}

void boss_draw(boss_t *boss, game_t *game) {
  pos_t pos = pos_snap(boss->pos);
  if (boss->dir > 0) {
    DrawTextureRec(game->assets.entities, texture_rect_v(boss->is_angry ? 12 : 10, 6, 2, 1, ENEMY_WIDTH, ENEMY_HEIGHT), pos, WHITE);
  }
  else {
    DrawTextureRec(game->assets.entities, texture_rect_v(boss->is_angry ? 12 : 10, 7, 2, 1, ENEMY_WIDTH, ENEMY_HEIGHT), pos, WHITE);
  }
}

void boss_kill(boss_t *boss, game_t *game) {
  for (int i = 0; i < game->entities_len; i++) {
    if (game->entities[i].type == ENTITY_BOSS && game->entities[i].boss == boss) {
      if (i + 1 < game->entities_len) {
        for (int j = i; j < game->entities_len - 1; j++) {
          game->entities[j] = game->entities[j + 1];
        }
      }
      game->entities_len--;
      game->entities = realloc(game->entities, sizeof(entity_t) * game->entities_len);
      game->xp += 10;
      break;
    }
  }
}

void boss_free(boss_t *boss) {
  free(boss);
}
