#ifndef _COMMON_FILEIO_HPP_
#define _COMMON_FILEIO_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_STDIO_HPP_
#include <common/stdio.hpp>
#endif
#ifndef _COMMON_INTEL_HPP_
#include <common/intel.hpp>
#endif

class FileIO
{
public:
  enum Mode{ReadOnly,ReadWrite};
	enum ByteOrder{BigEndian,LittleEndian};
	enum SeekFrom{SeekCurrent=SEEK_CUR,SeekEnd=SEEK_END,SeekBeginning=SEEK_SET};
  enum CreationFlags{Create,CreateAlways,None};
  FileIO(void);
  FileIO(String pathFileName,ByteOrder byteOrder=LittleEndian,Mode openMode=ReadOnly,CreationFlags creationFlags=None);
	virtual ~FileIO();
  bool open(String pathFileName,ByteOrder byteOrder=LittleEndian,Mode openMode=ReadOnly,CreationFlags creationFlags=None);
  bool close(void);
  bool rewind(void);
	bool peek(BYTE &value);
	bool read(BYTE &value);
	bool read(WORD &value);
	bool read(DWORD &value);
	bool read(char *lpBuffer,DWORD lengthData);
  bool read(BYTE *lpBuffer,DWORD lengthData);
	bool read(char *lpBuffer,DWORD lengthData,int stopChar);
	bool write(BYTE value);
	bool write(WORD value);
	bool write(DWORD value);
  bool write(char *lpBuffer,DWORD lengthData);
  FileIO &operator++(void);
  FileIO &operator--(void);
  bool seek(LONG seekOffset,SeekFrom seekFrom);
	DWORD readLine(String &lineString);
  bool writeLine(const String &strLine);
	bool isOkay(void)const;
  DWORD tell(void)const;
	ByteOrder getByteOrder(void)const;
	void setByteOrder(ByteOrder byteOrder);
private:
  enum {CarriageReturn=0x0D,LineFeed=0x0A,NullChar=0x00};
	FILE *mlpFilePointer;
  ByteOrder mByteOrder;
};

inline
bool FileIO::isOkay(void)const
{
  return (mlpFilePointer?true:false);
}

inline
DWORD FileIO::tell(void)const
{
	if(!isOkay())return false;
	return ::ftell(mlpFilePointer);
}

inline
bool FileIO::read(BYTE *lpBuffer,DWORD lengthData)
{
  return read((char*)lpBuffer,lengthData);
}

inline
bool FileIO::write(BYTE value)
{
	if(!isOkay())return false;
	if(1!=::fwrite(&value,1,1,mlpFilePointer))return false;
	return true;
}

inline
FileIO::ByteOrder FileIO::getByteOrder(void)const
{
  return mByteOrder;
}

inline
void FileIO::setByteOrder(ByteOrder byteOrder)
{
  mByteOrder=byteOrder;
}
#endif
