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

#pragma once

#include "RegDumpView.h"
#include "MemDumpView.h"
#include "DisasmView.h"
#include "TapeCtrlView.h"
#include "OscillatorView.h"
#include "PrintDlg.h"
#include "BKMEM_Dlg.h"
#include "SliderButton.h"

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

class CMotherBoard;
class CScreen;

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;
		CMFCStatusBar       m_wndStatusBar;

		CRegDumpView        m_registryDumpView; //панель дампа регистров
		CMemDumpView        m_memoryDumpView;   //панель дампа памяти
		CDisasmView         m_DisassembleView;  //панель отладчика
		CTapeCtrlView       m_tapeCtrlView;     //панель управления записью
		COscillatorlView    m_OscillatorView;   //панель осциллографа

		static const char LatShiftDigitTable[10];
		static const char RusShiftDigitTable[10];
		static const char RusAlphaBetTable[26];
		static const char RusAlphaBetTableShift[26];

		enum                {STATUS_PANE_SYSTEM = 0, STATUS_PANE_KBD_XLAT, STATUS_PANE_KBD_CAPS, STATUS_PANE_KBD_AR2, STATUS_PANE_KBD_SU, STATUS_PANE_INFO};
		enum                {PRINT_LINES_PER_PAGE = 66};
		enum                {PRINT_TAB_LENGTH = 8};

		LockVarType         m_lockDrawUI;   //блокировка на всякий случай. А то иногда случалось, при закрытии проги
		// окошко уже разрушалось, а обновление данных в окошках в своих потоках ещё пыталось продолжаться.

		CMutex              m_mtInstance;   //мутекс, предназначенный для запуска только одной копии программы (пока не функционирует как надо)
		CBKMEMView          *m_pBKMemView;  //объект отображения карты памяти
		LockVarType         m_lockBKMemViewOpen;   //флаг, что m_pBKMemView достоверен
		CRect               m_rectMemMap;   //координаты окна карты памяти
		// Эмулятор
		DWORD               m_dwBKBoardModel;   //тип эмулируемой модели БК (для конструктора конфигураций)
		CMotherBoard        *m_pChip;       //объект материнской платы БК
		CBkSound            *m_pSound;      //модуль звуковой подсистемы
		CDebugger           m_debugger;     //отладчик
		CScreen             *m_pScreen;     //модуль подсистемы вывода на экран

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

		CScriptRunner       m_script;       //объект обработчика скриптов
		CDropTarget         m_dropTarget;   //объект поддержки драг-н-дропа (вроде даже работает)
		//счётчики
		int                 m_nSecondsCounter;  //счётчик секунд, сколько работает эмулятор
		int                 m_nTickCounter;     //счётчик тиков в секунде, сколько раз MainLoop выполняется в секунду
		int                 m_nRegsDumpCounter; //счётчик. через сколько m_nTickCounter обновлять на экране дамп регистров
		//Клавиатура
		BOOL                m_bIsAr2Press;      //флаг нажатия АР2
		BOOL                m_bIsShiftPress;    //флаг нажатия шифта
		BOOL                m_bIsSuPress;       //флаг нажатия СУ
		BOOL                m_bIsZaglPress;     // TRUE - загл, FALSE - стр
		BOOL                m_bXlatMode;        // TRUE - рус, FALSE - лат
		BOOL                m_bIsKeyPress;      //флаг нажатия и удержания любой алфавитно-цифровой клавиши (для отключения автоповтора)
		int                 m_nKeyboardInterrupt; //адрес вектора прерывания
		BOOL                m_bLongResetPress;  //специально для А16М, вводим длинный ресет

		//имена файлов, получаемых через ДнД или командную строку
		CString             m_strBinFileName;
		CString             m_strMemFileName;
		CString             m_strTapeFileName;
		CString             m_strScriptFileName;
		//начальные флаги диалога печати
		BOOL                m_bPrintScreen;
		BOOL                m_bPrintInverse;
		CString             m_strPrintTitle;

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

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

		BOOL                ParseCommandLineParameters(CString strCommands);
		void                SetupConfiguration(int nConf = 0);
		BOOL                ConfigurationConstructor(int configuration, BOOL bStart = TRUE);
		void                AttachObjects();

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

		void                OutKeyboardSstatus(int pane);
		int                 TranslateKey(int key, UINT bExtended, BOOL &bSuccess);
		int                 LatModeTranslation(int key);
		int                 RusModeTranslation(int key);

		void                EmulateTapeOperation();
		BOOL                EmulateJoystickDown(UINT nChar, UINT nRepCnt, UINT nFlags);
		BOOL                EmulateJoystickUp(UINT nChar, UINT nRepCnt, UINT nFlags);

		BOOL                LoadMemoryState(CString strPath);
		BOOL                SaveMemoryState(CString strPath);

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

		void                SetFocusToBK();
		void                SetFocusToDebug();
		BOOL                MakeScreenShot();
		void                Print(CPrintDlg *pPrintDlg, WORD startAddress, WORD endAddress);
		WORD                PrintPage(CDC *pDC, CPrintInfo *pInfo, WORD currAddress, WORD endAddress);
		void                StartPlayTape(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, NULL);    //запустить таймер для OnMainLoop
			SetTimer(BKTIMER_SET_TITLE, 200, NULL);
		}
		inline void         StopTimer()
		{
			KillTimer(BKTIMER_UI_REFRESH);    //остановить таймер для OnMainLoop
		}
		void                OnMainLoop();       //функция вызова по таймеру
		void                StopAll();          //остановить всё - процессор, BKTIMER_UI_REFRESH
		void                StartAll();         //запустить всё - процессор, BKTIMER_UI_REFRESH
		void                StopTimerThread();
		BOOL                StartTimerThread();
		//поток с точным таймером
		static UINT AFX_CDECL TimerThreadWrapper(LPVOID lpParam);
		UINT TimerThreadFunc();    //собственно функция
		CWinThread *m_pTimerThread;

		LockVarType m_lockKillTimerEvent;   //событие, говорящее, что надо бы прекратить таймировать
		LockVarType m_lockTimerWork;        //событие, говорящее, что таймер работает
