// MSFManager.h: interface for the CMSFManager class.
//


#pragma once

#include "MSF.h"
#include "Config.h"

constexpr auto MSF_STATE_ID = 65536;
constexpr auto MSF_VERSION_MINIMAL = 20;
constexpr auto MSF_VERSION_CURRENT = 20;


class CMSFManager
{
	protected:
		FILE               *m_pMSFFile;
		bool                m_bOpenForLoad;
		MSF_FILE_HEADER     m_header;

		CArray<MSF_BLOCK_INFO, MSF_BLOCK_INFO &> m_blocks;

		bool                Seek(int nOffset, UINT nFrom);
		bool                ReleaseFile();

		bool                CheckBlockSize(MSF_BLOCK_INFO *pbi, DWORD size);

	public:
		CMSFManager();
		virtual ~CMSFManager();

		bool                CheckFile(const CString &strPath, bool bSilent = false);
		bool                OpenFile(const CString &strPath, bool bLoad, bool bSilent = false);

		inline void         SetType(DWORD type)
		{
			m_header.type = type;
		}
		inline DWORD        GetType()
		{
			return m_header.type;
		}

		inline void         SetVersion(DWORD version)
		{
			m_header.version = version;
		}
		inline DWORD        GetVersion()
		{
			return m_header.version;
		}

		inline bool         IsLoad()
		{
			return m_bOpenForLoad;
		}
		inline bool         IsSave()
		{
			return !m_bOpenForLoad;
		}

		bool                FindBlock(DWORD blockType, DWORD id, MSF_BLOCK_INFO *pBi);
		bool                SetBlockHeader(MSF_BLOCK_INFO *pBi);
		bool                GetBlockHeader(MSF_BLOCK_INFO *pBi);
		bool                SetBlockData(uint8_t *pBuff, DWORD length);
		bool                GetBlockData(uint8_t *pBuff, DWORD length);

		bool                SetBlockTape(uint8_t *pPackedWave, DWORD nBitsLength, DWORD nPackLength);
		bool                GetBlockTape(uint8_t *pPackedWave, DWORD *pnBitsLength, DWORD *pnPackLength);

		bool                SetBlockPlatformData(MSF_PLATFORM_DATA *pPD);
		bool                GetBlockPlatformData(MSF_PLATFORM_DATA *pPD);

		bool                SetBlockPreview(HBITMAP hScreenshot);
		bool                GetBlockPreview(HBITMAP *hScreenshot);

		bool                SetBlockConfig();
		bool                GetBlockConfig();

		bool                SetBlockFrameData(MSF_FRAMEDATA *FDBlock);
		bool                GetBlockFrameData(MSF_FRAMEDATA *FDBlock);

		bool                SetBlockCPURegisters(MSF_CPU_REGISTERS *pCPURegisters);
		bool                GetBlockCPURegisters(MSF_CPU_REGISTERS *pCPURegisters);


		bool                GetBlockMemMap(DWORD id, BKMEMBank_t *MBType, int nMemMapSize, uint32_t &nROMPresent);
		bool                SetBlockMemMap(DWORD id, BKMEMBank_t *MBType, int nMemMapSize, uint32_t nROMPresent);

		bool                SetBlockBaseMemory(DWORD id, uint8_t *pMemory, int nSize);
		bool                GetBlockBaseMemory(DWORD id, uint8_t *pMemory, int nSize);

		bool                SetBlockPortRegs(DWORD id, MSF_PORT_REGS *pPortRegs);
		bool                GetBlockPortRegs(DWORD id, MSF_PORT_REGS *pPortRegs);

		bool                SetBlockCustomData(DWORD id, uint8_t *pData, int nSize);
		bool                GetBlockCustomData(DWORD id, uint8_t *pData, int nSize);
};

