#include "../world.h"
#include "../npc.h"
#include "../player.h"
#include "../aabb.h"
#include <SDL3/SDL_events.h>
#include <SDL3/SDL_keycode.h>
#include <SDL3/SDL_oldnames.h>
#include "../map.h"

void UpdateWorld(F32 delta, World *world)
{
  UpdateBandit(delta, &world->bandit, world);
  UpdateNPCs(delta, world);
  PlayerUpdate(delta, &world->player);
}

void UpdateNPCs(F32 delta, World *world)
{
  for (U32 i = 0; i < world->npcCount; i++)
  {
    NPC *npc = &world->npcs[i];
    UpdateNPC(delta, npc, world);
    if (
        world->player.controls.shot && AABB_Slab(world->player.pos, world->player.shotPos, npc->collision) && npc->currentArea == world->player.currentArea)
    {
      printf("You shot %*.s\n", Sv(world->npcs[i].name));
    }
  }
}

void ProcessEvents(SDL_Event *event, World *world)
{
  PlayerInput(event, &world->player);
  if(event->type == SDL_EVENT_KEY_DOWN && event->key.key == SDLK_F5){
    SaveWorld(world->arena, world);
  }
}

void RenderWorld(World *world, D_Context *draw) {
  if(world->player.currentArea == WORLD_AREA_OUTSIDE) {
    for (int i = 0; i < 4800; i++) {
      D_Rect(
        draw,
        (F32) (i % 96), (F32) (i / 96),
        .texture = world->tileTypes[world->map[i]].tile,
        .angle = (F32) world->tileTypes[world->map[i]].rotation,
      );
    }
  }
  for (U32 i = 0; i < world->propCount; i++) {
    if(world->props[i].area == world->player.currentArea) {
      D_Rect(
        draw,
        world->props[i].pos.x,
        world->props[i].pos.y,
        .texture = world->propTypes[world->props[i].propType].assetHandle,
        .scale = world->propTypes[world->props[i].propType].scale,
      );
    }
  }
  for(U32 i = 0; i < world->npcCount; i++) {
    NPC npc = world->npcs[i];
    if(npc.currentArea == world->player.currentArea) {
      V2f drawPos = AABB_Centre(npc.collision);
      D_Rect(draw, drawPos.x, drawPos.y, .texture = 1);
    }
  }
  if(world->bandit.currentArea == world->player.currentArea) {
    V2f drawPos = AABB_Centre(world->bandit.collision);
    D_Rect(draw, drawPos.x, drawPos.y, .texture = 9);
  }

	PlayerDraw(draw, &world->player);
}

void SaveWorld(M_Arena *arena, World *world) {
	(void) arena;

  printf("Saving world\n");
  OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_WRITE);
  FS_FileWrite(file, world, sizeof(World)+sizeof(NavMesh), 0);
  FS_FileWrite(file, world->navMesh, sizeof(World)+sizeof(NavMesh), sizeof(World));
  FS_FileClose(file);
  printf("Saved world :)\n");
}

World *LoadWorld(M_Arena *arena) {
  printf("loading world\n");
  OS_Handle file = FS_FileOpen(S("world.sgdat"), FS_ACCESS_READ);
  World *world = M_ArenaPush(arena, World);
  NavMesh *navMesh = M_ArenaPush(arena, NavMesh);
  FS_FileRead(file, world, sizeof(World), 0);
  FS_FileRead(file, navMesh, sizeof(NavMesh), sizeof(World));
  FS_FileClose(file);
  world->navMesh = navMesh;
  world->arena = arena;
  world->player.world = world;
  printf("loaded world\n");
  return world;
}
