#include <stdlib.h>
#include <string.h>

#include "../include/util.h"
#include "../include/const.h"

fz_timer_t *fz_timer_create(int frames, int step) {
  fz_timer_t *timer = malloc(sizeof(fz_timer_t));
  timer->frames = step * frames;
  timer->count = 0;
  timer->step = step;
  return timer;
}

bool fz_timer_check(fz_timer_t *timer) {
  return timer->count == 0;
}

void fz_timer_update(fz_timer_t *timer) {
  if (timer->count >= timer->frames) {
    timer->count = 0;
  }
  else {
    timer->count++;
  }
}

void fz_timer_reset(fz_timer_t *timer) {
  timer->count = 0;
}

int fz_timer_get(fz_timer_t *timer) {
  return timer->count / timer->step;
}

void fz_timer_free(fz_timer_t *timer) {
  free(timer);
}

pos_t pos_snap(pos_t vec) {
  return (pos_t) { (int) vec.x, (int) vec.y };
}

rect_t rect_from_pos(pos_t pos, int width, int height) {
  return (rect_t) { pos.x, pos.y, width, height };
}

bool rect_collide(rect_t a, rect_t b) {
  return !(
    a.x > b.x + b.width ||
    a.x + a.width < b.x ||
    a.y + a.height < b.y ||
    a.y > b.y + b.height
  );
}

bool rect_collide_threshold(rect_t a, rect_t b, float threshold) {
  return !(
    a.x > b.x + (b.width - threshold) ||
    a.x + (a.width - threshold) < b.x ||
    a.y + (a.height - threshold) < b.y ||
    a.y > b.y + (b.height - threshold)
  );
}

Texture2D texture_load(char *filename, int scale) {
  Image image = LoadImage(filename);
  ImageResizeNN(&image, scale * image.width, scale * image.height);
  Texture2D texture = LoadTextureFromImage(image);
  UnloadImage(image);
  return texture;
}

Rectangle texture_rect(int x, int y, int width, int height) {
  return (Rectangle) { x * width, y * height, width, height };
}

Rectangle texture_rect_v(int x, int y, int width, int height, int size_x, int size_y) {
  return (Rectangle) { x * size_x, y * size_y, width * size_x, height * size_y };
}


void text_draw(pos_t pos, char *text, text_alignment_e alignment, game_t *game) {
  pos_t text_pos = pos;
  int text_len = strlen(text);
  float text_width = text_len * (FONT_WIDTH + FONT_WIDTH / 3.0);
  switch (alignment) {
    case TEXT_ALIGNMENT_LEFT:
      break;
    case TEXT_ALIGNMENT_RIGHT:
      text_pos.x -= text_width;
      break;
    case TEXT_ALIGNMENT_CENTER: {
      text_pos.x -= text_width / 2.0;
      break;
    }
  }
  for (int i = 0; i < text_len; i++) {
    char c = text[i];
    int x = 0;
    int y = 0;
    if (c >= 48 && c <= 58) {
      x = text[i] - 48;
      y = 0;
    }
    else if (c >= 65 && c <= 90) {
      x = (text[i] - 65) % 10;
      y = (text[i] - 65) / 10 + 1;
    }
    else if (c >= 97 && c <= 122) {
      x = (text[i] - 97) % 10;
      y = (text[i] - 97) / 10 + 1;
    }
    else if (c == ' ') {
      x = 9;
      y = 3;
    }
    else if (c == '+') {
      x = 7;
      y = 3;
    }
    else if (c == '-') {
      x = 8;
      y = 3;
    }
    else {
      x = 6;
      y = 3;
    }
    DrawTextureRec(
      game->assets.font,
      texture_rect(x, y, FONT_WIDTH, FONT_HEIGHT),
      pos_snap((pos_t) { text_pos.x + i * (FONT_WIDTH + FONT_WIDTH / 3.0), text_pos.y }),
      WHITE
    );
  }
}
