#pragma once
#include "BKFloppyImage_Prototype.h"

#pragma pack(push)
#pragma pack(1)
struct MicrodosFileRecord
{
	uint8_t dir_dir;	/*статус записи: бит 7 - бэд блок, остальные значения - неизвестно */
	uint8_t dir_num;	/*статус записи: значения неизвестны */
	uint8_t name[14];	//имя файла, если начинается с 0177 - каталог. и значит это не микродос
	uint16_t start_block;//начальный блок
	uint16_t len_blk;	//длина в блоках, если len_blk == 0 то это тоже с большой долей вероятности каталог
	uint16_t address;	//стартовый адрес
	uint16_t length;	//длина, или остаток длины от длины в блоках, если размер файла > 64кб
	MicrodosFileRecord()
	{
		memset(this, 0, sizeof(MicrodosFileRecord));
	}
	MicrodosFileRecord &operator = (const MicrodosFileRecord &src)
	{
		memcpy(this, &src, sizeof(MicrodosFileRecord));
		return *this;
	}
	MicrodosFileRecord &operator = (const MicrodosFileRecord *src)
	{
		memcpy(this, src, sizeof(MicrodosFileRecord));
		return *this;
	}
};
#pragma pack(pop)

constexpr auto FMT_MIKRODOS_CAT_RECORD_NUMBER = 030;
constexpr auto FMT_MIKRODOS_TOTAL_FILES_USED_BLOCKS = 032;
constexpr auto FMT_MIKRODOS_DISK_SIZE = 0466;
constexpr auto FMT_MIKRODOS_CAT_BEGIN = 0500;

class CBKFloppyImage_MicroDos :
	public CBKFloppyImage_Prototype
{
		uint8_t *m_pCatBuffer;      //буфер каталога
		int     m_nCatSize;         //размер буфера каталога, выровнено по секторам, включая служебную область
		int     m_nMKCatSize;       //размер каталога в записях
		int     m_nMKLastCatRecord; //индекс последней записи в каталоге, чтобы определять конец каталога

		/* поиск заданной записи в каталоге.
		делается поиск на полное бинарное соответствие
		выход: -1 если не найдено,
		номер записи в каталоге - если найдено.
		*/
		int     FindRecord(MicrodosFileRecord *pMKRec);
		/* поиск заданной записи в каталоге.
		если bFull==false делается поиск по имени
		если bFull==true делается поиск по имени и другим параметрам
		выход: -1 если не найдено,
		номер записи в каталоге - если найдено.
		*/
		int     FindRecord2(MicrodosFileRecord *pMKRec, bool bFull = true);

		bool Squeeze();

	protected:
		virtual void ConvertAbstractToRealRecord(AbstractFileRecord *pFR, bool bRenameOnly = false) override;
		virtual void ConvertRealToAbstractRecord(AbstractFileRecord *pFR) override;

	public:
		CBKFloppyImage_MicroDos(const PARSE_RESULT &image);
		virtual ~CBKFloppyImage_MicroDos() override;

		//виртуальные функции

		/* прочитать каталог образа.
		 на выходе: заполненная структура m_sDiskCat */
		virtual bool ReadCurrentDir() override;
		/* записать каталог образа */
		virtual bool WriteCurrentDir() override;
		/* прочитать файл из образа
		* Параметры.
		* pFR - указатель на абстрактную запись о файле, внутри которой сохранена
		*       и реальная запись о файле, где сохранены все необходимые данные,
		*       даже с дублированием.
		* pBuffer - указатель на заранее выделенный массив памяти, куда будем сохранять файл.
		*   что мы будем делать потом с данными буфера, функцию не волнует. */
		virtual bool ReadFile(AbstractFileRecord *pFR, uint8_t *pBuffer) override;
		/* записать файл в образ
		* Параметры.
		* pFR - указатель на абстрактную запись о файле, внутри которой сформирована
		*       реальная запись о файле, где по возможности сохранены все необходимые данные для записи,
		*       даже с дублированием.
		* pBuffer - указатель на заранее выделенный массив памяти, где заранее подготовлен массив сохраняемого файла. */
		virtual bool WriteFile(AbstractFileRecord *pFR, uint8_t *pBuffer) override;
		/* удалить файл в образе
		* Параметры.
		* pFR - указатель на абстрактную запись о файле, внутри которой сохранена
		*       и реальная запись о файле, где сохранены все необходимые данные,
		*       даже с дублированием. */
		virtual bool DeleteFile(AbstractFileRecord *pFR, bool bForce = false) override;

		virtual bool GetNextFileName(AbstractFileRecord *pFR) override;

		virtual bool RenameRecord(AbstractFileRecord *pFR) override;
};

/*
Поскольку формат микродос остаётся тайной-тайн, будем делать так.
первые 2 байта dir_dir и dir_num будем просто игнорировать, кроме бита 7 первого байта.
каталогов нет. в ячейке 030 - общее кол-во записей.
*/