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

#include "stdafx.h"
#include "Globals.h"
#include "BKMEM_Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(CBKMEM_Dlg, CDialogEx)

// диалоговое окно CBKMEM_Dlg
CBKMEM_Dlg::CBKMEM_Dlg(BK_MODEL nBKModel, BK_FDD_MODEL nBKFDDModel, BYTE *MainMem, BYTE *AddMem, CWnd *pParent /*=NULL*/)
	: CDialogEx(CBKMEM_Dlg::IDD, pParent)
	, m_Memory(MainMem)
	, m_MemoryADD(AddMem)
	, m_BKModel(nBKModel)
	, m_BKFDDmodel(nBKFDDModel)
	, m_nTabsCount(0)
	, m_nSelectedTab(0)
{
	ZeroMemory(m_pContainers, sizeof(m_pContainers));
}

CBKMEM_Dlg::~CBKMEM_Dlg()
{
	//всё и без этого вроде бы удаляется, но если ещё раз вручную не удалять - получаются утечки памяти
	for (unsigned int i = 0; i < m_nTabsCount; ++i)
	{
		C16KPageContainer *pc = m_pContainers[i];
		pc->DestroyWindow();
		SAFE_DELETE(pc);
		m_pContainers[i] = pc;
	}
}

void CBKMEM_Dlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TAB_MEMMAP, m_tab);
}

BEGIN_MESSAGE_MAP(CBKMEM_Dlg, CDialogEx)
	ON_WM_QUERYDRAGICON()
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_MEMMAP, &CBKMEM_Dlg::OnTcnSelchangeTab1)
END_MESSAGE_MAP()

BOOL CBKMEM_Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	//создаём вкладки
	switch (m_BKModel)
	{
		case BK_0010:
			CreateTabs_10();
			break;

		case BK_0011M:
		case BK_0011:
			CreateTabs_11M();
			break;

		default:
			ASSERT(FALSE); //неопределённых значений не должно быть в принципе
	}

	switch (m_BKFDDmodel)
	{
		default:
		case DEV_FDD_STD:
			break;

		case DEV_FDD_A16M:
			AddTabsA16M();
			break;

		case DEV_FDD_SMK512:
			AddTabsSMK512();
			break;
	}

	AdjustTab();
	m_pContainers[m_nSelectedTab]->ShowWindow(SW_SHOW);
	return TRUE; // возврат значения TRUE, если фокус не передан элементу управления
}

void CBKMEM_Dlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
	m_pContainers[m_nSelectedTab]->ShowWindow(SW_HIDE);
	m_nSelectedTab = m_tab.GetCurSel();

	if (m_nSelectedTab < 0)
	{
		m_nSelectedTab = 0;
	}

	m_pContainers[m_nSelectedTab]->ShowWindow(SW_SHOW);
	*pResult = S_OK;
}

void CBKMEM_Dlg::AdjustTab()
{
	CRect l_rectClient;
	CRect l_rectWnd;
	GetDlgItem(IDC_TAB_MEMMAP)->GetWindowRect(l_rectClient);

	for (unsigned int i = 0; i < m_nTabsCount; ++i)
	{
		m_pContainers[i]->GetWindowRect(l_rectWnd);
		l_rectClient.right = l_rectWnd.Width();
		l_rectClient.bottom = l_rectWnd.Height();
		m_pContainers[i]->MoveWindow(l_rectClient, FALSE);
	}
}

void CBKMEM_Dlg::CreateTabs_10()
{
	m_nTabsCount = 1;
	CString str, strwnd, strtab;
	unsigned int nUnique_num = 0, t1, t2;

	for (unsigned int i = 0; i < m_nTabsCount; ++i)
	{
		m_pContainers[i] = new C16KPageContainer(C16KP_NUM_PAGES);
		str.Format(_T("pgBK10_n%d"), nUnique_num);
		m_pContainers[i]->SetBuffer_Param(C16KP_FIRST_PAGE, m_Memory + i * 0100000,
		                                  040000, t1 = nUnique_num++, str);
		str.Format(_T("pgBK10_n%d"), nUnique_num);
		m_pContainers[i]->SetBuffer_Param(C16KP_SECOND_PAGE, m_Memory + i * 0100000 + 040000,
		                                  040000, t2 = nUnique_num++, str);
		strwnd.Format(_T("tabBK10_n%d"), i);

		if (!m_pContainers[i]->Create(NULL, strwnd, WS_CHILD, CRect(0, 0, 200, 200), this, 0))
		{
			GetLastErrorOut(_T("TabBK10"));
		}

		strtab.Format(_T("BK10_pg%d%d"), t1, t2);
		m_tab.InsertItem(i, strtab);
	}
}

