#pragma once
#include "resource.h"
#include "MultiEditListCtrl.h"

#include <mutex>

enum DUMP_DISPLAY_MODE : int
{
	DD_WORD_VIEW = 0,
	DD_BYTE_VIEW
};

constexpr auto MAX_DUMP_COLS_WORD = 4;
constexpr auto MAX_DUMP_COLS_BYTE = 8;
constexpr auto COLUMN_WIDTH_ADDR = 60;
constexpr auto COLUMN_WIDTH_WORD = 68;
constexpr auto COLUMN_WIDTH_BYTE = 34;
constexpr auto COLUMN_WIDTH_TXT = 70;

class CDumpListCtrl :
	public CMultiEditListCtrl
{
		DUMP_DISPLAY_MODE m_DisplayMode;

		uint16_t        m_nTopAddr; //адрес верхнего итема списка
		uint16_t        m_nBottomAddr; //адрес нижнего итема списка

		std::mutex      m_lock;

	public:
		CDumpListCtrl();
		virtual ~CDumpListCtrl() override;

		enum : int
		{
			IDS_MEMORY_ADDR_WORD = 0,
			IDS_MEMORY_COLUMN1_WORD,
			IDS_MEMORY_COLUMN2_WORD,
			IDS_MEMORY_COLUMN3_WORD,
			IDS_MEMORY_COLUMN4_WORD,
			IDS_MEMORY_ASCII_WORD
		};
		enum : int
		{
			IDS_MEMORY_ADDR_BYTE = 0,
			IDS_MEMORY_COLUMN1_BYTE,
			IDS_MEMORY_COLUMN2_BYTE,
			IDS_MEMORY_COLUMN3_BYTE,
			IDS_MEMORY_COLUMN4_BYTE,
			IDS_MEMORY_COLUMN5_BYTE,
			IDS_MEMORY_COLUMN6_BYTE,
			IDS_MEMORY_COLUMN7_BYTE,
			IDS_MEMORY_COLUMN8_BYTE,
			IDS_MEMORY_ASCII_BYTE
		};

		TCHAR GetMemDumpByteAsANSI(uint8_t byte);
		void Init(DUMP_DISPLAY_MODE mode);
		void RefreshItems(uint16_t nNewAddr = 0, bool bNewAddrIsValid = false);
		inline const DUMP_DISPLAY_MODE GetDisplayMode()
		{
			return m_DisplayMode;
		}
		inline const uint16_t GetDumpAddress()
		{
			return m_nTopAddr;
		}
		void SetDumpAddr(uint16_t addr)
		{
			m_nTopAddr = addr;
			ChangeAddr();
		}
		void SetDisplayMode(DUMP_DISPLAY_MODE mode);
		void SetItemWithModifiedByte(register uint8_t byte, register int nItem, register int nSubitem, bool bColored = true);

	protected:
		void SetHeader();
		void AdjustRows();
		void AdjustScroll();
		void SetEditAddress();
		void ChangeAddr();
		void InsertNewLine(int nNum);

	protected:
		virtual BOOL PreCreateWindow(CREATESTRUCT &cs) override;
		afx_msg void OnSize(UINT nType, int cx, int cy);
		afx_msg void OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult);
		afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar);
		afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
		DECLARE_MESSAGE_MAP()
};

