#pragma once

#if defined(_WIN32)
#include <windows.h>
#include "fdrawcmd.h"
#endif

class CBKImgFile
{
		uint8_t         m_nCylinders{ 83 };
		uint8_t         m_nHeads{ 2 };
		uint8_t         m_nSectors{ 10 };

		FILE           *m_f{nullptr};        // если открываем образ - то это его файл
#if defined(_WIN32)
		HANDLE          m_h { INVALID_HANDLE_VALUE }; // если открываем устройство - то это его хэндл
#endif
		fs::path        m_strName;  // имя образа или устройства

		struct CHS
		{
			uint8_t c{ 0 }, h{ 0 }, s{ 0 };
		};

		CHS             ConvertLBA(const uint32_t lba) const;   // LBA -> CHS
		uint32_t        ConvertCHS(const CHS chs) const;        // CHS -> LBA
		uint32_t        ConvertCHS(const uint8_t c, const uint8_t h, const uint8_t s) const;    // CHS -> LBA
#if defined(_WIN32)
		// операция ввода вывода, т.к. оказалось, что fdraw не умеет блочный обмен мультитрековый,
		// да и позиционирование нужно делать вручную
		bool            IOOperation(const DWORD cmd, FD_READ_WRITE_PARAMS *rwp, void *buffer, const uint32_t numSectors) const;
#endif
	public:
		CBKImgFile();
		CBKImgFile(const fs::path &strName, const bool bWrite);
		~CBKImgFile();
		bool            Open(const fs::path &pathName, const bool bWrite);
		void            Close();

		// установка новых значений chs
		// если какое-то значение == 255, то заданное значение не меняется
		void            SetGeometry(const uint8_t c, const uint8_t h, const uint8_t s);
		/*
		buffer - куда читать/писать, о размере должен позаботиться пользователь
		cyl - номер дорожки
		head - номер головки
		sector - номер сектора
		numSectors - количество читаемых/писаемых секторов
		*/
		bool            ReadCHS(void *buffer, const uint8_t cyl, const uint8_t head, const uint8_t sector, const uint32_t numSectors) const;
		bool            WriteCHS(void *buffer, const uint8_t cyl, const uint8_t head, const uint8_t sector, const uint32_t numSectors) const;
		bool            ReadLBA(void *buffer, const uint32_t lba, const uint32_t numSectors) const;
		bool            WriteLBA(void *buffer, const uint32_t lba, const uint32_t numSectors) const;
		long            GetFileSize() const;
		bool            SeekTo00() const;
		bool            IsFileOpen() const;
};

