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

#include <mutex>

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

class CDumpListCtrl :
	public CMultiEditListCtrl
{
	// переменные, чтобы можно было листать в ограниченном пространстве,
	// например в окне 16 кб.
		int                 m_nBaseAddr;	// начальный адрес
		int					m_nLength;		// длина участка
		int					m_nBaseEndAddr;	// конечный адрес == m_nBaseAddr + m_nLength

		DUMP_DISPLAY_MODE   m_DisplayMode;

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

		std::mutex          m_lock;

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

		enum DUMP_LISTW : int
		{
			W_ADDR = 0,
			W_COL1,
			W_COL2,
			W_COL3,
			W_COL4,
			W_ASCII
		};
		enum DUMP_LISTB : int
		{
			B_ADDR = 0,
			B_COL1,
			B_COL2,
			B_COL3,
			B_COL4,
			B_COL5,
			B_COL6,
			B_COL7,
			B_COL8,
			B_ASCII
		};

		void                SetAddress(uint16_t addr)
		{
			m_nDumpAddr = addr;
			if (m_nDumpAddr < m_nBaseAddr)
			{
				m_nDumpAddr = m_nBaseAddr;
			}
			else if(m_nDumpAddr >= m_nBaseEndAddr)
			{
				m_nDumpAddr = m_nBaseEndAddr - 8;
			}
		}

		uint16_t            GetAddress()
		{
			return m_nDumpAddr;
		}

		void                Init(DUMP_DISPLAY_MODE mode);
		void                RefreshItems(uint16_t nNewAddr = 0, bool bNewAddrIsValid = false);
		
		void                SetDisplayMode(DUMP_DISPLAY_MODE mode);

		inline const DUMP_DISPLAY_MODE GetDisplayMode()
		{
			return m_DisplayMode;
		}

		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);

		void				AddrPlus(int nValue)
		{
			m_nDumpAddr += nValue;
			if (m_nDumpAddr >= m_nBaseEndAddr)
			{
				m_nDumpAddr -= m_nLength;
			}
		}
		void				AddrMinus(int nValue)
		{
			m_nDumpAddr -= nValue;
			if (m_nDumpAddr < m_nBaseAddr)
			{
				m_nDumpAddr += m_nLength;
			}
		}


	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()
};

