#pragma once

//набор структур енумов и функций скопирован из BKParseImage из BKDE, если там что-то поменяется, тут тоже не забыть поменять
enum IMAGE_TYPES
{
	IMAGE_TYPE_ERROR = -1,
	IMAGE_TYPE_UNKNOWN = 0,
	IMAGE_TYPE_ANDOS,
	IMAGE_TYPE_MKDOS,
	IMAGE_TYPE_AODOS,
	IMAGE_TYPE_NORD,
	IMAGE_TYPE_MIKRODOS,
	IMAGE_TYPE_CSIDOS3,
	IMAGE_TYPE_RT11,
	IMAGE_TYPE_NCDOS,
	IMAGE_TYPE_DXDOS,
	IMAGE_TYPE_MSDOS
};

struct PARSE_RESULT
{
	ULONGLONG nImageSize;
	ULONGLONG nBaseOffset;
	IMAGE_TYPES imageOSType;
	bool bImageBootable;
	CString strName;

	PARSE_RESULT()
	{
		clear();
	}

	~PARSE_RESULT()
	{
		this->strName.Empty();
	}

	void clear()
	{
		this->nBaseOffset = this->nImageSize = 0;
		this->imageOSType = IMAGE_TYPE_UNKNOWN;
		this->bImageBootable = false;
		this->strName = _T("");
	}

	PARSE_RESULT(const PARSE_RESULT *src)
	{
		this->nImageSize = src->nImageSize;
		this->nBaseOffset = src->nBaseOffset;
		this->imageOSType = src->imageOSType;
		this->bImageBootable = src->bImageBootable;
		this->strName = src->strName;
	}

	PARSE_RESULT &operator = (const PARSE_RESULT &src)
	{
		this->nImageSize = src.nImageSize;
		this->nBaseOffset = src.nBaseOffset;
		this->imageOSType = src.imageOSType;
		this->bImageBootable = src.bImageBootable;
		this->strName = src.strName;
		return *this;
	}
};

struct RT11SegmentHdr
{
	WORD segments_num;  //число сегментов, отведённых под каталог
	WORD next_segment;  //номер следующего сегмента каталога, если 0 - то этот сегмент последний
	WORD used_segments; //счётчик сегментов, имеющих записи, есть только в первом сегменте
	WORD filerecord_add_bytes;   //число дополнительных БАЙТОВ! в записи о файле в каталоге
	WORD file_block;    //номер блока, с которого начинается самый первый файл, описанный в данном сегменте

	RT11SegmentHdr()
	{
		memset(this, 0, sizeof(RT11SegmentHdr));
	}
	RT11SegmentHdr &operator = (const RT11SegmentHdr &src)
	{
		memcpy(this, &src, sizeof(RT11SegmentHdr));
		return *this;
	}
	RT11SegmentHdr &operator = (const RT11SegmentHdr *src)
	{
		memcpy(this, src, sizeof(RT11SegmentHdr));
		return *this;
	}
};


// CLoadImgDlg

class CLoadImgDlg : public CFileDialog
{
		DECLARE_DYNAMIC(CLoadImgDlg)

		static const char *strID_Andos;
		static const char *strID_DXDOS;
		static const char *strID_FAT12;
		static const char *strID_Aodos;
		static const char *strID_Nord;
		static const char *strID_Nord_Voland;
		static const char *strID_RT11;
		static const char *strID_RT11Q;

		static UINT_PTR CALLBACK OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
		static void DrawPreview(HWND hdlg, const CString &strPath);

	public:
		CLoadImgDlg(BOOL bOpenFileDialog, // TRUE для FileOpen, FALSE для FileSaveAs
		            LPCTSTR lpszDefExt = nullptr,
		            LPCTSTR lpszFileName = nullptr,
		            DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		            LPCTSTR lpszFilter = nullptr,
		            CWnd *pParentWnd = nullptr,
		            DWORD dwSize = 0,
		            BOOL bVistaStyle = FALSE); //если сделать FALSE в Win7 в отладочной версии случается debug assertion, впрочем не влияющий на работу.
		//если bVistaStyle = TRUE то не работают хуки, и принципиально невозможно как-то свою информацию показывать.
		virtual ~CLoadImgDlg();

	protected:
		static bool charcompare(BYTE a, BYTE b);
		static bool substrfind(BYTE *bufs, size_t len_bufs, BYTE *buff, size_t len_buff);
		static bool ReadLBA(CFile *f, void *buffer, ULONGLONG lba, int numSectors);

		static PARSE_RESULT ParseImage(const CString &fname, ULONGLONG nBaseOffset);
		static int IsCSIDOS3(CFile *f, ULONGLONG nBaseOffsetLBA, BYTE *buf);
		static int IsRT11_old(CFile *f, ULONGLONG nBaseOffsetLBA, BYTE *buf);
		static int IsRT11(CFile *f, ULONGLONG nBaseOffsetLBA, BYTE *buf);
		static int AnalyseMicrodos(CFile *f, ULONGLONG nBaseOffsetLBA, BYTE *buf);
		static void GetImgFormat(const CString &strImageName, CString &strFormatName, CString &strSystemFlag);

		DECLARE_MESSAGE_MAP()
};


