#include "stdafx.h"
#include "War3TypesAndConstants.h"
#include "War3File.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CWar3File::CWar3File() :CFile()
{
}

CWar3File::~CWar3File()
{
}


/*
ReadInt
*******
Reads an integer from the file into i.

In:
 none

Out:
 CWar3Int &i: integer read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadInt(CWar3Int &i)
{
	BOOL ret = FALSE;
	try
	{
		fread(&i, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
ReadString
**********
Reads a string from the file into str.

In:
 none

Out:
 CWar3String &szStr: string read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadString(CWar3String &szStr)
{
	BOOL ret = FALSE;
	int i = 0, size = 0, pos = 0;
	char* pBuf;

	try
	{
		pos = (int) ftell(this);
		size = (int)(filelength(fileno(this)) - pos);
		if (size > 0)
		{
			pBuf = new char[size];
			if (pBuf)
			{
				fread(pBuf, size, 1, this);
				i = 0;
				szStr = "";
				while ((i < size) && pBuf[i])
				{
					szStr += pBuf[i++];
				}
				delete []pBuf;
				pos = pos + szStr.length() + 1;
				fseek(this, pos, SEEK_SET);
				ret = TRUE;
			}
			else
			{
				ret = FALSE;
			}
		}
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
ReadFloat
*********
Reads a float from the file into f.

In:
 none

Out:
 CWar3Float &f: float read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadFloat(CWar3Float &f)
{
	BOOL ret = FALSE;
	try
	{
		fread(&f, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
ReadChar
********
Reads a char from the file into c.

In:
 none

Out:
 CWar3Char &c: char read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadChar(CWar3Char &c)
{
	BOOL ret = FALSE;
	try
	{
		fread(&c, 1, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
ReadFlags
*********
Reads an integer from the file into flags.

In:
 none

Out:
 CWar3Flags &flags: flags read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadFlags(CWar3Flags &flags)
{
	BOOL ret = FALSE;
	try
	{
		fread(&flags, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
ReadStrID
*********
Reads a String ID from the file into strID.

In:
 CWar3StrID strID: a pointer to the destination char[4] buffer

Out:
 *(CWar3StrID strID): string ID read

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::ReadStrID(CWar3StrID &strID)
{
	BOOL ret = FALSE;
	char acBuf[4];

	try
	{
		fread(acBuf, 4, 1, this);
		strID = acBuf;
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteChar
*********
Write the char c to the file.

In:
 CWar3Char c: char to be Written

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteChar(CWar3Char c)
{
	BOOL ret = FALSE;
	try
	{
		fwrite(&c, 1, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteStrID
**********
Write the string ID strID to the file.

In:
 CWar3StrID strID: string ID to be written

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteStrID(CWar3StrID strID)
{
	BOOL ret = FALSE;
	try
	{
		fwrite(strID.GetStrID(), 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteInt
********
Write the int i to the file.

In:
 CWar3Int i: int to write

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteInt(CWar3Int i)
{
	BOOL ret = FALSE;
	try
	{
		fwrite(&i, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteFlags
**********
Write the flags "flags" to the file.

In:
 CWar3Flags flags: flags to be written

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteFlags(CWar3Flags flags)
{
	BOOL ret = FALSE;
	try
	{
		fwrite(&flags, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteFloat
**********
Write the float f to the file.

In:
 CWar3Float f: the float to write

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteFloat(CWar3Float f)
{
	BOOL ret = FALSE;
	try
	{
		fwrite(&f, 4, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}


/*
WriteString
***********
Write the string szStr to the file.

In:
 CWar3String szStr: string to write

Out:
 nothing

Return:
 BOOL: TRUE if successfull, FALSE otherwise

*/
BOOL CWar3File::WriteString(CWar3String szStr)
{
	BOOL ret = FALSE;
	CWar3String szLocalStr;
	szLocalStr = szStr;
	int iStrSize;
	char cNull ='\0';

	try
	{
		// gets string size
		iStrSize = szLocalStr.length();
		// write the string content
		fwrite(szLocalStr.c_str(), iStrSize, 1, this);
		// write the ending null char
		fwrite(&cNull, 1, 1, this);
		ret = TRUE;
	}
	catch(...)
	{
		ret = FALSE;
	}
	return ret;
}