void CBKMEM_Dlg::CreateTabs_11M()
{
	m_nTabsCount = 4;
	static unsigned int Pages[8] = { 0, 1, 2, 3, 5, 6, 4, 7 };
	CString str, strwnd, strtab;
	unsigned int n0, n1;
	BYTE *buf0, *buf1;

	for (unsigned int i = 0; i < m_nTabsCount; ++i)
	{
		n0 = Pages[i * 2];
		n1 = Pages[i * 2 + 1];
		buf0 = m_Memory + (n0 << 14);
		buf1 = m_Memory + (n1 << 14);
		m_pContainers[i] = new C16KPageContainer(C16KP_NUM_PAGES);
		str.Format(_T("pgBK11M_n%d"), n0);
		m_pContainers[i]->SetBuffer_Param(C16KP_FIRST_PAGE, buf0, 040000, n0, str);
		str.Format(_T("pgBK11M_n%d"), n1);
		m_pContainers[i]->SetBuffer_Param(C16KP_SECOND_PAGE, buf1, 040000, n1, str);
		strwnd.Format(_T("tabBK11M_n%d"), i);

		if (!m_pContainers[i]->Create(NULL, strwnd, WS_CHILD, CRect(0, 0, 200, 200), this, 0))
		{
			GetLastErrorOut(_T("TabBK11M"));
		}

		strtab.Format(_T("BK11M_pg%d%d"), n0, n1);
		m_tab.InsertItem(i, strtab);
	}
}

void CBKMEM_Dlg::AddTabsA16M()
{
	unsigned int i = m_nTabsCount++;
	CString str, strwnd, strtab;
	unsigned int nUnique_num = 0, t1;
	m_pContainers[i] = new C16KPageContainer(C16KP_NUM_PAGES - 1);
	str.Format(_T("pgA16M_n%d"), nUnique_num);
	m_pContainers[i]->SetBuffer_Param(C16KP_FIRST_PAGE, m_MemoryADD,
	                                  040000, t1 = nUnique_num++, str);
	strwnd.Format(_T("tabA16M_n%d"), i);

	if (!m_pContainers[i]->Create(NULL, strwnd, WS_CHILD, CRect(0, 0, 200, 200), this, 0))
	{
		GetLastErrorOut(_T("TabA16M"));
	}

	strtab.Format(_T("A16M_pg%d"), t1);
	m_tab.InsertItem(i, strtab);
}

void CBKMEM_Dlg::AddTabsSMK512()
{
	unsigned int n = m_nTabsCount;
	m_nTabsCount += 16;
	CString str, strwnd, strtab;
	unsigned int nUnique_num = 0, t1, t2;

	for (unsigned int i = n; i < m_nTabsCount; ++i)
	{
		m_pContainers[i] = new C16KPageContainer(C16KP_NUM_PAGES);
		str.Format(_T("pgSMK_n%d"), nUnique_num);
		m_pContainers[i]->SetBuffer_Param(C16KP_FIRST_PAGE, m_MemoryADD + (i - n) * 0100000,
		                                  040000, t1 = nUnique_num++, str);
		str.Format(_T("pgSMK_n%d"), nUnique_num);
		m_pContainers[i]->SetBuffer_Param(C16KP_SECOND_PAGE, m_MemoryADD + (i - n) * 0100000 + 040000,
		                                  040000, t2 = nUnique_num++, str);
		strwnd.Format(_T("tabSMK_n%d"), i);

		if (!m_pContainers[i]->Create(NULL, strwnd, WS_CHILD, CRect(0, 0, 200, 200), this, 0))
		{
			GetLastErrorOut(_T("TabSMK512"));
		}

		strtab.Format(_T("SMK_pg%d%d"), t1, t2);
		m_tab.InsertItem(i, strtab);
	}
}

void CBKMEM_Dlg::DrawTab()
{
	m_pContainers[m_nSelectedTab]->Draw16KPages();
}


// CBKMEMView

IMPLEMENT_DYNAMIC(CBKMEMView, CFrameWnd)

CBKMEMView::CBKMEMView(BK_MODEL nBKModel, BK_FDD_MODEL BKFDDmodel, BYTE *MainMem, BYTE *AddMem)
{
	m_pdlgBKMem = new CBKMEM_Dlg(nBKModel, BKFDDmodel, MainMem, AddMem);
}

CBKMEMView::~CBKMEMView()
{
}

BEGIN_MESSAGE_MAP(CBKMEMView, CFrameWnd)
	ON_WM_DESTROY()
	ON_WM_CREATE()
END_MESSAGE_MAP()


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


int CBKMEMView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == - 1)
	{
		return -1;
	}

	if (m_pdlgBKMem == NULL)
	{
		return -1;
	}

	if (!m_pdlgBKMem->Create(IDD_BKMEM_MAP_DIALOG, this))
	{
		TRACE0("Не удалось создать диалог Memory Map\n");
		return -1; // не удалось создать
	}

	CRect rectClient;
	m_pdlgBKMem->GetClientRect(rectClient);
	ClientToScreen(rectClient);
	SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), rectClient.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
	return 0;
}

void CBKMEMView::DrawCurrentTab()
{
	if (m_lockStop.IsLocked())
	{
		return;
	}

	m_lockDraw.Lock();
	m_pdlgBKMem->DrawTab();
	m_lockDraw.UnLock();
}

void CBKMEMView::OnDestroy()
{
	m_lockStop.Lock();

	while (m_lockDraw.IsLocked())
	{
		Sleep(1);
	}

	//посылаем в MainFrame сообщение о закрытии всего этого тут
	::SendMessage(GetParentFrame()->GetSafeHwnd(), WM_MEMMAP_CLOSE, 0, 0);

	if (m_pdlgBKMem)
	{
		m_pdlgBKMem->DestroyWindow();
		delete m_pdlgBKMem;
	}

	CFrameWnd::OnDestroy();
}

