/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/sgx/filesystem/memorycard/memcardfilestate.cpp

*/

#include "sgx/core/core.hpp"
#include "sgx/filesystem/filesystem.hpp"
#include "sgx/filesystem/memorycard/memcardfile.hpp"

CSGXDeviceMemoryCardFile::CSGXDeviceMemoryCardFile(CSGXDeviceMemoryCard *pDevice, CSGXDeviceBlockMemoryCard *pBlock, const tBOOL bSaving) {
	m_CurrOffset = 0;
	m_iSize = pDevice->getBlockSize();
	m_pData = new tBYTE[m_iSize];
	m_bSaving = bSaving;
	m_pMemDevice = pDevice;
	m_pBlock = pBlock;
	//
	if (!m_bSaving) {
		// TODO: Load data from memory card (as described by pBlock) into
		// m_pData memory.
	}
}

CSGXDeviceMemoryCardFile::~CSGXDeviceMemoryCardFile()
{
	if (m_bSaving) {
		// TODO: Flush data in m_pData to card
	}
	//
	delete m_pData;
}

//
// Block State
//
tMEM_SIZE CSGXDeviceMemoryCardFile::read(tBYTE *pDest, tMEM_SIZE size)
{
    tMEM_SIZE readbytes;

    // Check if file is open? Done by filemanager? Yes!
    if (m_CurrOffset + size > m_iSize) {
        readbytes = m_iSize - m_CurrOffset;
    } else {
        readbytes = size;
    }

    sgxMemmove(pDest, &m_pData[m_CurrOffset], readbytes);
    m_CurrOffset += readbytes;
    return readbytes;
}

tMEM_SIZE CSGXDeviceMemoryCardFile::write(const tBYTE *pSource, tMEM_SIZE size)
{
    tMEM_SIZE written;

    if (m_CurrOffset + size > m_iSize) {
        written = m_iSize - m_CurrOffset;
    } else {
        written = size;
    }

    sgxMemmove(&m_pData[m_CurrOffset], pSource, written);
    m_CurrOffset += written;
    return written;
}

tBOOL CSGXDeviceMemoryCardFile::seek(tINT32 offset, CSGXDeviceBlockState::tSeekFrom from)
{
    switch(from)
    {
    case    eSeekFromBegin:   m_CurrOffset = offset; break;
    case    eSeekFromCurrent: m_CurrOffset += offset; break;
    case    eSeekFromEnd:     m_CurrOffset = m_iSize+offset; break;
    }

    return true;
}

tDISC_SIZE CSGXDeviceMemoryCardFile::getSeekPos() const
{
    return m_CurrOffset;
}
