#include "file.hpp"

extern "C" {
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <string.h>
#include <dos.h>
}

File::File(LPSTR pPath, WORD Style)
{
  struct stat FStatus;
  int Fhnd;
  WORD oStyle=Style;
  if (oStyle==OF_EXIST) oStyle=OF_READ;
  Fhnd=OpenFile((LPSTR)pPath,(LPOFSTRUCT)&OfStruct, oStyle);
  if (Fhnd==-1) {
    if(Style==OF_READ)Error(IDS_CANTREAD,(LPSTR)OfStruct.szPathName);
    else if(Style==OF_CREATE)Error(IDS_CANTCREATE,(LPSTR)OfStruct.szPathName);
    else if(Style==OF_WRITE)Error(IDS_CANTWRITE,(LPSTR)OfStruct.szPathName);
    else if(Style==OF_READWRITE)Error(IDS_CANTOPEN,(LPSTR)OfStruct.szPathName);
    FileSize=0;
    bOpened=FALSE;
  }
  else {
    FileSize=_llseek(Fhnd,0,2);   // seek to end
    _llseek(Fhnd,0,0);		  // seek back to start
    _close(Fhnd);
    bOpened=TRUE;
  }
  SeekPos=0;
}

LPSTR File::Path()
{
  return (LPSTR)OfStruct.szPathName;
}

DWORD File::Read(Memory * pMem, DWORD Size)
{
  Lock MemLock(pMem);
  return Read((LPSTR)MemLock.Buffer,Size);
}

DWORD File::Read(LPSTR pBuffer, DWORD Size)
{
  int Fhnd;
  DWORD Result=0;
  if (!FileSize|| !pBuffer || !bOpened) return 0;
  Fhnd=OpenFile("",(LPOFSTRUCT)&OfStruct, OF_READ |OF_REOPEN);
  if (Fhnd==-1) Error(IDS_CANTREAD,(LPSTR)OfStruct.szPathName);
  else {
    if(_llseek(Fhnd,SeekPos,0)==-1) return 0;
    Result=_lread(Fhnd,pBuffer,Size);
    _close(Fhnd);
  }
  SeekPos +=Result;
  return Result;
}

DWORD File::Write(Memory * pMem, DWORD Size)
{
  Lock MemLock(pMem);
  return Write((LPSTR)MemLock.Buffer,Size);
}

DWORD File::Write(LPSTR pBuffer, DWORD Size)
{
  int Fhnd;
  DWORD Result=0;
  if (!Size || !pBuffer || !bOpened) return 0;
  Fhnd=OpenFile("",(LPOFSTRUCT)&OfStruct, OF_WRITE |OF_REOPEN);
  if (Fhnd==-1) Error(IDS_CANTWRITE,(LPSTR)OfStruct.szPathName);
  else {
    if(_llseek(Fhnd,SeekPos,0)==-1) return 0;
    Result=_lwrite(Fhnd,pBuffer,Size);
    _close(Fhnd);
  }
  SeekPos +=Result;
  if (SeekPos>FileSize) FileSize=SeekPos;
  return Result;
}

File& File::operator=(File& File2)
{
  DWORD BufSize=GlobalCompact(0);
  if (BufSize>0x4000) BufSize=0x4000;
  GlobalMem Mem(BufSize);
  DWORD BytesRead=1;
  while (BytesRead) {
    BytesRead=File2.Read(&Mem,BufSize);
    BytesRead=Write(&Mem,BytesRead);
  }
  return File2;
}

DWORD File::Size()
{
  return FileSize;
}
