#pragma once

#include "BKParseImage.h"
#include "BKFloppyImage_Prototype.h"

/*
Класс, где будут все основные методы для работы с образом.
Открытие образа, закрытие,
добавление файлов/директорий (групповое)
удаление файлов/директорий (групповое и рекурсивное)
создание директорий
извлечение файлов и преобразование форматов
*/
enum class ADD_ERROR : int
{
	OK_NOERROR = 0, //нет ошибок
	IMAGE_NOT_OPEN, //файл образа не открыт
	FILE_TOO_LARGE, //файл слишком большой
	USER_CANCEL,    //операция отменена пользователем
	IMAGE_ERROR,    //ошибку смотри в nImageErrorNumber
	NUMBERS
};

extern std::wstring g_AddOpErrorStr[];

struct ADDOP_RESULT
{
	bool bFatal;    //флаг необходимости прервать работу.
	ADD_ERROR nError;    //номер ошибки в результате добавления объекта в образ
	IMAGE_ERROR nImageErrorNumber; //номер ошибки в результате операций с образом
	AbstractFileRecord afr; //экземпляр абстрактной записи, которая вызвала ошибку.
	// Она нам нужна будет для последующей обработки ошибок
	ADDOP_RESULT()
	{
		bFatal = false;
		nError = ADD_ERROR::OK_NOERROR;
		nImageErrorNumber = IMAGE_ERROR::OK_NOERRORS;
		afr.clear();
	}
};

/*
  из-за того, что как оказалось в структуре _tfinddata_t
  имя файла передаётся без пути, будем дублировать имя файла,
  но уже с путём отдельно.
*/
struct sendfiledata
{
	std::wstring strName;
	struct _tfinddata_t findFile;
};


class CBKListCtrl;

class CBKImage
{
		std::wstring             m_strStorePath;     //путь, куда будем сохранять файлы
		CBKListCtrl        *m_pListCtrl;

		PaneInfo            m_PaneInfo;
		std::vector<PaneInfo>    m_vSelItems;

		CBKFloppyImage_Prototype *m_pFloppyImage;
		std::vector<CBKFloppyImage_Prototype *> m_vpImages; //тут будут храниться объекты, когда мы заходим в лог.диски

		bool m_bCheckUseBinStatus;      //состояние чекбоксов "использовать формат бин"
		bool m_bCheckUseLongBinStatus;  //состояние чекбоксов "использовать формат бин"
		bool m_bCheckLogExtractStatus;  //и "создавать лог извлечения" соответственно, проще их тут хранить, чем запрашивать сложными путями у родителя

	protected:
		void StepIntoDir(AbstractFileRecord *fr);
		bool StepUptoDir(AbstractFileRecord *fr);
		void OutCurrFilePath();

		bool ExtractObject(AbstractFileRecord *fr);
		bool ExtractFile(AbstractFileRecord *fr);
		bool DeleteRecursive(AbstractFileRecord *fr);
		bool AnalyseExportFile(AnalyseFileStruct *a);
		void SetStorePath(const std::wstring &str);
		bool ViewFile(AbstractFileRecord *fr);
		bool ViewFileRT11(AbstractFileRecord *fr);
		bool ViewFileAsSprite(AbstractFileRecord *fr);

	public:
		CBKImage();
		~CBKImage();
		void AttachView(CBKListCtrl *pListCtrl)
		{
			m_pListCtrl = pListCtrl;
		}

		bool Open(PARSE_RESULT &pr, bool bLogDisk = false); //открыть файл по результатам парсинга
		bool ReOpen(); //переинициализация уже открытого образа
		void Close(); //закрыть текущий файл
		UINT GetImgFormatName(IMAGE_TYPE nType = IMAGE_TYPE::UNKNOWN);
		void ClearImgVector();
		void PushCurrentImg();
		bool PopCurrentImg();

		bool ReadCurrentDir(int nCursorPos);

		inline bool IsImageOpen()
		{
			return (m_pFloppyImage != nullptr);
		}

		inline bool GetImageOpenStatus()
		{
			return m_pFloppyImage->GetImageOpenStatus();
		}
		inline unsigned long GetBaseOffset() const
		{
			return m_pFloppyImage->GetBaseOffset();
		}
		inline unsigned long GetImgSize() const
		{
			return m_pFloppyImage->GetImgSize();
		}
		inline void SetCheckBinExtractStatus(bool bStatus = false)
		{
			m_bCheckUseBinStatus = bStatus;
		}
		inline void SetCheckUseLongBinStatus(bool bStatus = false)
		{
			m_bCheckUseLongBinStatus = bStatus;
		}
		inline void SetCheckLogExtractStatus(bool bStatus = false)
		{
			m_bCheckLogExtractStatus = bStatus;
		}
		void ItemProcessing(int nItem, AbstractFileRecord *fr);
		void ViewSelected(bool bViewAsText = true);
		void ExtractSelected(const std::wstring &strOutPath);
		void RenameRecord(AbstractFileRecord *fr);
		void DeleteSelected();

		//добавить в образ файл/директорию
		ADDOP_RESULT AddObject(struct sendfiledata &findFile, bool bExistDir = false);
		void OutFromDirObject(AbstractFileRecord *fr);
		//удалить из образа файл/директорию
		ADDOP_RESULT DeleteObject(AbstractFileRecord *fr, bool bForce = false);
};

