// PrintDlg.cpp : implementation file
//

#include "pch.h"
#include "Config.h"
#include "Debugger.h"
#include "PrintDlg.h"
#include "resource.h"

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

/////////////////////////////////////////////////////////////////////////////
// CPrintDlg

IMPLEMENT_DYNAMIC(CPrintDlg, CPrintDialog)

CPrintDlg::CPrintDlg(BOOL bPrintSetupOnly, DWORD dwFlags, CWnd *pParentWnd)
	: CPrintDialog(bPrintSetupOnly, dwFlags, pParentWnd)
{
	m_pd.lpPrintTemplateName = MAKEINTRESOURCE(IDD_PRINT);
	// m_pd.lpSetupTemplateName = MAKEINTRESOURCE(IDD_PRINT);
	m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;
	// m_pd.Flags |= PD_ENABLESETUPTEMPLATE;
	m_pd.hInstance = AfxGetInstanceHandle();
	// AfxGetApp()->GetPrinterDeviceDefaults(&m_pd); - вот из-за этой строки диалог вызывал повреждение памяти. Ни в коем случае не использовать такое больше.
	m_pd.nCopies = 1;
}

CPrintDlg::~CPrintDlg()
    = default;

BEGIN_MESSAGE_MAP(CPrintDlg, CPrintDialog)

	ON_WM_SHOWWINDOW()
	ON_COMMAND(IDC_PRN_PRINT_SCREEN, &CPrintDlg::OnPrintScreen)
	ON_COMMAND(IDC_PRN_PRINT_CODE, &CPrintDlg::OnPrintCode)
	ON_COMMAND(IDOK, &CPrintDlg::OnOk)
	ON_EN_CHANGE(IDC_PRN_START_ADDR, &CPrintDlg::OnStartAddr)
	ON_EN_CHANGE(IDC_PRN_END_ADDR, &CPrintDlg::OnEndAddr)

END_MESSAGE_MAP()

void CPrintDlg::DoDataExchange(CDataExchange *pDX)
{
	CPrintDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_PRN_TITLE, m_strTitle);
	DDX_Text(pDX, IDC_PRN_START_ADDR, m_strStartAddr);
	DDX_Text(pDX, IDC_PRN_END_ADDR, m_strEndAddr);
	DDX_Text(pDX, IDC_PRN_PAGES, m_nPages);
	DDX_Check(pDX, IDC_PRN_INVERSE, m_bInverse);
	DDX_Check(pDX, IDC_PRN_PRINT_SCREEN, m_bPrintScreen);
	DDX_Check(pDX, IDC_PRN_PRINT_CODE, m_bPrintCode);
}

void CPrintDlg::OnPrintScreen()
{
	UpdateData(TRUE);
	HideControls();
}


void CPrintDlg::OnPrintCode()
{
	UpdateData(TRUE);
	HideControls();
}



void CPrintDlg::OnStartAddr()
{
	GetStartAddress();
}


void CPrintDlg::OnEndAddr()
{
	GetEndAddress();
}


void CPrintDlg::OnOk()
{
	if (!GetStartAddress())
	{
		return;
	}

	if (!GetEndAddress())
	{
		return;
	}

	UpdateData(TRUE);
	CPrintDialog::OnOK();
}


void CPrintDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CPrintDialog::OnShowWindow(bShow, nStatus);
	m_bPrintCode = !m_bPrintScreen;
	m_strStartAddr = Global::WordToOctString(m_startAddr);
	m_strEndAddr = Global::WordToOctString(m_endAddr);
	UpdateData(FALSE);
	HideControls();
}


void CPrintDlg::HideControls()
{
	GetDlgItem(IDC_PRN_INVERSE)->EnableWindow(m_bPrintScreen);
	GetDlgItem(IDC_PRN_START_ADDR)->EnableWindow(!m_bPrintScreen);
	GetDlgItem(IDC_PRN_END_ADDR)->EnableWindow(!m_bPrintScreen);
}


BOOL CPrintDlg::GetStartAddress()
{
	UpdateData(TRUE);
	m_startAddr = Global::OctStringToWord(m_strStartAddr);
	CalcPages();
	return TRUE;
}


BOOL CPrintDlg::GetEndAddress()
{
	UpdateData(TRUE);
	m_endAddr = Global::OctStringToWord(m_strEndAddr);
	CalcPages();
	return TRUE;
}


void CPrintDlg::CalcPages()
{
	ASSERT(m_pDebugger);
	uint16_t pc = m_startAddr;
	int nPages = 1;
	int nLines = 0;

	while (pc < m_endAddr)
	{
		pc += m_pDebugger->CalcInstructionLength_pc(pc);

		if (++nLines == m_nLinesPerPage - 6)
		{
			nLines = 0;
			nPages++;
		}
	}

	m_nPages = nPages;
	UpdateData(FALSE);
}
