/**
    File        : File.h
    Description : File access
    Author      : Raymond Marsh
    Created     : 08/01/2009
    Copyright 2009, 2010 Raymond Marsh

    This program is distributed under the terms of the GNU General Public License.
    To view a copy of the license see the file 'copying.txt'

    This file is part of the Ace Personal Finance Assistant Suite.

    Ace Personal Finance Assistant is free software: you can redistribute it and/or modify it under
    the terms of the GNU General Public License as published by the Free Software Foundation, either
    version 3 of the License, or (at your option) any later version.

    Ace Personal Finance Assistant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with Ace Personal Finance Assistant.
    If not, see <http://www.gnu.org/licenses/>.
**/

#ifndef FILE_H_INCLUDED
#define FILE_H_INCLUDED

#include <fstream>
#include "Base.h"
#include "Dialogs.h"

class CFileBase
{
    public:
    virtual ~CFileBase() { }
    virtual bool IsOpen() = 0;
};

class CInFile : public CFileBase
{
    public:
    CInFile(wxString& FileName, bool Create = true);
    ~CInFile();
    bool IsOpen()             { return m_iFile.is_open(); }
    bool HasMoreRecords()     { return !m_iFile.eof(); }
    int GetSizeOfNextRecord();
    bool ReadObject(STransaction& Transaction);
    bool ReadObject(SReoccuringTransaction& Transaction);
    bool ReadObject(SAccountInfo& ai);
    bool ReadString(wxString& String)
    {
        const int Size = GetSizeOfNextRecord();
        if (Size > 0)
        {
            char* chStr = new char[Size];
            m_iFile.read(chStr, Size);
            String = chStr;
            String.Truncate(Size);
            delete[] chStr;
        }
        else
            String = "";
        return !m_iFile.fail();
    }
    template <class T>
    bool Read(T& Value)
    {
        char chValue[sizeof(T) ];
        T* pValue;
        m_iFile.read(chValue, sizeof(T) );
        pValue = reinterpret_cast<T*>(chValue);
        Value = *pValue;
        return !m_iFile.fail();
    }

    private:
    std::ifstream  m_iFile;
    wxString       m_FileName;
};

class COutFile : public CFileBase
{
    public:
    COutFile(wxString FileName, bool Trunc = true, bool Create = true);
    ~COutFile();
    bool IsOpen()     { return m_oFile.is_open(); }
    bool WriteObject(STransaction& Transaction);
    bool WriteObject(SReoccuringTransaction& Transaction);
    bool WriteObject(SAccountInfo& ai);
    bool WriteString(wxString& String)
    {
        int len = (int)String.Len();
        m_oFile.write(reinterpret_cast<char*>(&len), sizeof(int) );
        if (len > 0)
            m_oFile.write(String.c_str(), (std::streamsize)len);
        return !m_oFile.fail();
    }
    template <class T>
    bool Write(T& Value)
    {
        m_oFile.write(reinterpret_cast<char*>(&Value), (std::streamsize)sizeof(T) );
        return !m_oFile.fail();
    }

    private:
    std::ofstream  m_oFile;
    wxString       m_FileName;
};

#endif // FILE_H_INCLUDED
