// BreapointView.cpp: файл реализации
//

#include "pch.h"
#include "resource.h"
#include "BreakpointView.h"
#include "Platform.h"

// Диалоговое окно CBreakpointView

IMPLEMENT_DYNAMIC(CBreakpointView, CDocPaneDlgViewBase)

CBreakpointView::CBreakpointView()
{
}

CBreakpointView::~CBreakpointView()
{
}

void CBreakpointView::InitView()
{
	m_ListBPT.InitView();
}

void CBreakpointView::DoDataExchange(CDataExchange *pDX)
{
	CDocPaneDlgViewBase::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_BPT_BREAKPOINTS, m_ListBPT);
}


BEGIN_MESSAGE_MAP(CBreakpointView, CDocPaneDlgViewBase)
	ON_MESSAGE(WM_DBG_BREAKPOINTS_UPDATE, &CBreakpointView::OnBreakpointsUpdate)
	ON_MESSAGE(WM_INITDIALOG, &CBreakpointView::HandleInitDialog)
	ON_COMMAND(IDC_BUTTON_BPT_ADDADDR, &CBreakpointView::OnBnClickedButtonAddAddrBP)
	ON_COMMAND(IDC_BUTTON_BPT_ADDMEM, &CBreakpointView::OnBnClickedButtonAddMemBP)
	ON_COMMAND(IDC_BUTTON_BPT_DEL, &CBreakpointView::OnBnClickedButtonDelBP)
	ON_COMMAND(IDC_BUTTON_BPT_ONOFF, &CBreakpointView::OnBnClickedButtonOnOffBP)
	ON_COMMAND(IDC_BUTTON_BPT_DELALL, &CBreakpointView::OnBnClickedButtonDelAllBP)
	ON_COMMAND(IDC_BUTTON_BPT_ONALL, &CBreakpointView::OnBnClickedButtonOnAllBP)
	ON_COMMAND(IDC_BUTTON_BPT_OFFALL, &CBreakpointView::OnBnClickedButtonOffAllBP)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_ADDADDR, &CBreakpointView::OnUpdateButton)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_ADDMEM, &CBreakpointView::OnUpdateButton)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_DEL, &CBreakpointView::OnUpdateButton2)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_ONOFF, &CBreakpointView::OnUpdateButton2)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_DELALL, &CBreakpointView::OnUpdateButton2)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_ONALL, &CBreakpointView::OnUpdateButton2)
	ON_UPDATE_COMMAND_UI(IDC_BUTTON_BPT_OFFALL, &CBreakpointView::OnUpdateButton2)
	ON_WM_SETFOCUS()
	ON_WM_SHOWWINDOW()
END_MESSAGE_MAP()


// Обработчики сообщений CBreakpointView
LRESULT CBreakpointView::HandleInitDialog(WPARAM wp, LPARAM lp)
{
	CDocPaneDlgViewBase::HandleInitDialog(wp, lp);
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_ADDADDR), _T("Добавить обычную точку останова."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_ADDMEM), _T("Добавить точку останова на доступ к памяти."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_DEL), _T("Удалить выделенные точки останова."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_ONOFF), _T("Включить/выключить выделенные точки останова."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_DELALL), _T("Удалить все точки останова."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_ONALL), _T("Включить все точки останова."));
	m_ToolTip.AddTool(GetDlgItem(IDC_BUTTON_BPT_OFFALL), _T("Выключить все точки останова."));
	m_ListBPT.SetFont(&m_hFont, FALSE);
	m_ListBPT.Init();
	return TRUE; // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}

void CBreakpointView::OnSetFocus(CWnd *pOldWnd)
{
	m_ListBPT.SetFocus();
}

void CBreakpointView::OnBnClickedButtonAddAddrBP()
{
	NewBPParam sBPParam;
	CRect btnRect;
	GetDlgItem(IDC_BUTTON_BPT_ADDADDR)->GetWindowRect(&btnRect);
	const auto pDlg = std::make_unique<CAddAddrBP>(btnRect, &sBPParam);

	if (pDlg)
	{
		if (pDlg->DoModal() == IDOK)
		{
			g_Platform.GetDebuggerPtr()->SetSimpleBreakpoint(sBPParam.nAddr);
			m_ListBPT.OutContent();
		}
	}
}

void CBreakpointView::OnBnClickedButtonAddMemBP()
{
	NewBPParam sBPParam;
	CRect btnRect;
	GetDlgItem(IDC_BUTTON_BPT_ADDMEM)->GetWindowRect(&btnRect);
	const auto pDlg = std::make_unique<CAddMemBP>(btnRect, &sBPParam);

	if (pDlg)
	{
		if (pDlg->DoModal() == IDOK)
		{
			g_Platform.GetDebuggerPtr()->SetMemAccessBreakpoint(sBPParam.nAddr, sBPParam.nFlags);
			m_ListBPT.OutContent();
		}
	}
}

void CBreakpointView::OnBnClickedButtonDelBP()
{
	m_ListBPT.DeleteSelected();
}

void CBreakpointView::OnBnClickedButtonOnOffBP()
{
	m_ListBPT.SwitchOnOffSelected();
}

void CBreakpointView::OnBnClickedButtonDelAllBP()
{
	m_ListBPT.DeleteAll();
}

