
// MainFrm.h : интерфейс класса CMainFrame
//

#pragma once
#include "BKView.h"
#include "RegDumpViewCPU.h"
#include "RegDumpViewFDD.h"
#include "MemDumpView.h"
#include "DisasmView.h"
#include "TapeCtrlView.h"
#include "OscillatorView.h"
#include "BKVKBDView.h"

#include "DropTarget.h"
#include "ScriptRunner.h"
#include "BkSound.h"
#include "Speaker.h"
#include "Covox.h"
#include "emu2149.h"
#include "Tape.h"
#include "LockVarType.h"
#include "Config.h"

//----мои-сообщения-----------------------------------------------------------
#define QUESTION_PRIME_HWND     0xBE
#define ANSWER_PRIME_HWND       0xDA
//----------------------------------------------------------------------------

class CMotherBoard;
class CScreen;
class CBKMEM_Dlg;

class CMainFrame : public CFrameWndEx
{
		DECLARE_DYNCREATE(CMainFrame)

		typedef struct
		{
			CString strSection;
			CString strDescription;
			CString strArguments;
			DWORD iconID;
			UINT nExtStrID;
		} initRegRaram;

		// встроенные члены панели элементов управления
		CMFCMenuBar         m_wndMenuBar;
		CMFCToolBar         m_wndToolBar;
		CMFCToolBar         m_wndToolBarSound;
		CMFCToolBar         m_wndToolBarDebug;
//		CMFCToolBarImages   m_UserImages;
		CMFCStatusBar       m_wndStatusBar;

		CRegDumpViewCPU     m_paneRegistryDumpViewCPU;  //панель дампа регистров CPU
		CRegDumpViewFDD     m_paneRegistryDumpViewFDD;  //панель дампа регистров FDD
		CMemDumpView        m_paneMemoryDumpView;       //панель дампа памяти
		CDisasmView         m_paneDisassembleView;      //панель отладчика
		CTapeCtrlView       m_paneTapeCtrlView;         //панель управления записью
		COscillatorlView    m_paneOscillatorView;       //панель осциллографа
		CBKVKBDView         m_paneBKVKBDView;           //панель виртуальной клавиатуры
//		COutputWnd          m_wndOutput;

		CMutex              m_mtInstance;       //мутекс, предназначенный для запуска только одной копии программы (пока не функционирует как надо)
		UINT                m_nInterAppGlobalMsg;   //индекс юзерского сообщения, которое будет зарегистрировано

		CBKMEM_Dlg         *m_pBKMemView;       //объект отображения карты памяти
		bool				m_bBKMemViewOpen;   //флаг, что m_pBKMemView достоверен
		CRect               m_rectMemMap;       //координаты окна карты памяти
		// Эмулятор
		CMotherBoard       *m_pChip;            //объект материнской платы БК
		CBkSound           *m_pSound;           //модуль звуковой подсистемы
		CDebugger          *m_pDebugger;
		CScreen            *m_pScreen;          //модуль подсистемы вывода на экран

		CSpeaker            m_speaker;          //объект пищалка
		CCovox              m_covox;            //объект ковокс
		CEMU2149            m_ay8910;           //объект сопроцессор Ay8910-3
		CTape               m_tape;             //объект обработчика кассет

		CScriptRunner       m_script;           //объект обработчика скриптов
		CDropTarget         m_dropTarget;       //объект поддержки драг-н-дропа (вроде даже работает)
		//счётчики
		bool                m_bBeginPeriod;
		DWORD               m_nStartTick;
		DWORD               m_nTickCounter;     //счётчик тиков в секунде, сколько раз MainLoop выполняется в секунду
		int                 m_nRegsDumpCounter; //счётчик. через сколько m_nTickCounter обновлять на экране дамп регистров
		bool                m_bLongResetPress;  //специально для А16М, вводим длинный ресет

		//имена файлов, получаемых через ДнД или командную строку
		CString             m_strBinFileName;
		CString             m_strMemFileName;
		CString             m_strTapeFileName;
		CString             m_strScriptFileName;
		//размеры экрана
		enum ScreenSizeNumber : int
		{
			SCREENSIZE_CUSTOM = 0,
			SCREENSIZE_256X192,
			SCREENSIZE_324X243,
			SCREENSIZE_432X324,
			SCREENSIZE_512X384,
			SCREENSIZE_576X432,
			SCREENSIZE_768X576,
			SCREENSIZE_1024X768,
			SCREENSIZE_NUMBER
		};
		ScreenSizeNumber    m_nScreenSize;
		int                 m_nScreen_X, m_nScreen_Y, m_nScreen_CustomX, m_nScreen_CustomY;
		static CPoint       m_aScreenSizes[SCREENSIZE_NUMBER];

