#ifndef __FFTFILE_H__
#define __FFTFILE_H__

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <string>
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "SDL_ttf.h"
#include "physfs.h"
#include "graphics.h"
#include "aries.h"
#include "input.h"
#include "log.h"

using aries::newNode;
using aries::Node;
using aries::DataNode;
using aries::StringNode;
using aries::DataNodeList;
using aries::NodeList;

#define __MAXSHIPSLOTS 20

typedef struct{
	int id;
	int w;
	int l;
	int d;
	int cargounits;
	int ammoamount;
	int holdamount;
	std::string type;
	bool full;
	bool weaponfull;
	std::string fulltype;
	std::string holdweapon;
	std::string fn;
	std::string fpk;
	SDL_Surface *image;
}__ship_slot;

char PHYSFS_getc(PHYSFS_file *fp);
std::string PHYSFS_getline(PHYSFS_file *fp);
bool isWhiteSpace(char c);
std::string stripString(const std::string& str);
std::string getNextName(PHYSFS_file *fp);
DataNode *ReadDoc(PHYSFS_file *fp);
DataNode *ReadString(std::string str);
int physfsrwops_seek(SDL_RWops *rw, int offset, int whence);
int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum);
int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num);
int physfsrwops_close(SDL_RWops *rw);
SDL_RWops *create_rwops(PHYSFS_file *handle);
SDL_Surface *LoadIMG(std::string imgfile);
SDL_Surface *LoadICON(std::string imgfile);
TTF_Font *LoadTTF(std::string ttffile, int ptsize);
Mix_Chunk *LoadSound(std::string soundfile);

/* When instantiated, yield an empty search path.
 * Upon destruction, restore the old path.
 */
class PathSaver
{
public:
	PathSaver();
	~PathSaver();
private:
	char **saved;
	void clearPath();
};

bool IsFPK(std::string str);
std::string lastPathElement(const std::string &path);
int FPK_count();
float FPK_versionByName(std::string name);
std::string FPK_ByName(std::string name);
void FPK_Invalid(std::string fpk, std::string message);
int FPK_countPlayerShips(std::string fpk);
SDL_Surface *FPK_LoadIMG(std::string fpk, std::string img);
int SWarpToSpeed(std::string swarp);
std::string SpeedToSWarp(int speed);
float SpeedToFWarp(int speed);

class FPKShip
{
public:
	FPKShip(int listindex, int num);
	FPKShip(std::string sfpk, std::string shipname);
	~FPKShip();
	void GetFileInfo(int listindex, int num);
	void GetFileInfo(std::string sfpk, std::string shipname);
	void Reload(int listindex, int num);
	std::string GetName();
	std::string GetFPK();
	std::string GetImageFN();
	std::string GetShieldFN();
	int GetW();
	int GetL();
	int GetD();
	std::string GetSW();
	std::string GetSL();
	std::string GetSD();
	int GetShootX();
	int GetShootY();
	unsigned int GetPrice();
	std::string GetSPrice();
	int GetHullHitMax();
	std::string GetSHullHitMax();
	SDL_Surface *GetImage();
	bool HasShield();
	SDL_Surface *GetShield();
	void Colorize(Uint8 r, Uint8 g, Uint8 b);
	int CountSlots();
	int GetSlotCount();
	std::string GetSSlotCount();
	void ZeroSlots();
	void FillSlots();
	__ship_slot *GetSlots();
private:
	std::string name;
	std::string fpk;
	std::string imagefn;
	SDL_Surface *image;
	bool hasShield;
	std::string shieldfn;
	std::string sprice;
	std::string shullhitmax;
	int hullhitmax;
	int w, l, d;
	int shootx, shooty;
	unsigned int price;
	std::string sw, sl, sd;
	int slotcount;
	__ship_slot slots[__MAXSHIPSLOTS];
	SDL_Surface *shield;
};

class FPKEngine
{
public:
	FPKEngine(std::string sfpk, std::string shipname);
	~FPKEngine();
	void GetFileInfo(std::string sfpk, std::string engine);
	void Reload(std::string sfpk, std::string engine);
	std::string GetName();
	std::string GetFPK();
	std::string GetImageFN();
	int GetMaxSpeed();
	std::string GetMaxWarp();
	int GetMaxWarpSpeed();
	std::string GetMaxSafeWarp();
	int GetMaxSafeWarpSpeed();
	int GetTurnDelay();
	int GetWarpTurnDelay();
	unsigned int GetPrice();
	std::string GetSPrice();
	int GetOverHeatMax();
	SDL_Surface *GetImage();
private:
	std::string name;
	std::string fpk;
	std::string imagefn;
	SDL_Surface *image;
	std::string sMaxwarp;
	std::string sMaxsafewarp;
	std::string sprice;
	int maxspeed;
	int maxwarp, maxsafewarp;
	unsigned int price;
	int turndelay, warpturndelay;
	int overheatmax;
};

class Preferences
{
public:
	Preferences(std::string fn);
	~Preferences();
	void Load();
	void Save();
	void ChangeInput(FFTInput *input);
	FFTInput *GetInput();
private:
	std::string filename;
	DataNode *root;
};

#endif /* __FFTFILE_H__ */

