
// BK.cpp : Определяет поведение классов для приложения.
//

#include "pch.h"
#include "BK.h"

#include "MainFrm.h"
#include "BKDoc.h"
#include "BKView.h"
#include "StaticLink.h"
#include "Config.h"
#include "ToolManager.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CBKApp

BEGIN_MESSAGE_MAP(CBKApp, CWinAppEx)
	ON_COMMAND(ID_APP_ABOUT, &CBKApp::OnAppAbout)
	// Стандартная команда настройки печати
	ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
END_MESSAGE_MAP()


// создание CBKApp

CBKApp::CBKApp()
	: m_strProgramTitleVersion(_T(""))
	, m_strProgramName(_T(""))
	, m_strCompileVersion(_T(""))
{
	m_bHiColorIcons = true;
	// TODO: замените ниже строку идентификатора приложения строкой уникального идентификатора; рекомендуемый
	// формат для строки: ИмяКомпании.ИмяПродукта.СубПродукт.СведенияОВерсии
	SetAppID(_T("gid.EMULATOR.BK0010-0011M.Win"));
	// TODO: добавьте код создания,
	// Размещает весь важный код инициализации в InitInstance
}

// Единственный объект CBKApp

CBKApp theApp;


// инициализация CBKApp

BOOL CBKApp::InitInstance()
{
	_tsetlocale(LC_ALL, _T("Russian"));
	// InitCommonControlsEx() требуются для Windows XP, если манифест
	// приложения использует ComCtl32.dll версии 6 или более поздней версии для включения
	// стилей отображения. В противном случае будет возникать сбой при создании любого окна.
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// Выберите этот параметр для включения всех общих классов управления, которые необходимо использовать
	// в вашем приложении.
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);
	CWinAppEx::InitInstance();

	// Инициализация библиотек OLE
	if (!AfxOleInit())
	{
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}

	AfxEnableControlContainer();
	EnableTaskbarInteraction(FALSE);
	// Для использования элемента управления RichEdit требуется метод AfxInitRichEdit2()
	// AfxInitRichEdit2();
	// Стандартная инициализация
	// Если эти возможности не используются и необходимо уменьшить размер
	// конечного исполняемого файла, необходимо удалить из следующего
	// конкретные процедуры инициализации, которые не требуются
	// Измените раздел реестра, в котором хранятся параметры
	// TODO: следует изменить эту строку на что-нибудь подходящее,
	// например на название организации
	SetRegistryKey(_T("gid prod."));
	// подменим профиль, чтобы не плодить кучу разных настроек в реестре
	free((void *)m_pszProfileName); // освободим память выделенную под прошлое имя
	m_pszProfileName = _tcsdup(_T("BKEMUL2")); // зададим своё
	// LoadStdProfileSettings(0);  // Загрузите стандартные параметры INI-файла (включая MRU)
	InitContextMenuManager();
	InitKeyboardManager();
	InitTooltipManager();
	CMFCToolTipInfo ttParams;
	ttParams.m_bVislManagerTheme = TRUE;
	theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
	                                             RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
	// Зарегистрируйте шаблоны документов приложения. Шаблоны документов
	//  выступают в роли посредника между документами, окнами рамок и представлениями
	EnableD2DSupport(D2D1_FACTORY_TYPE_MULTI_THREADED);
	CSingleDocTemplate *pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
	    IDR_MAINFRAME,
	    RUNTIME_CLASS(CBKDoc),
	    RUNTIME_CLASS(CMainFrame),       // основное окно рамки SDI
	    RUNTIME_CLASS(CBKView));

	if (!pDocTemplate)
	{
		TRACE0("Не удалось создать CSingleDocTemplate.\n");
		AfxMessageBox(_T("Не удалось создать CSingleDocTemplate.\n"));
		return FALSE;
	}

	AddDocTemplate(pDocTemplate);
	// инициализируем публичные переменные
	// Version build
#define STRINGIZE1(a) #a
#define STRINGIZE(a) STRINGIZE1(a)
#if (_MSC_VER >= 1920)
	CString strVN = _T(", VS 2019");
