#if !defined(LD_GAME_WORLD_H_)
#define LD_GAME_WORLD_H_

#include "../core/math.h"
#include "./aabb.h"

#define WORLD_HITBOX_MAX 4096
#define WORLD_PROP_MAX 2048
#define WORLD_PROP_TYPE_MAX 64
#define WORLD_TILE_TYPE_MAX 64
#define WORLD_MAP_MAX 4800
#define WORLD_PORTAL_MAX 64

// Areas are which
typedef U32 World_Area;
enum World_Area
{
  WORLD_AREA_OUTSIDE = 1,
  WORLD_AREA_SALOON = 2,
};

typedef struct World_Tile World_Tile;
struct World_Tile {
  Str8 tag;
  F32 rotation;
};

typedef struct World_PropType World_PropType;
struct World_PropType {
  Str8 tag;
  F32 scale;
};

typedef struct World_Prop World_Prop;
struct World_Prop
{
  U32 propType;
  World_Area area;
  V2f pos;
};

typedef struct World_Portal World_Portal;
struct World_Portal
{
  AABB box;
  World_Area area;
};
typedef World_Portal World_Hitbox;


typedef struct World World;
#include "player.h"
#include "npc.h"
#include "bandit.h"

struct World {
  //// Utils
  M_Arena *arena;
  //// Static stuff
  NavMesh *navMesh;
  Random random;
  V2f mouseProjected;
  //// Loaded from world file
  World_Tile *tileTypes;
  World_PropType *propTypes;
  World_Prop *props; 
  World_Hitbox *hitboxes; 
  World_Portal *portals; 
  U32 *map;
  bool showPoster;
  U32 propCount;
  U32 portalCount;
  U32 hitboxCount;


  //// Player
  Player player;

  //// NPCs
  U32 npcCount;
  NPC npcs[128];

  ////Bandit
  // The bandit the player is after.
  Bandit bandit;

  // NPC points of interest, places to walk to.
  U32 npcPOI[256];
};

function void UpdateWorld(F32 delta, World *world);
function void RenderWorld(World *world, D_Context *drawContext);
function void ProcessEvents(SDL_Event *event, World *world);
function void UpdateNPCs(F32 delta, World *world);
function void UpdateNPC(F32 delta, NPC *npc, World *world);
function void UpdateBandit(F32 delta, Bandit *bandit, World *world);

function void LoadWorld(M_Arena *arena, World *world);
function void SaveWorld(World *world);
function void GenerateNavMesh(M_Arena *arena, World *world);

#endif  // LD_GAME_WORLD_H_
