#include <string>
#include <vector>
#include <allegro.h>
#include "CMain.hpp"
#include "CNpc.hpp"


#ifndef CMAP_HPP
#define CMAP_HPP

#define SET_BIT(a,flag)		((a)|=(flag))
#define REMOVE_BIT(a,flag)  ((a)&= ~(flag))
#define TOGGLE_BIT(a,flag)	((a)^=(flag))
#define CHECK_BIT(a,flag)	((a) & (flag))

#define FLAG_WALKABLE	1
#define FLAG_PORTAL		2
#define FLAG_WAYPOINT	4
#define FLAG_EVENT		8

#define EVENT_SIGN		1 // 0xF0000000
#define EVENT_MOVE		2 // 0xFF000000....
#define EVENT_MSG		4
#define EVENT_ITEM      8
#define EVENT_SHOP_WEAPON  16      // TODO: Change this to EVENT_SHOP --- It doesn't matter if it's a weapon shop
#define EVENT_INN          32
#define EVENT_CLERIC       64
#define EVENT_CHEST        128
#define EVENT_SWITCH       256
#define EVENT_TRAINER      512
// #define MAX_ITEM_PER_TILE  4
 
#define LAYER_GROUND    0
#define LAYER_EVENT     1

void Move(int &x, int &y, int dir);

class CCam
{
public:
	dword x;
	dword y;
};

class CTile
{
  private:

  public:
   dword gfx;
   dword flags;
   byte  alpha;			// Used for translucent tiles
};

class CPortal 
{

public:
    CPortal();
	dword srcx;
	dword srcy; 
	
	dword destx;
	dword desty;
	
    int cine_id;
	int check_quest;
	
	std::string name; // Holds the mapname that the portal points to
};


class CEvent 
{
public:
	CEvent();
	
	dword x;
	dword y; 
	dword flags; // What type of event?
	
	std::string name; 
	
	// For the EVENT_SIGN
	std::string text;
	
	std::string posttext; // TODO: Uh, do we need this anymore?
	
	// For EVENT_MSG
	// See HandleEvents(int i) -> CMain.cpp for other uses
	bool read;
	
	// For EVENT_ITEM or EVENT_SHOP_****
	
	int id;
};


class CPlayer;
class CNpc;
class CNpcInfo;
class CCoord;
class CMap
{
  private:
   dword w;
   dword h;
   byte layers;

   /* used internally */
   byte bltx;
   byte blty;

   // Functions
   void ResizeMap();

  public:
   std::string name;
   std::string tileset_name;
   std::string spriteset_name;
   
   dword player_start_x;
   dword player_start_y;
   dword player1_start_x;
   dword player1_start_y;
   
   // These point to where the player goes after a battle completes
   // overwritten by portals
   std::string battle_destmap;
   dword battle_x;
   dword battle_y;

   // Functions
   CMap();
   ~CMap();
   
  void ResizeMap(int layer, int width, int height);

  int LoadMap(std::string filename);
  
  // TODO: This hard codes the player's and second player's gfx into being removed(bad!) **************************
  int LoadMap(std::string filename, bool iscine); // true == yes it's a cinematic so don't remove special gfx
                                                  // false == no, remove the PC gfx etc
  int SaveMap(std::string filename);
  void InitMap(dword width, dword height, int tilesizex, int tilesizey, dword layers);
  void ClearMap();

  void LoadTileset(std::string filename);
  void LoadSpriteset(std::string filename);

  void SetPositions(); // places the PC's

  dword GetWidth();
  dword GetHeight();
  byte  GetLayers();

  std::vector< std::vector< std::vector<CTile> > > tile;      // [layer][y][x]
  
  std::vector<CPortal> portal;
  std::vector<CEvent> event;
  std::vector<CNpc> npc; 
  dword max_event;
  dword max_portal;
  dword max_npc;
  
  BITMAP *tile_bmp;
  BITMAP *sprite_bmp;

/* oh gawd I cant believe i'm hard coding this ... points to the location of the TILE_ITEM graphic in the tileset...(town_set.bmp) */
  #define TILE_ITEM        (9)
  //BITMAP *special_tiles[1];


  int sizew;    // Holds the size of the tiles
  int sizeh;
  
  int config;  // determines how the map is drawn.
  
  void DrawTile(dword loc, int x, int y);
  void DrawTileTrans(dword loc, int x, int y);
  void DrawMap(byte layer, dword mapdrawx, dword mapdrawy);
  void DrawMapTrans(byte layer, dword mapdrawx, dword mapdrawy);
  void DrawMapEditor(byte layer, dword mapdrawx, dword mapdrawy);
  void DrawObjects(byte layer, dword mapdrawx, dword mapdrawy);
  void TransTile(int hit, dword mapdrawx, dword mapdrawy);
  void TransTileGfx(dword loc, int x, int y);

  bool Collision(dword x, dword y);

  void CheckCine();
  bool CheckBattle();
  
  
  void CheckEvents(CPlayer &pc);
  bool CheckNpcs(int x, int y);
  int  GetNpcid(int x, int y);
  bool CheckPlayer(int x, int y);
  int WhichPlayer(int x, int y);
  void InteractNpcs(int x, int y);
  void CheckPortals(CPlayer &pc);
  
  void RenderScene(int x, int y);

  void LoadNpcs();
  CCam npccam;
  std::vector<CNpcInfo> npcinfo;
  
  bool isbattle; // Is the map a town (false), or a battle field(true)?
  int cine_id; // Holds the cinematic id (if one exists)
};

extern CMap map;


#endif