#elif (_MSC_VER >= 1910)
	CString strVN = _T(", VS 2017");
#elif (_MSC_VER >= 1900)
	CString strVN = _T(", VS 2015");
#elif (_MSC_VER >= 1800) // 1800: MSVC 2013 (yearly release cycle)
	CString strVN = _T(", VS 2013");
#elif (_MSC_VER >= 1700)
	CString strVN = _T(", VS 2012");
#elif (_MSC_VER >= 1600)
	CString strVN = _T(", VS 2010");
#elif (_MSC_VER >= 1500)
	CString strVN = _T(", VS 2008");
#elif (_MSC_VER >= 1400)
	CString strVN = _T(", VS 2005");
#elif (_MSC_VER >= 1310)
	CString strVN = _T(", VS 2003");
#elif (_MSC_VER >= 1300)
	CString strVN = _T(", VS v7.0");
#elif (_MSC_VER >= 1200)
	CString strVN = _T(", VS v6.0");
#elif (_MSC_VER >= 1100)
	CString strVN = _T(", VS v5.0");
#else
	CString strVN = _T(", VS Old");
#endif
	m_strCompileVersion = _T("Compiled: ") + getCompileDate() + _T(' ') + getCompileTime(_T("%H:%M:%S"))
	                      + strVN + _T(" (") _T(STRINGIZE(_MSC_FULL_VER)) _T(".") _T(STRINGIZE(_MSC_BUILD)) _T(")");
	m_strProgramName = CString(m_pszExeName) + _T(".exe");;
	MakeTitleVersion();
	CString strIniFileName;
	strIniFileName.LoadString(IDS_INI_FILENAME);
	g_Config.InitConfig(strIniFileName);
	g_Config.VerifyRoms(); // проверим наличие, но продолжим выполнение при отсутствии чего-либо
	// Разрешить использование расширенных символов в горячих клавишах меню
	CMFCToolBar::m_bExtCharTranslation = TRUE;
	// Синтаксический разбор командной строки на стандартные команды оболочки, DDE, открытие файлов
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);
	// чтобы самим обрабатывать командную строку подправим немного результат парсинга.
	// в принципе можно вообще закомментировать строку выше.
	cmdInfo.m_nShellCommand = CCommandLineInfo::FileNew;
	// Включить открытие выполнения DDE
	EnableShellOpen();
	RegisterShellFileTypes(TRUE);

	// Команды диспетчеризации, указанные в командной строке. Значение FALSE будет возвращено, если
	// приложение было запущено с параметром /RegServer, /Register, /Unregserver или /Unregister.
	if (!ProcessShellCommand(cmdInfo))
	{
		TRACE0("Неверные команды диспетчеризации.\n");
		AfxMessageBox(_T("Неверные команды диспетчеризации.\n"));
		return FALSE;
	}

	// Одно и только одно окно было инициализировано, поэтому отобразите и обновите его
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();
	// вызов DragAcceptFiles только при наличии суффикса
	//  В приложении SDI это должно произойти после ProcessShellCommand
	// Включить открытие перетаскивания
	m_pMainWnd->DragAcceptFiles();
	return TRUE;
}

int CBKApp::ExitInstance()
{
	// TODO: обработайте дополнительные ресурсы, которые могли быть добавлены
	AfxOleTerm(FALSE);
	return CWinAppEx::ExitInstance();
}

// обработчики сообщений CBKApp
void CBKApp::MakeTitleVersion()
{
	DWORD dwHandle;
	DWORD dwSize = GetFileVersionInfoSize(m_strProgramName.GetString(), &dwHandle);

	if (dwSize)
	{
		auto lpData = new TCHAR[dwSize];

		if (lpData)
		{
			GetFileVersionInfo(m_strProgramName.GetString(), dwHandle, dwSize, lpData);
			UINT uBufLen;
			VS_FIXEDFILEINFO *lpfi;
			VerQueryValue(lpData, _T("\\"), (void **)&lpfi, &uBufLen);
			CString t(MAKEINTRESOURCE(IDS_EMUL_TITLE));
			CString s;
			s.Format(_T(" v%d.%d.%d.%d "),
			         HIWORD(lpfi->dwFileVersionMS), LOWORD(lpfi->dwFileVersionMS),
			         HIWORD(lpfi->dwFileVersionLS), LOWORD(lpfi->dwFileVersionLS));
#ifdef _WIN64
#define TITLE_SUFFIX _T("x64")
#else
#define TITLE_SUFFIX _T("x86")
#endif
			m_strProgramTitleVersion = t + s + TITLE_SUFFIX;
#undef TITLE_SUFFIX
			delete[] lpData;
		}
	}
}



