////////////////////////////////////////////////////////////////////////////////
// Win32/File.h -- this file is part of the Emulator Developers Kit
// available at http://ourworld.compuserve.com/homepages/pc64/develop.htm

class File {
protected:

  DWORD dwDesiredAccess;
  DWORD dwShareMode;
  DWORD dwCreationDistribution;
  DWORD dwFlagsAndAttributes;
  string Name;
  HANDLE hFile;
  bool bReadOnly;
  byte abFill[3];

public:

  // constructor
  global File() {
    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
    dwShareMode = FILE_SHARE_READ;
    dwCreationDistribution = OPEN_ALWAYS;
    dwFlagsAndAttributes = FILE_FLAG_RANDOM_ACCESS;
    hFile = INVALID_HANDLE_VALUE;
    bReadOnly = false;
  }

  // destructor
  global void Close();
  virtual ~File() {
    Close();
  }

  // properties
  inline void SetShareMode(DWORD dwNewShareMode) {
    dwShareMode = dwNewShareMode;
  }
  inline void SetCreationDistribution(DWORD dwNewCreationDistribution) {
    dwCreationDistribution = dwNewCreationDistribution;
  }
  inline void SetFlagsAndAttributes(DWORD dwNewFlagsAndAttributes) {
    dwFlagsAndAttributes = dwNewFlagsAndAttributes;
  }
  global void SetName(const char* pcNewName);
  inline const string& GetName() {
    return Name;
  }
  global void SetSize(int iNewSize);
  global int GetSize();
  global void SetPosition(int iNewPosition);
  global int GetPosition();
  inline HANDLE GetHandle() {
    return hFile;
  }
  inline void SetReadOnly(bool bNewReadOnly) {
    bReadOnly = bNewReadOnly;
  }
  inline bool IsReadOnly() {
    return bReadOnly;
  }

  // access functions
  global void Read(void* pBuffer, int iCount);
  inline void Read(int iNewPosition, void* pBuffer, int iCount) {
    SetPosition(iNewPosition);
    Read(pBuffer, iCount);
  }
  global void Write(const void* pBuffer, int iCount);
  inline void Write(int iNewPosition, const void* pBuffer, int iCount) {
    SetPosition(iNewPosition);
    Write(pBuffer, iCount);
  }
};


////////////////////////////////////////////////////////////////////////////////
// special cases for sequential access

class InFile : public File {
public:
  InFile() { 
    dwDesiredAccess = GENERIC_READ;
    dwCreationDistribution = OPEN_EXISTING;
    dwFlagsAndAttributes = FILE_FLAG_SEQUENTIAL_SCAN;
    bReadOnly = true;
  }
};

class OutFile : public File {
public:
  OutFile() {
    dwDesiredAccess = GENERIC_WRITE;
    dwCreationDistribution = CREATE_ALWAYS;
    dwFlagsAndAttributes = FILE_FLAG_SEQUENTIAL_SCAN;
  }
};
