// LoadImgDlg.cpp: файл реализации
//

#include "pch.h"
#include "resource.h"
#include "LoadImgDlg.h"
#include "BKMessageBox.h"

// CLoadImgDlg
#pragma warning(disable:4996)

IMPLEMENT_DYNAMIC(CLoadImgDlg, CFileDialog)

CLoadImgDlg::CLoadImgDlg(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
                         DWORD dwFlags, LPCTSTR lpszFilter, CWnd *pParentWnd, DWORD dwSize, BOOL bVistaStyle) :
	CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd, dwSize, bVistaStyle)
{
	m_ofn.hwndOwner = pParentWnd->GetSafeHwnd();
	m_ofn.Flags |= OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE;
	m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_LOAD_IMAGE);
	m_ofn.lpfnHook = OFNHookProc;
	m_ofn.lCustData = reinterpret_cast<LPARAM>(this);
}

CLoadImgDlg::~CLoadImgDlg()
    = default;


BEGIN_MESSAGE_MAP(CLoadImgDlg, CFileDialog)
END_MESSAGE_MAP()



// обработчики сообщений CLoadImgDlg
UINT_PTR CALLBACK CLoadImgDlg::OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	static CRect rectHD;
	auto obj = reinterpret_cast<CLoadImgDlg *>(lParam);
	// !!! под Win8 хук работает, но параметр ему не передаётся, поэтому обойдёмся статическими объектами

	switch (uiMsg)
	{
		case WM_INITDIALOG:
		{
			::GetWindowRect(hdlg, &rectHD);
			break;
		}

		case WM_CHILDACTIVATE:
		{
			HWND hParent = ::GetParent(hdlg);
			CRect rectFD;
			BOOL bRes = ::GetWindowRect(hParent, &rectFD);
			CRect rectHD1;
			bRes = ::GetWindowRect(hdlg, &rectHD1);
			// увеличим окно в ширину
			bRes = ::MoveWindow(hParent, rectFD.left, rectFD.top, rectFD.Width() + rectHD.Width() + 10, rectFD.Height() - rectHD.Height(), FALSE);
			// переместим превьюшку на своё новое место
			bRes = ::MoveWindow(hdlg, rectFD.Width() - 20, -355, rectHD.Width(), rectHD1.Height(), FALSE);
			break;
		}

		case WM_NOTIFY:
		{
			auto pNm = reinterpret_cast<LPNMHDR >(lParam);

			// auto pOFN = reinterpret_cast<LPOFNOTIFY >(wParam);

			if (pNm->code == CDN_SELCHANGE)
			{
				CString strPath;
				HWND hParent = ::GetParent(hdlg);
				::SendMessage(hParent, CDM_GETFILEPATH, 1024, reinterpret_cast<LPARAM>(strPath.GetBufferSetLength(1024)));
				strPath.ReleaseBuffer();
				CLoadImgDlg::DrawPreview(hdlg, strPath);
				return 0;
			}

			break;
		}
	}

	return 0;
}

void CLoadImgDlg::DrawPreview(HWND hdlg, const CString &strPath)
{
	CWnd *pDlg = CWnd::FromHandle(hdlg);
	CString strFormatName, strSystemFlag;
	GetImgFormat(strPath, strFormatName, strSystemFlag);
	pDlg->SetDlgItemText(IDC_EDIT_LI_SYSTEM, strFormatName);
	pDlg->SetDlgItemText(IDC_EDIT_LI_BOOTABLE, strSystemFlag);
}

void CLoadImgDlg::GetImgFormat(const CString &strImageName, CString &strFormatName, CString &strSystemFlag)
{
	CBKParseImage parser;
	CFileStatus fs;

	if (CFile::GetStatus(strImageName, fs))
	{
		if (fs.m_attribute & CFile::Attribute::directory)
		{
			strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_DIR));
		}
		else
		{
			PARSE_RESULT res = parser.ParseImage(std::wstring(strImageName), 0);
			strSystemFlag = _T("");

			if (res.bImageBootable)
			{
				strSystemFlag = CString(MAKEINTRESOURCE(IDS_DISK_SYSTEM));
			}

			switch (res.imageOSType)
			{
				case IMAGE_TYPE::ERROR_NOIMAGE:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_ERROR));
					break;

				case IMAGE_TYPE::ANDOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_ANDOS));
					break;

				case IMAGE_TYPE::MKDOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_MKDOS));
					break;

				case IMAGE_TYPE::AODOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_AODOS));
					break;

				case IMAGE_TYPE::NORD:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_NORD));
					break;

				case IMAGE_TYPE::MIKRODOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_MICRODOS));
					break;

				case IMAGE_TYPE::CSIDOS3:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_CSIDOS));
					break;

				case IMAGE_TYPE::RT11:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_RT11));
					break;

				case IMAGE_TYPE::NCDOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_NCDOS));
					break;

				case IMAGE_TYPE::DXDOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_DXDOS));
					break;

				case IMAGE_TYPE::MSDOS:
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_MSDOS));
					break;

				default:
				{
					strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_UNKNOWN));
					// теперь проверим на образ винчестера
					IMGFormat hddFormat;

					if (AnalyseImage(strImageName, &hddFormat))
					{
						if (hddFormat.bSamara)
						{
							strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_SAMARA));
						}
						else
						{
							strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_FORMAT_ALTPRO));
						}
					}
				}
			}
		}
	}
	else
	{
		strFormatName = CString(MAKEINTRESOURCE(IDS_DISK_NOACCESS));
	}
}

bool CLoadImgDlg::AnalyseImage(const CString &fname, IMGFormat *pFormat)
{
	bool bRet = false;
	FILE *f = nullptr;

	if ((f = _tfopen(fname, _T("rb"))) == nullptr)
	{
		return false;
	}

	bRet = ::CheckFormat(f, pFormat);
	fclose(f);
	return bRet;
}