// Переопределение
	public:
		virtual BOOL        PreCreateWindow(CREATESTRUCT &cs);
		virtual BOOL        LoadFrame(UINT nIDResource, DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd *pParentWnd = NULL, CCreateContext *pContext = NULL);
		virtual BOOL        OnShowPopupMenu(CMFCPopupMenu *pMenuPopup);

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

		void                SetScreen(CScreen *scr)
		{
			m_pScreen = scr;   //задание объекта экранной подсистемы. Он создаётся в другом месте
		}
		//выдача указателей на объекты всем желающим
		inline CBkSound     *GetBKSoundPtr()
		{
			return m_pSound;
		}
		inline CDebugger    *GetDebuggerPtr()
		{
			return &m_debugger;
		}
		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_OscillatorView;
		}


// Созданные функции схемы сообщений
	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 int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnViewCustomize();
		afx_msg LRESULT OnToolbarCreateNew(WPARAM wp, LPARAM lp);
		afx_msg LRESULT OnToolbarReset(WPARAM wp, LPARAM lp);
		afx_msg void OnApplicationLook(UINT id);
		afx_msg void OnUpdateApplicationLook(CCmdUI *pCmdUI);
		afx_msg void OnLVolumeSlider(NMHDR *pNMHDR, LRESULT *pResult);

		afx_msg LRESULT OnDisplayChange(WPARAM wParam, LPARAM lParam);
		afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg LRESULT OnEmulateTape(WPARAM wParam, LPARAM lParam);
		afx_msg LRESULT OnCpuBreak(WPARAM wParam, LPARAM lParam);

		afx_msg void OnViewFullscreenmode();
		afx_msg void OnUpdateViewColormode(CCmdUI *pCmdUI);
		afx_msg void OnViewColormode();
		afx_msg void OnUpdateViewAdaptivebwmode(CCmdUI *pCmdUI);
		afx_msg void OnViewAdaptivebwmode();
		afx_msg void OnUpdateOptionsEnableSpeaker(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableSpeaker();
		afx_msg void OnUpdateOptionsEnableCovox(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableCovox();
		afx_msg void OnUpdateOptionsStereoCovox(CCmdUI *pCmdUI);
		afx_msg void OnOptionsStereoCovox();
		afx_msg void OnCpuResetCpu();
		afx_msg void OnCpuLongReset();
		afx_msg void OnUpdateCpuAccelerate(CCmdUI *pCmdUI);
		afx_msg void OnCpuAccelerate();
		afx_msg void OnUpdateCpuSlowdown(CCmdUI *pCmdUI);
		afx_msg void OnCpuSlowdown();
		afx_msg void OnUpdateCpuRunbk001001(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001();
		afx_msg void OnUpdateCpuRunbk001001Focal(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Focal();
		afx_msg void OnUpdateCpuRunbk00100132k(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk00100132k();
		afx_msg void OnUpdateCpuRunbk001001Fdd16k(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Fdd();
		afx_msg void OnUpdateCpuRunbk001001Fdd(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001Fdd16k();
		afx_msg void OnUpdateCpuRunbk0011m(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011m();
		afx_msg void OnUpdateCpuRunbk0011mFDD(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFDD();
		afx_msg void OnUpdateCpuRunbk0011mFddA16m(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk001001FddSmk512();
		afx_msg void OnUpdateCpuRunbk001001FddSmk512(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFddA16m();
		afx_msg void OnUpdateCpuRunbk0011mFddSmk512(CCmdUI *pCmdUI);
		afx_msg void OnCpuRunbk0011mFddSmk512();
		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 OnUpdateOptionsEmulateBkkeyboard(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateBkkeyboard();
		afx_msg void OnUpdateOptionsEnableJoystick(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEnableJoystick();
		afx_msg void OnUpdateOptionsUseSavesdirectory(CCmdUI *pCmdUI);
		afx_msg void OnOptionsUseSavesdirectory();
		afx_msg void OnUpdateOptionsShowPerformanceOnStatusbar(CCmdUI *pCmdUI);
		afx_msg void OnOptionsShowPerformanceOnStatusbar();
		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 OnOptionsEnableAy8910();
		afx_msg void OnUpdateOptionsEnableAy8910(CCmdUI *pCmdUI);
		afx_msg void OnFileLoadstate();
		afx_msg void OnFileSavestate();
		afx_msg void OnFileLoadtape();
		afx_msg void OnFilePrint();
		afx_msg void OnUpdateDebugBreak(CCmdUI *pCmdUI);
		afx_msg void OnDebugBreak();
		afx_msg void OnCpuNormalspeed();
		afx_msg void OnDebugStepinto();
		afx_msg void OnDebugStepover();
		afx_msg void OnDebugStepout();
		afx_msg void OnDebugRuntocursor();
		afx_msg void OnUpdateDebugStepinto(CCmdUI *pCmdUI);
		afx_msg void OnUpdateDebugStepover(CCmdUI *pCmdUI);
		afx_msg void OnUpdateDebugStepout(CCmdUI *pCmdUI);
		afx_msg void OnUpdateDebugRuntocursor(CCmdUI *pCmdUI);
		afx_msg void OnUpdateOptionsEmulateTapeLoading(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateTapeLoading();
		afx_msg void OnUpdateOptionsEmulateTapeSaving(CCmdUI *pCmdUI);
		afx_msg void OnOptionsEmulateTapeSaving();
		afx_msg void OnUpdateFileLoadtape(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 OnOptionsTapemanager();
		afx_msg BOOL OnCopyData(CWnd *pWnd, COPYDATASTRUCT *pCopyDataStruct);
		afx_msg void OnDebugBreakpoint();
		afx_msg void OnTimer(UINT_PTR nIDEvent);
		afx_msg void OnToolLaunch(UINT id);
		afx_msg void OnDebugDumpregsInterval(UINT id);
		afx_msg void OnUpdateDebugDumpregsInterval(CCmdUI *pCmdUI);
		afx_msg void OnFileScreenshot();
		afx_msg void OnOptionsEmulateFddio();
		afx_msg void OnUpdateOptionsEmulateFddio(CCmdUI *pCmdUI);
		afx_msg void OnDebugMemmap();
		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();
		afx_msg void OnClose();
		DECLARE_MESSAGE_MAP()
};
