///////////////////////////////////////////////////////////////////////////////
//
// File      : Tools_File_Wrapper.cpp
// Author    : Philip Hall
// Created   : 01/10/2007
//
// Copyright (C) 2007 Rebellion. All Rights Reserved
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header
#include "PC/FileSystem/Tools_File_Wrapper.h"

// Asura Platform-independent
#include "Core/Asura_String.h"
#include "Debugging/Asura_Assert.h"


Tools_File_Wrapper::Tools_File_Wrapper()
{
	m_xHandle = NULL;
}

Tools_File_Wrapper::~Tools_File_Wrapper()
{
	Close();
}

////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::Open
// Description : Open the named file for access
//
// Parameters  :
//   const char *szFilename  - Full path of file to open
//   bool bReadOnly          - Set true for readonly (otherwise readwrite)
//
// Returns     : bool - Returns true on success
///////////////////////////////////////////////////////////////////////////////
bool  Tools_File_Wrapper::Open(const char *szFilename, bool bReadOnly)
{
	m_xHandle = ::CreateFile(szFilename, bReadOnly ? GENERIC_READ : (GENERIC_READ|GENERIC_WRITE),
                             FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0 );
	return (m_xHandle != INVALID_HANDLE_VALUE);
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::Create
// Description : Create the named file for writing
//
// Parameters  :
//   const char *szFilename  - Full path of file to create
//   bool bOverwrite         - Set true to overwrite if exists
//
// Returns     : bool - Returns true on success
///////////////////////////////////////////////////////////////////////////////
bool Tools_File_Wrapper::Create(const char *szFilename, bool bOverwrite)
{
	m_xHandle = ::CreateFile(szFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ,
	                         NULL, bOverwrite ? CREATE_ALWAYS : CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0 );
	return (m_xHandle != INVALID_HANDLE_VALUE);
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::Read
// Description : Read data from this file
//
// Parameters  :
//   void *pBuffer  - Target data buffer (preallocated)
//   u_int uBufferSize - Size of target buffer
//
// Returns     : u_int - Returns number of bytes read (zero on failure/EOF)
///////////////////////////////////////////////////////////////////////////////
u_int Tools_File_Wrapper::Read(void *pBuffer, u_int uBufferSize)
{
	Asura_Assert(m_xHandle != INVALID_HANDLE_VALUE, "[Tools_File_Wrapper::Read] - Invalid handle\n");

	DWORD uBytesRead = 0;
	if ( !::ReadFile(m_xHandle, pBuffer, uBufferSize, &uBytesRead, NULL) ) { return 0; }
	return uBytesRead;
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::Write
// Description : Write the given data buffer to the file
//
// Parameters  :
//   void *pBuffer  - Data buffer to write
//   u_int uBufferSize - Size of data to write (in bytes)
//
// Returns     : u_int - Number of bytes written (0 on failure or zero input)
///////////////////////////////////////////////////////////////////////////////
u_int Tools_File_Wrapper::Write(void *pBuffer, u_int uBufferSize)
{
	Asura_Assert(m_xHandle != INVALID_HANDLE_VALUE, "[Tools_File_Wrapper::Write] - Invalid handle\n");

	DWORD uBytesWritten = 0;
	if ( !::WriteFile(m_xHandle, pBuffer, uBufferSize, &uBytesWritten, NULL) ) { return 0; }
	return uBytesWritten;
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::Close
// Description : Close this file
//
// Parameters  : none
//
// Returns     : nothing
///////////////////////////////////////////////////////////////////////////////
void  Tools_File_Wrapper::Close()
{
	if (m_xHandle != INVALID_HANDLE_VALUE)
	{
		::CloseHandle(m_xHandle);
		m_xHandle = INVALID_HANDLE_VALUE;
	}
}


////PGH////////////////////////////////////////////////////////////////////////
// Function    : Tools_File_Wrapper::FileSize
// Description : Gets the (32 bit) size of the currently open file
//
// Parameters  : none
//
// Returns     : u_int - Size of file (in bytes), max 4gb
///////////////////////////////////////////////////////////////////////////////
u_int Tools_File_Wrapper::FileSize() const
{
	Asura_Assert(m_xHandle != INVALID_HANDLE_VALUE, "[Tools_File_Wrapper::Close] - Invalid handle\n");

	return ::GetFileSize(m_xHandle, NULL);
}