// Диалоговое окно CAboutDlg используется для описания сведений о приложении

class CAboutDlg : public CDialogEx
{
		CStaticLink m_staticHomePage, m_staticHomePage2;
		CStaticLink m_staticGames;
		CStaticLink m_staticMail, m_staticMail2;
		CStaticLink m_staticForum;
		CStaticLink m_staticSVN, m_staticSVN2;
		CStaticLink m_staticSVN3, m_staticSVN4, m_staticSVN5;

	public:
		CAboutDlg();

// Данные диалогового окна
		enum { IDD = IDD_ABOUTBOX };

	protected:
		virtual void DoDataExchange(CDataExchange *pDX) override;    // поддержка DDX/DDV

// Реализация
	protected:
		virtual BOOL OnInitDialog() override;
		DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_HOMEPAGE, m_staticHomePage);
	DDX_Control(pDX, IDC_STATIC_HOMEPAGE2, m_staticHomePage2);
	DDX_Control(pDX, IDC_STATIC_GAMES, m_staticGames);
	DDX_Control(pDX, IDC_STATIC_MAIL, m_staticMail);
	DDX_Control(pDX, IDC_STATIC_MAIL2, m_staticMail2);
	DDX_Control(pDX, IDC_STATIC_FORUM, m_staticForum);
	DDX_Control(pDX, IDC_STATIC_SVN, m_staticSVN);
	DDX_Control(pDX, IDC_STATIC_SVN2, m_staticSVN2);
	DDX_Control(pDX, IDC_STATIC_SVN3, m_staticSVN3);
	DDX_Control(pDX, IDC_STATIC_SVN4, m_staticSVN4);
	DDX_Control(pDX, IDC_STATIC_SVN5, m_staticSVN5);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

BOOL CAboutDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	GetDlgItem(IDC_STATIC_EMULTITLE)->SetWindowText(theApp.m_strProgramTitleVersion);
	GetDlgItem(IDC_STATIC_EMULCOMPILED)->SetWindowText(theApp.m_strCompileVersion);
	return TRUE;  // return TRUE unless you set the focus to a control
	// Исключение: страница свойств OCX должна возвращать значение FALSE
}

// Команда приложения для запуска диалога
void CBKApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

// CBKApp настройка методов загрузки и сохранения

void CBKApp::PreLoadState()
{
// это разные попап менюшки
	BOOL bNameValid;
	CString strName;
	bNameValid = strName.LoadString(IDS_EDIT_MENU);
	ASSERT(bNameValid);
	GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EDIT);
	bNameValid = strName.LoadString(IDS_EXPLORER);
	ASSERT(bNameValid);
	GetContextMenuManager()->AddMenu(strName, IDR_POPUP_EXPLORER);
	/*
	 а вот таким образом я тупо удаляю из реестра ветки с акселераторами и меню
	 перед загрузкой параметров из реестра. ибо не знаю как переписать функции LoadState и SaveState
	 так, чтобы они делали то, что мне нужно. А новые акселераторы из проги почему-то перебиваются старыми
	 из реестра, и меню, которое генерируется динамически, тоже перебивается старым меню из реестра.
	 Поэтому данные о них лучше нафиг поудалять.
	 Акселераторы и стандартный тулбар можно будет не трогать в финальной версии.
	*/
	DeleteUnneededKeys();
}

void CBKApp::LoadCustomState()
{
	TRACE0("Вызов LoadCustomState.\n");
}

void CBKApp::SaveCustomState()
{
	TRACE0("Вызов SaveCustomState.\n");
}

