///////////////////////////////////////////////////////////////////////////////
/// @file deWinFile.cpp
///
/// @brief Simple Win32 File Class
///
/// @author Hootie
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Oct 2001
/// @author Hootie
/// @remarks Rearchitecture II
///
///////////////////////////////////////////////////////////////////////////////


//=================================================================================
// Includes
//=================================================================================

#include "deShared.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>



//=================================================================================
// deWinFile::deWinFile()
//
// Constructor 
//=================================================================================
deWinFile::deWinFile()
{
   CurrentOpenFile = NULL;
}



//=================================================================================
// deWinFile::~deWinFile()
//
// Destructor 
//=================================================================================
deWinFile::~deWinFile()
{
   if (CurrentOpenFile != NULL && CurrentOpenFile != INVALID_HANDLE_VALUE)
      CloseHandle(CurrentOpenFile);
}



//=================================================================================
// deWinFile::deWinFile()
//
// Open a file.
//=================================================================================
deBoolean deWinFile::Open(const char *FileName, const deWinFileAccessType FileAccessType,
                          const deWinFileDisposition FileDispositionType)
{
   DWORD FileAccess = 0;
   DWORD FileDisposition = 0;


   if (FileName == NULL || strlen(FileName) == 0)
      return deFALSE;

   switch (FileAccessType)
   {
      case DEWINFILE_READONLY:
         FileAccess = GENERIC_READ;
         break;

      case DEWINFILE_WRITEONLY:
         FileAccess = GENERIC_WRITE;
         break;

      case DEWINFILE_READWRITE:
         FileAccess = (GENERIC_READ | GENERIC_WRITE);
         break;

      default:
         return deFALSE;
         break;
   }

   switch (FileDispositionType)
   {
      case DEWINFILE_NEW:
         FileDisposition = CREATE_ALWAYS;
         break;

      case DEWINFILE_EXISTS:
         FileDisposition = OPEN_EXISTING;
         break;

      default:
         return deFALSE;
         break;
   }

   if (CurrentOpenFile != NULL && CurrentOpenFile != INVALID_HANDLE_VALUE)
      CloseHandle(CurrentOpenFile);

   CurrentOpenFile = CreateFile(FileName, 
                                FileAccess,
                                0,
                                NULL,
                                FileDisposition,
                                FILE_ATTRIBUTE_NORMAL,
                                NULL);

   if (CurrentOpenFile == INVALID_HANDLE_VALUE)
      return deFALSE;

   return deTRUE;
}



//=================================================================================
// deWinFile::Close()
//
// Close current file. 
//=================================================================================
deBoolean deWinFile::Close(void)
{
   if (CurrentOpenFile != NULL && CurrentOpenFile != INVALID_HANDLE_VALUE)
      CloseHandle(CurrentOpenFile);

   CurrentOpenFile = NULL;
   return deTRUE;
}



//=================================================================================
// deWinFile::Read()
//
// Read a file.
//=================================================================================
unsigned int deWinFile::Read(void *Buffer, unsigned int BufferSize)
{
   DWORD BytesRead = 0;
   BOOL ReturnValue;


   if (Buffer == NULL || BufferSize == 0)
      return 0;

   if (CurrentOpenFile == NULL || CurrentOpenFile == INVALID_HANDLE_VALUE)
      return 0;

   ReturnValue = ReadFile(CurrentOpenFile,
                          Buffer,
                          BufferSize,
                          &BytesRead,
                          NULL);

   return BytesRead;
}



//=================================================================================
// deWinFile::Write()
//
// Write a file.
//=================================================================================
unsigned int deWinFile::Write(void *Buffer, unsigned int BufferSize)
{
   DWORD BytesWritten = 0;
   BOOL ReturnValue;


   if (Buffer == NULL || BufferSize == 0)
      return 0;

   if (CurrentOpenFile == NULL || CurrentOpenFile == INVALID_HANDLE_VALUE)
      return 0;

   ReturnValue = WriteFile(CurrentOpenFile,
                           Buffer,
                           BufferSize,
                           &BytesWritten,
                           NULL);

   return BytesWritten;
}



//=================================================================================
// deWinFile::GetSize()
//
// Get size of file up to about a gigabyte.
//=================================================================================
unsigned int deWinFile::GetSize(void)
{
   DWORD FileSize = 0;


   if (CurrentOpenFile == NULL || CurrentOpenFile == INVALID_HANDLE_VALUE)
      return 0;

   FileSize = GetFileSize(CurrentOpenFile, NULL);

   if (FileSize == -1)
      return 0;

   return FileSize;
}