void CBreakpointView::OnBnClickedButtonOnAllBP()
{
	m_ListBPT.SwitchAll(true);
}

void CBreakpointView::OnBnClickedButtonOffAllBP()
{
	m_ListBPT.SwitchAll(false);
}

void CBreakpointView::OnUpdateButton(CCmdUI *pCmdUI)
{
	pCmdUI->Enable(true);
}

void CBreakpointView::OnUpdateButton2(CCmdUI *pCmdUI)
{
	const int n = m_ListBPT.GetItemCount();
	pCmdUI->Enable(n > 0);
}

LRESULT CBreakpointView::OnBreakpointsUpdate(WPARAM, LPARAM)
{
	if (IsVisible())
	{
		m_ListBPT.OutContent();
	}

	return S_OK;
}

void CBreakpointView::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CDocPaneDlgViewBase::OnShowWindow(bShow, nStatus);

	if (bShow)
	{
		m_ListBPT.OutContent();
	}
}

// Диалоговое окно CAddAddrBP

IMPLEMENT_DYNAMIC(CAddAddrBP, CBaseDialog)

CAddAddrBP::CAddAddrBP(const CRect &OwnRect, NewBPParam *pParam /*= nullptr*/, CWnd *pParent /*=nullptr*/)
	: CBaseDialog(CAddAddrBP::IDD, pParent)
	, m_pParam(pParam)
	, m_nOwnRect(OwnRect)
	, m_nAddr(0)
{
	m_strAddr = Global::WordToOctString(m_nAddr);
}

CAddAddrBP::~CAddAddrBP()
{}

void CAddAddrBP::DoDataExchange(CDataExchange *pDX)
{
	CBaseDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_AABP_ADDR, m_EditAddr);
	DDX_Text(pDX, IDC_EDIT_AABP_ADDR, m_strAddr);
}


BOOL CAddAddrBP::OnInitDialog()
{
	CRect r2;
	GetWindowRect(r2);
	CRect r;
	r.left = m_nOwnRect.left;
	r.top = m_nOwnRect.top + m_nOwnRect.Height();
	r.right = r.left + r2.Width();
	r.bottom = r.top + r2.Height();
	MoveWindow(r, FALSE);
	CBaseDialog::OnInitDialog();
	m_EditAddr.SetLimitText(6);
	UpdateData(FALSE);
	m_EditAddr.SetFocus();
	return TRUE;
}

void CAddAddrBP::OnOK()
{
	UpdateData(TRUE);

	if (m_pParam)
	{
		m_nAddr = Global::OctStringToWord(m_strAddr);
		m_pParam->nAddr = m_nAddr;
	}

	CBaseDialog::OnOK();
}

BEGIN_MESSAGE_MAP(CAddAddrBP, CBaseDialog)
END_MESSAGE_MAP()


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


// Диалоговое окно CAddMemBP

IMPLEMENT_DYNAMIC(CAddMemBP, CBaseDialog)

CAddMemBP::CAddMemBP(const CRect &OwnRect, NewBPParam *pParam /*= nullptr*/, CWnd *pParent /*=nullptr*/)
	: CBaseDialog(CAddMemBP::IDD, pParent)
	, m_pParam(pParam)
	, m_nOwnRect(OwnRect)
	, m_nAddr(0)
	, m_bByte(FALSE)
	, m_bRead(FALSE)
	, m_bWrite(FALSE)
{
	m_strAddr = Global::WordToOctString(m_nAddr);
}

CAddMemBP::~CAddMemBP()
{}

void CAddMemBP::DoDataExchange(CDataExchange *pDX)
{
	CBaseDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_AMBP_ADDR, m_EditAddr);
	DDX_Text(pDX, IDC_EDIT_AMBP_ADDR, m_strAddr);
	DDX_Check(pDX, IDC_CHECK_AMBP_BYTE, m_bByte);
	DDX_Check(pDX, IDC_CHECK_AMBP_RD, m_bRead);
	DDX_Check(pDX, IDC_CHECK_AMBP_WR, m_bWrite);
}


BOOL CAddMemBP::OnInitDialog()
{
	CRect r2;
	GetWindowRect(r2);
	CRect r;
	r.left = m_nOwnRect.left;
	r.top = m_nOwnRect.top + m_nOwnRect.Height();
	r.right = r.left + r2.Width();
	r.bottom = r.top + r2.Height();
	MoveWindow(r, FALSE);
	CBaseDialog::OnInitDialog();
	m_EditAddr.SetLimitText(6);
	UpdateData(FALSE);
	m_EditAddr.SetFocus();
	return TRUE;
}

void CAddMemBP::OnOK()
{
	UpdateData(TRUE);

	if (m_pParam)
	{
		m_nAddr = Global::OctStringToWord(m_strAddr);
		m_pParam->nAddr = m_nAddr;

		if (m_bRead)
		{
			m_pParam->nFlags |= BP_MEMACCESS_RD;
		}

		if (m_bWrite)
		{
			m_pParam->nFlags |= BP_MEMACCESS_WR;
		}

		if (m_bByte)
		{
			m_pParam->nFlags |= BP_MEMACCESS_BYTE;
		}
	}

	CBaseDialog::OnOK();
}

BEGIN_MESSAGE_MAP(CAddMemBP, CBaseDialog)
END_MESSAGE_MAP()


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

