#include "pch.h"

#include "RegDumpViewFDD.h"
#include "Platform.h"
#include "Screen_Sizes.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif

constexpr auto COLUMN_WIDTH_OPTOKREG = 150;
constexpr auto COLUMN_WIDTH_REG = 38;

constexpr auto COLNUM_FDD = 3;
constexpr auto ROWNUM_FDD = 3;
constexpr auto COLNUM_HDD = 6;
constexpr auto ROWNUM_HDD = 11;
constexpr auto COLNUM_OPTOK = 2;
constexpr auto ROWNUM_OPTOK = 6;


static const CRegDumpDocPaneDlgViewHelper::ColParam_t arFDDCols[COLNUM_FDD] =
{
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH, BG_COLOR},
	{COL_WIDTH, COLUMN_WIDTH, 0},
	{COL_WIDTH, COLUMN_WIDTH, 0}
};


static const CRegDumpDocPaneDlgViewHelper::CellParam_t arFDDRows[ROWNUM_FDD][COLNUM_FDD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_MODE, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_READ, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_WRITE, BG_COLOR},},
	{ {COL_VALUE | COL_COLOR, IDS_FDDLST_177130, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                             },
	{ {COL_VALUE | COL_COLOR, IDS_FDDLST_177132, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0}                                              }
};


static const CRegDumpDocPaneDlgViewHelper::ColParam_t arHDDCols[COLNUM_HDD] =
{
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH_REG, BG_COLOR},
	{COL_WIDTH, COLUMN_WIDTH, 0},
	{COL_WIDTH, COLUMN_WIDTH, 0},
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH_REG, BG_COLOR},
	{COL_WIDTH, COLUMN_WIDTH, 0},
	{COL_WIDTH, COLUMN_WIDTH, 0}
};

static const CRegDumpDocPaneDlgViewHelper::CellParam_t arHDDRows[ROWNUM_HDD][COLNUM_HDD] =
{
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_MODE, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_READ, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_WRITE, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_MODE, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_READ, BG_COLOR}, {COL_VALUE | COL_COLOR, IDS_HDDLST_HDR_WRITE, BG_COLOR}, },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F0, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F0, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F1, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F1, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F2, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F2, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F3, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F3, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F4, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F4, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F5, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F5, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F6, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F6, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F7, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_1F7, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_3F6, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_3F6, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
	{ {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_3F7, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               {COL_VALUE | COL_COLOR, IDS_HDDLST_REG_3F7, BG_COLOR},  {0, 0, 0},                                              {0, 0, 0},                                               },
};


static const CRegDumpDocPaneDlgViewHelper::ColParam_t arOPTOKCols[COLNUM_OPTOK] =
{
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH_OPTOKREG, BG_COLOR},
	{COL_WIDTH, COLUMN_WIDTH, 0}
};

static const CRegDumpDocPaneDlgViewHelper::CellParam_t arOPTOKRows[ROWNUM_OPTOK][COLNUM_OPTOK] =
{
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177620RW, BG_COLOR}, {0, 0, 0}, },
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177622RW, BG_COLOR}, {0, 0, 0}, },
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177624RW, BG_COLOR}, {0, 0, 0}, },
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177626W,  BG_COLOR}, {0, 0, 0}, },
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177626R,  BG_COLOR}, {0, 0, 0}, },
	{ {COL_VALUE | COL_COLOR, IDS_OPTOK_177630W,  BG_COLOR}, {0, 0, 0}, }
};

/////////////////////////////////////////////////////////////////////////////
// CRegDumpViewFDD
IMPLEMENT_DYNAMIC(CRegDumpViewFDD, CRegDumpDocPaneDlgViewHelper)

CRegDumpViewFDD::CRegDumpViewFDD()
    = default;

CRegDumpViewFDD::~CRegDumpViewFDD()
    = default;

void CRegDumpViewFDD::DoDataExchange(CDataExchange *pDX)
{
	CRegDumpDocPaneDlgViewHelper::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_RDD_FDDREGS, m_listFDD);
	DDX_Control(pDX, IDC_LIST_RDD_HDDREGS, m_listHDD);
	DDX_Control(pDX, IDC_LIST_RDD_OPTOKREGS, m_listOPTOK);
}

BEGIN_MESSAGE_MAP(CRegDumpViewFDD, CRegDumpDocPaneDlgViewHelper)
	ON_MESSAGE(WM_INITDIALOG, &CRegDumpViewFDD::HandleInitDialog)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_RDD_FDDREGS, &CRegDumpViewFDD::OnLvnItemchangedMdFddData)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// обработчики сообщений CRegDumpViewFDD