	protected:
		// функции инициализации эмулятора
		void                InitEmulator();
		void                InitRegistry();

		void                RegisterDefaultIcon(CString &strName, initRegRaram *regParam);
		void                RegisterShellCommand(CString &strName, initRegRaram *regParam);

		bool                ParseCommandLineParameters(CString strCommands);
		void                SetupConfiguration(CONFIG_BKMODEL_NUMBER nConf = CONFIG_BKMODEL_NUMBER_BK_0010_01);
		bool                ConfigurationConstructor(CONFIG_BKMODEL_NUMBER nConf, bool bStart = true);
		bool                ConfigurationConstructor_LoadConf(CONFIG_BKMODEL_NUMBER nConf);
		void                AttachObjects();

		void                UpdateTapeDlgControls();   //изменение состояния кнопок Запись и Стоп в панели управления записью
		void				UpdateToolbarDriveIcons();
		void				UpdateToolbarSize();
		void				ResetToolbar(UINT uiToolBarId);


		bool                LoadMemoryState(CString strPath);
		bool                SaveMemoryState(CString strPath);

		void                SetDebugCtrlsState();
		void                SetDebugCtrlsState(WORD debugAddress);

		bool                MakeScreenShot();

		void                StartPlayTape(const CString &strPath);
		void                ClearProcessingFiles();
		bool                ProcessFile(bool type = false);  //тип - признак, откуда вызывается функция
		//работа с иконками загрузки/выгрузки образов на панели инструментов
		void                LoadFileImage(UINT nBtnID, int nDrive);
		void                ChangeImageIcon(UINT nBtnID, int nDrive);

		inline void         StartTimer()
		{
			SetTimer(BKTIMER_UI_REFRESH, 20, nullptr);    //запустить таймер для OnMainLoop
		}
		inline void         StopTimer()
		{
			KillTimer(BKTIMER_UI_REFRESH);      //остановить таймер для OnMainLoop
		}
		void                OnMainLoop();       //функция вызова по таймеру
		void                StopAll();          //остановить всё - процессор, BKTIMER_UI_REFRESH
		void                StartAll();         //запустить всё - процессор, BKTIMER_UI_REFRESH
		bool                CheckDebugMemmap();

// Переопределение
	public:
		virtual BOOL        LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd *pParentWnd = nullptr, CCreateContext *pContext = nullptr) override;
		virtual BOOL        OnShowPopupMenu(CMFCPopupMenu *pMenuPopup) override;
		virtual BOOL        PreTranslateMessage(MSG *pMsg) override;

// Реализация
	public:
		CMainFrame();
		virtual ~CMainFrame();
#ifdef _DEBUG
		virtual void        AssertValid() const;
		virtual void        Dump(CDumpContext &dc) const;
#endif
		void                SetFocusToBK();
		void                SetFocusToDebug();

		void                SetScreen(CScreen *scr, CDebugger *dbg)
		{
			m_pScreen = scr;   //задание объекта экранной подсистемы. Он создаётся в другом месте
			m_pDebugger = dbg;
		}
		//выдача указателей на объекты всем желающим
		inline CBkSound     *GetBKSoundPtr()
		{
			return m_pSound;
		}
		inline CSpeaker     *GetSpeakerPtr()
		{
			return &m_speaker;
		}
		inline CCovox       *GetCovoxPtr()
		{
			return &m_covox;
		}
		inline CEMU2149     *GetAY8910Ptr()
		{
			return &m_ay8910;
		}
		inline CTape        *GetTapePtr()
		{
			return &m_tape;
		}
		inline CScriptRunner *GetScriptRunnerPtr()
		{
			return &m_script;
		}
		inline COscillatorlView *GetOscillatorViewPtr()
		{
			return &m_paneOscillatorView;
		}

		inline CBKVKBDView *GetBKVKBDViewPtr()
		{
			return &m_paneBKVKBDView;
		}

		inline CMotherBoard *GetChip()
		{
			return m_pChip;
		}
		inline CScreen *GetScreen()
		{
			return m_pScreen;
		}
		inline CString *GetStrBinFileName()
		{
			return &m_strBinFileName;
		}
