//Screen.h: Файл заголовка
//

#pragma once
#include "LockVarType.h"
#include "Screen_Shared.h"

// CScreen
#define SCREEN_WIDTH 512
#define SCREEN_HEIGHT 256
//если уменьшить до 1, получается уж очень мутная текстура
#define TEXTURE_MULTIPLER_X 2
#define TEXTURE_MULTIPLER_Y 2

class CScreen : public CWnd
{
		DECLARE_DYNAMIC(CScreen)

		BKSCREENHANDLE m_pscrSharedFunc;
		HMODULE m_hModule;
		using GETBKSCR = BKSCREENHANDLE(WINAPI *)();

		union BCOLOR
		{
			uint32_t dw;
			uint8_t bb[sizeof(uint32_t)];
		};

		static const int    TEXTURE_WIDTH, TEXTURE_HEIGHT;
		static const double BK_ASPECT_RATIO;
		static const int    BK_SCREEN_WIDTH, BK_SCREEN_HEIGHT;
		//16kPage
		uint8_t            *m_pBuffer;
		size_t              m_nBufSize;

		bool                m_bReverseScreen; //флаг перевёрнутого экрана.
		/* DrawDIB в отличие всех остальных рисует вверх ногами.
		или наоборот, все остальные в отличие от DrawDIB рисуют вверх ногами. Поэтому для определения
		направления введён этот флаг. */
		CString             m_strDllName;

	protected:
		CWnd               *m_pwndParent; //указатель на родительское окно (View)
		int                 m_nFrame; //счётчик фреймов
		int                 m_nCurFPS; //текущее значение  FPS
		uint32_t            m_msec; //счётчик миллисекунд, прошедшие с момента старта системы
		uint8_t             m_nOfs; //смещение экрана. Используется только в отладочном методе прорисовки экрана
		int                 m_nPaletteNum;
		bool                m_bColorMode; //флаг работы в цветном режиме
		bool                m_bAdapt; //флаг работы в ч/б адаптивном режиме
		bool                m_bExtended; //флаг расширенного режима.
		bool                m_bLuminoforeEmul; //флаг режима плавного затухания люминофора
		LockVarType         m_lockChangeMode; //флаг, пока переключаются режимы экрана,чтобы в это время не рисовался экран
		LockVarType         m_lockPrepare;
		LockVarType         m_lockBusy;

		uint32_t           *m_pColTable32;
		uint32_t           *m_pMonoTable32;
		uint32_t           *m_pTexBits; //указатель на выделенную память текстуры. здесь с ним ничего делать не нужно.

	public:
		CScreen(int nRenderType);
		CScreen(int nRenderType, uint8_t *buffer, size_t size); //16kpage
		void ChangeBuffer(uint8_t *buffer, size_t size) //16kpage
		{
			m_pBuffer = buffer;
			m_nBufSize = size;
		}
		virtual ~CScreen() override;
		void InitVars(int nRenderType);
		void ClearObjects();
		virtual void ReDrawScreen() //16kpage
		{
			PrepareScreenRGB32(m_pBuffer);
			DrawScreen();
		};
		virtual void        DrawScreen(bool bCheckFPS = false);
		virtual void        PrepareScreenLineByteRGB32(int nLineNum, int nByteNum, uint8_t b);
		virtual void        PrepareScreenLineWordRGB32(int nLineNum, int nByteNum, uint16_t w);
#ifdef _DEBUG
		void                PrepareScreenLineByte_Debug(int nLineNum, int nByteNum);
#endif
		virtual void        PrepareScreenRGB32(uint8_t *ScreenBuffer);
		virtual void        AdjustLayout();
		// Screen own methods
		virtual void        SetRegister(uint16_t w)
		{
			SetOffset(LOBYTE(w));
			SetExtendedMode((w & 01000) == 0);
		}
		inline virtual void SetOffset(uint8_t nOfs)
		{
			m_nOfs = nOfs;
		}
		inline virtual uint8_t GetOffset()
		{
			return m_nOfs;
		}
		inline virtual void SetExtendedMode(bool bFlag)
		{
			m_bExtended = bFlag;
		}
		inline virtual bool GetExtendedMode()
		{
			return m_bExtended;
		}
		inline virtual void SetLuminoforeEmuMode(bool bFlag)
		{
			m_bLuminoforeEmul = bFlag;
		}
		inline virtual bool GetLuminoforeEmuMode()
		{
			return m_bLuminoforeEmul;
		}
		inline virtual int  GetFPS()
		{
			return m_nCurFPS;
		}
		inline virtual int  GetPalette()
		{
			return m_nPaletteNum;
		}
		virtual void        SetPalette(int palette)
		{
			m_nPaletteNum = palette & 0xf;
		}

		virtual void        SetAdaptMode(bool bFlag)
		{
			m_bAdapt = bFlag;
			InitColorTables();
		}
		inline virtual bool IsAdaptMode()
		{
			return m_bAdapt;
		}

		virtual void        SetColorMode(bool bColorMode = true);
		inline virtual bool IsColorMode()
		{
			return m_bColorMode;
		}
		virtual bool        SetFullScreenMode();
		virtual bool        SetWindowMode();
		virtual bool        IsFullScreenMode();

		inline virtual CWnd *GetBackgroundWindow()
		{
			return this;
		}
		virtual HBITMAP     GetScreenshot();

	protected:
		virtual bool        InitColorTables();

		virtual BOOL PreCreateWindow(CREATESTRUCT &cs) override;
		virtual BOOL PreTranslateMessage(MSG *pMsg) override;

		afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg BOOL OnEraseBkgnd(CDC *pDC);
		afx_msg void OnDestroy();
		afx_msg void OnPaint();
		DECLARE_MESSAGE_MAP()
};


