#ifndef BOT_IO
#define BOT_IO

#include <string.h>
#ifdef _DEBUG
#include <assert.h>
#endif

void BuildBotFileName(char *filename, char *arg1, char *arg2);
bool FileIsOlder(const char *szFileName1, const char *szFileName2);
bool IsValidFile(const char *szFileName);

class CBaseOutput
{
public:
	/* removed by harSens: doesn't seem to do anything, besides not compiling in linux
	CBaseOutput(const &CBaseOutput){}
	CBaseOutput &operator =(const &CBaseOutput){}
	*/

	char TextToDisplay[512];

	CBaseOutput(void) {strcpy(TextToDisplay, "");} // construction
	virtual ~CBaseOutput(void) {} // destruction

	virtual void Display(void);

	virtual void CheckForThrowOut(char *NewStr)
	{
		short CurrentLength = strlen(TextToDisplay);
		short NewLength = strlen(NewStr);

		if ((CurrentLength + NewLength) > 511)
			Display();
	};

	virtual void AddToTextString(const char *NewStr)
	{
		if (strlen(NewStr) < 512)
		{
			strncpy(TextToDisplay, NewStr, 512);
			TextToDisplay[512] = 0;
		}
		else
			strcpy(TextToDisplay, NewStr);

		// Display it right away
		Display();
	};

	CBaseOutput &operator <<(int i)
	{
		char temp[25] = "";
		sprintf(temp, "%d", i);

		AddToTextString(temp);

		return (*this);
	};

	CBaseOutput &operator <<(bool b)
	{
		AddToTextString((b) ? "1" : "0");
		return (*this);
	};

	CBaseOutput &operator <<(unsigned long i)
	{
		char temp[50] = "";
		sprintf(temp, "%d", i);

		AddToTextString(temp);

		return (*this);
	};

	CBaseOutput &operator <<(float f)
	{
		char temp[25] = "";
		sprintf(temp, "%f", f);
		AddToTextString(temp);
		return (*this);
	};

	CBaseOutput &operator <<(double f)
	{
		char temp[25] = "";
		sprintf(temp, "%f", f);
		AddToTextString(temp);
		return (*this);
	};

	CBaseOutput &operator <<(char *s)
	{
		AddToTextString(s);
		return (*this);
	};

	CBaseOutput &operator <<(const char *s)
	{
		AddToTextString(static_cast<const char*>(s));
		return (*this);
	};
};

class CLog
{
	bool CursedVar; // O_o otherwise started won't work :S
	bool Started;
	FILE *fLogFile;

public:
	CLog(void);
	virtual ~CLog(void);

	virtual void AddToTextString(const char *NewStr);
	virtual void Display(void);

	CLog &operator <<(int i)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return (*this);

		fprintf(fLogFile, "%i", i);
		fflush(fLogFile);
		return (*this);
	};

	CLog &operator <<(unsigned long i)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return (*this);

		fprintf(fLogFile, "%i", i);
		fflush(fLogFile);
		return (*this);
	};

	/* removed by harSens: your mum is an int64
	CLog &operator <<(__int64 i)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, "%i", i);
		fflush(fLogFile);
		return (*this);
	};
	*/

	CLog &operator <<(float f)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, "%f", f);
		fflush(fLogFile);
		return (*this);
	};

	CLog &operator <<(double f)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, "%f", f);
		fflush(fLogFile);
		return (*this);
	};

	CLog &operator <<(char s)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, "%c", s);
		fflush(fLogFile);
		return (*this);
	};

	CLog &operator <<(char *s)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, "%s", s);
		fflush(fLogFile);
		return (*this);
	};

	CLog &operator <<(const char *s)
	{
		if (!Started)
		{
			Started = true;
			char LogFileName[256] = "";
			BuildBotFileName(LogFileName, "bot_log.txt", NULL);
			fLogFile = fopen(LogFileName, "a");
			fprintf(fLogFile, "\n----------------------------------------------------------\n\n");
		}

		if (!fLogFile)
			return(*this);

		fprintf(fLogFile, s);
		fflush(fLogFile);
		return (*this);
	};

	void EndFrame(void)
	{
		if (fLogFile)
			fclose(fLogFile);
		Started = false;
	}
};

class CScreenOutput: public CBaseOutput
{
public:
	short xpos;
	short ypos;
	short R, G, B;
	short TextChannel;

	virtual void AddToTextString(const char *NewStr);
	virtual void Display(void);
};

class CLeftOutput: public CScreenOutput
{
public:
	CLeftOutput(void)
	{
		xpos = -7500;
		ypos = -5000;
		R = 255;
		G = 0;
		B = 0;
		TextChannel = 2;
	};
};

class CRightOutput: public CScreenOutput
{
public:
	CRightOutput(void)
	{
		xpos = -450;
		ypos = -1;
		R = 0;
		G = 255;
		B = 0;
		TextChannel = 3;
	};
};

class CMiddleOutput: public CScreenOutput
{
public:
	CMiddleOutput(void)
	{
		xpos = -3500;
		ypos = 300;
		R = 70;
		G = 70;
		B = 255;
		TextChannel = 4;
	};
};

#endif // BOT_IO