LRESULT CRegDumpViewFDD::HandleInitDialog(WPARAM wp, LPARAM lp)
{
	CRegDumpDocPaneDlgViewHelper::HandleInitDialog(wp, lp);
	// Создадим список регистров FDD
	m_vList.push_back(
	{
		&m_listFDD,     // list
		&arFDDCols[0],  // colparam
		&arFDDRows[0][0], // rowparam
		COLNUM_FDD, // 3 колонки, 1-я - имя регистра, 2-я - его значение по чтению, 3-я - значение по записи
		ROWNUM_FDD, // rows
		IDC_STATIC_RDD_FDDREGTITLE, // group ID
		false
	});
	// Создадим список регистров HDD
	m_vList.push_back(
	{
		&m_listHDD,     // list
		&arHDDCols[0],  // colparam
		&arHDDRows[0][0], // rowparam
		COLNUM_HDD, // 6 колонок, 1-я и 4-я - адрес порта/регистра, 2-я и 5-я - их значения по чтению, 3-я и 6-я - их значения по записи
		ROWNUM_HDD, // rows
		IDC_STATIC_RDD_HDDREGTITLE, // group ID
		false
	});
	// Создадим список регистров ОПТОК
	m_vList.push_back(
	{
		&m_listOPTOK,     // list
		&arOPTOKCols[0],  // colparam
		&arOPTOKRows[0][0], // rowparam
		COLNUM_OPTOK, // 2 колонки, 1-я - имя регистра, 2-я - его значение
		ROWNUM_OPTOK, // rows
		IDC_STATIC_RDD_OPTOKREGTITLE, // group ID
		false
	});

	for (auto &i : m_vList)
	{
		CreateList(i);
		ReArrangeList(i);
	}

	return TRUE; // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CRegDumpViewFDD::RecreateControls()
{
	const uint32_t status = g_Platform.GetPlatformStatus();
	m_vList[0].bVisible = !!(status & CONFPLATFORM_FDD);
	m_vList[1].bVisible = !!(status & CONFPLATFORM_HDD);
	m_vList[2].bVisible = !!(status & CONFPLATFORM_OPTOK);
	int nMaxGrpWidth = 0;
	CPoint ptLT{ 0, 0 };

	for (auto &i : m_vList)
	{
		ResizeList(i, ptLT, nMaxGrpWidth);
		ReArrangeList(i);
	}

	if (status & CONFPLATFORM_FDD)
	{
		m_listFDD.SetRowBkColor(BG_COLOR, LISTFDD_L::TITLE);
	}

	if (status & CONFPLATFORM_HDD)
	{
		m_listHDD.SetRowBkColor(BG_COLOR, LISTHDD_L::MODE);
	}

	// теперь сделаем группы все одной ширины
	for (auto &i : m_vList)
	{
		if (i.bVisible)
		{
			SetGrpWidth(GetDlgItem(i.nGrpId), nMaxGrpWidth);
		}
	}

	//и под конец изменим размеры самого окна
	CRect rect;
	GetWindowRect(&rect);
	ScreenToClient(&rect);
	rect.bottom = ptLT.y - ::GetSystemMetrics(SM_CYCAPTION) / 2;

	if (rect.bottom < 0)
	{
		rect.bottom = 0;
	}

	rect.right = ptLT.x + nMaxGrpWidth;
	m_sizeDefault = rect.Size();
	AdjustLayout();
}

void CRegDumpViewFDD::DisplayRegDump()
{
	if (IsWindowVisible())
	{
		const uint32_t status = g_Platform.GetPlatformStatus();

		// выводим на экран данные FDD
		if (status & CONFPLATFORM_FDD)
		{
			DisplayFDDData();
		}

		if (status & CONFPLATFORM_HDD)
		{
			DisplayHDDData();
		}

		if (status & CONFPLATFORM_OPTOK)
		{
			DisplayOPTOKData();
		}
	}
}

void CRegDumpViewFDD::DisplayFDDData()
{
	const auto pDbg = g_Platform.GetDebuggerPtr();

	for (int i = LISTFDD_L::REG177130, j = 0; i <= LISTFDD_L::REG177132; ++i, j += 2)
	{
		m_listFDD.SetItemWithModified(pDbg->GetFDDData(j), i,     LISTFDD_C::VALUE1);
		m_listFDD.SetItemWithModified(pDbg->GetFDDData(j + 1), i, LISTFDD_C::VALUE2);
	}
}

void CRegDumpViewFDD::DisplayHDDData()
{
	const auto pDbg = g_Platform.GetDebuggerPtr();

	for (int i = LISTHDD_L::R1F0; i <= LISTHDD_L::R3F7; ++i)
	{
		m_listHDD.SetItemWithModified(pDbg->GetDebugHDDRegs(0, i, true),  i, LISTHDD_C::VALUE11);
		m_listHDD.SetItemWithModified(pDbg->GetDebugHDDRegs(0, i, false), i, LISTHDD_C::VALUE12);
		m_listHDD.SetItemWithModified(pDbg->GetDebugHDDRegs(1, i, true),  i, LISTHDD_C::VALUE21);
		m_listHDD.SetItemWithModified(pDbg->GetDebugHDDRegs(1, i, false), i, LISTHDD_C::VALUE22);
	}
}

void CRegDumpViewFDD::DisplayOPTOKData()
{
	const auto pDbg = g_Platform.GetDebuggerPtr();

	for (int i = LISTOPTOK_L::REG177620; i <= LISTOPTOK_L::REG177630; ++i)
	{
		m_listOPTOK.SetItemWithModified(pDbg->GetOPTOKData(i), i, LISTOPTOK_C::VALUE);
	}
}

void CRegDumpViewFDD::OnLvnItemchangedMdFddData(NMHDR *pNMHDR, LRESULT *pResult)
{
	const auto pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	// TODO: добавьте свой код обработчика уведомлений
	*pResult = S_OK;
}