// Созданные функции схемы сообщений
	protected:
		bool CreateDockingWindows();
		void SetDockingWindowIcons(bool bHiColorIcons);
		afx_msg LRESULT OnMemMapClose(WPARAM wParam, LPARAM lParam);    //событие передаваемое из объекта карты памяти, говорящее, что оно закрывается, и не надо больше его вызывать
		afx_msg LRESULT OnMemDumpUpdate(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnDropFile(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnToolbarCreateNew(WPARAM wp, LPARAM lp);
		afx_msg LRESULT OnToolbarReset(WPARAM wp, LPARAM lp);
		afx_msg LRESULT OnScreenSizeChanged(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnEmulateTape(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnCpuBreak(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnOutKeyboardStatus(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnStartPlatform(WPARAM wParam, LPARAM lParam);

		afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnViewCustomize();
		afx_msg void OnApplicationLook(UINT id);
		afx_msg void OnUpdateApplicationLook(CCmdUI *pCmdUI);
		afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
		afx_msg void OnLVolumeSlider(NMHDR *pNMHDR, LRESULT *pResult);

		afx_msg void OnClose();
		afx_msg BOOL OnCopyData(CWnd *pWnd, COPYDATASTRUCT *pCopyDataStruct);
		afx_msg void OnTimer(UINT_PTR nIDEvent);

//меню Файл
		afx_msg void OnFileLoadstate();
		afx_msg void OnFileSavestate();
		afx_msg void OnFileLoadtape();
		afx_msg void OnUpdateFileLoadtape(CCmdUI *pCmdUI);
		afx_msg void OnFileScreenshot();
//меню Конфигурация
		afx_msg void OnCpuResetCpu();
		afx_msg void OnCpuSuResetCpu();
		afx_msg void OnCpuLongReset();
		afx_msg void OnCpuRunbk001001();
		afx_msg void OnUpdateCpuRunbk001001(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Focal();
		afx_msg void OnUpdateCpuRunbk001001Focal(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk00100132k();
		afx_msg void OnUpdateCpuRunbk00100132k(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Fdd();
		afx_msg void OnUpdateCpuRunbk001001Fdd(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Fdd16k();
		afx_msg void OnUpdateCpuRunbk001001Fdd16k(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001FddSmk512();
		afx_msg void OnUpdateCpuRunbk001001FddSmk512(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001FddSamara();
		afx_msg void OnUpdateCpuRunbk001001FddSamara(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011();
		afx_msg void OnUpdateCpuRunbk0011(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011Fdd();
		afx_msg void OnUpdateCpuRunbk0011Fdd(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011FddSmk512();
		afx_msg void OnUpdateCpuRunbk0011FddSmk512(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011FddSamara();
		afx_msg void OnUpdateCpuRunbk0011FddSamara(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011m();
		afx_msg void OnUpdateCpuRunbk0011m(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFDD();
		afx_msg void OnUpdateCpuRunbk0011mFDD(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFddA16m();
		afx_msg void OnUpdateCpuRunbk0011mFddA16m(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFddSmk512();
		afx_msg void OnUpdateCpuRunbk0011mFddSmk512(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFddSamara();
		afx_msg void OnUpdateCpuRunbk0011mFddSamara(CCmdUI *pCmdUI);
		afx_msg void OnCpuAccelerate();
		afx_msg void OnUpdateCpuAccelerate(CCmdUI *pCmdUI);
		afx_msg void OnCpuSlowdown();
		afx_msg void OnUpdateCpuSlowdown(CCmdUI *pCmdUI);
		afx_msg void OnCpuNormalspeed();
//меню Опции
		afx_msg void OnOptionsEnableSpeaker();
		afx_msg void OnUpdateOptionsEnableSpeaker(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableCovox();
		afx_msg void OnUpdateOptionsEnableCovox(CCmdUI *pCmdUI);
		afx_msg void OnOptionsStereoCovox();
		afx_msg void OnUpdateOptionsStereoCovox(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableAy8910();
		afx_msg void OnUpdateOptionsEnableAy8910(CCmdUI *pCmdUI);
		afx_msg void OnOptionsSpeakerFilter();
		afx_msg void OnUpdateOptionsSpeakerFilter(CCmdUI *pCmdUI);
		afx_msg void OnOptionsCovoxFilter();
		afx_msg void OnUpdateOptionsCovoxFilter(CCmdUI *pCmdUI);
		afx_msg void OnOptionsAy8910Filter();
		afx_msg void OnUpdateOptionsAy8910Filter(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateBkkeyboard();
		afx_msg void OnUpdateOptionsEmulateBkkeyboard(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableJoystick();
		afx_msg void OnUpdateOptionsEnableJoystick(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateFddio();
		afx_msg void OnUpdateOptionsEmulateFddio(CCmdUI *pCmdUI);
		afx_msg void OnOptionsUseSavesdirectory();
		afx_msg void OnUpdateOptionsUseSavesdirectory(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateTapeLoading();
		afx_msg void OnUpdateOptionsEmulateTapeLoading(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateTapeSaving();
		afx_msg void OnUpdateOptionsEmulateTapeSaving(CCmdUI *pCmdUI);
		afx_msg void OnOptionsTapemanager();
		afx_msg void OnAppSettings();
//меню Отладка
		afx_msg void OnDebugBreak();
		afx_msg void OnUpdateDebugBreak(CCmdUI *pCmdUI);
		afx_msg void OnDebugStepinto();
		afx_msg void OnUpdateDebugStepinto(CCmdUI *pCmdUI);
		afx_msg void OnDebugStepover();
		afx_msg void OnUpdateDebugStepover(CCmdUI *pCmdUI);
		afx_msg void OnDebugStepout();
		afx_msg void OnUpdateDebugStepout(CCmdUI *pCmdUI);
		afx_msg void OnDebugRuntocursor();
		afx_msg void OnUpdateDebugRuntocursor(CCmdUI *pCmdUI);
		afx_msg void OnDebugBreakpoint();
		afx_msg void OnDebugMemmap();
		afx_msg void OnDebugDumpregsInterval(UINT id);
		afx_msg void OnUpdateDebugDumpregsInterval(CCmdUI *pCmdUI);
		afx_msg void OnDebugDialogAskForBreak();
		afx_msg void OnUpdateDebugDialogAskForBreak(CCmdUI *pCmdUI);
		afx_msg void OnDebugPauseCpuAfterStart();
		afx_msg void OnUpdateDebugPauseCpuAfterStart(CCmdUI *pCmdUI);
		afx_msg void OnDebugEnableIclblock();
		afx_msg void OnUpdateDebugEnableIclblock(CCmdUI *pCmdUI);
//меню Вид
		afx_msg void OnOptionsShowPerformanceOnStatusbar();
		afx_msg void OnUpdateOptionsShowPerformanceOnStatusbar(CCmdUI *pCmdUI);
		afx_msg void OnVkbdtypeKeys(UINT id);
		afx_msg void OnUpdateVkbdtypeKeys(CCmdUI *pCmdUI);
		afx_msg void OnViewFullscreenmode();
		afx_msg void OnViewColormode();
		afx_msg void OnUpdateViewColormode(CCmdUI *pCmdUI);
		afx_msg void OnViewAdaptivebwmode();
		afx_msg void OnUpdateViewAdaptivebwmode(CCmdUI *pCmdUI);
		afx_msg void OnViewLuminoforemode();
		afx_msg void OnUpdateViewLuminoforemode(CCmdUI *pCmdUI);
		afx_msg void OnSetScreenSize(UINT id);
		afx_msg void OnUpdateSetScreenSize(CCmdUI *pCmdUI);
		//меню Инструменты
		afx_msg void OnToolLaunch(UINT id);
//тулбар для работы с дискетами и их меню
		afx_msg void OnFileLoadDriveA();
		afx_msg void OnFileLoadDriveB();
		afx_msg void OnFileLoadDriveC();
		afx_msg void OnFileLoadDriveD();
		afx_msg void OnUpdateFileLoadDriveA(CCmdUI *pCmdUI);
		afx_msg void OnUpdateFileLoadDriveB(CCmdUI *pCmdUI);
		afx_msg void OnUpdateFileLoadDriveC(CCmdUI *pCmdUI);
		afx_msg void OnUpdateFileLoadDriveD(CCmdUI *pCmdUI);
		afx_msg void OnFileUmountA();
		afx_msg void OnFileUmountB();
		afx_msg void OnFileUmountC();
		afx_msg void OnFileUmountD();

		DECLARE_MESSAGE_MAP()



};
