#include "pch.h"
#include "RegDumpDocPaneDlgViewHelper.h"
#include "BKMessageBox.h"
#include "Config.h"
#include "Screen_Sizes.h"

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


IMPLEMENT_DYNAMIC(CRegDumpDocPaneDlgViewHelper, CDocPaneDlgViewBase)

static const CRegDumpDocPaneDlgViewHelper::ColParam_t arLSTCols[COLNUM_STD] =
{
	{COL_WIDTH | COL_COLOR, COLUMN_WIDTH, BG_COLOR},
	{COL_WIDTH | COL_EDITABLE, COLUMN_WIDTH, 0}
};


CRegDumpDocPaneDlgViewHelper::CRegDumpDocPaneDlgViewHelper()
	: m_nPixelW(0)
	, m_nPixelH(0)
	, m_padX(0)
	, m_padY(0)
{
}

void CRegDumpDocPaneDlgViewHelper::CreateList(ListParam_t &p)
{
	p.pList->SetFont(&m_hFont, FALSE);
	p.pList->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_DOUBLEBUFFER | LVS_EX_SNAPTOGRID);

	// создаём колонки
	for (int col = 0; col < p.nCols; ++col)
	{
		if (p.pCP[col].dwState & COL_WIDTH)
		{
			p.pList->InsertColumn(col, LPSTR_TEXTCALLBACK, LVCFMT_LEFT, ::MulDiv(p.pCP[col].nWidth, m_nPixelW, DEFAULT_DPIX));
		}
		else
		{
			p.pList->InsertColumn(col, LPSTR_TEXTCALLBACK, LVCFMT_LEFT);
		}
	}

	// добавляем строки и значения в ячейки
	for (int row = 0; row < p.nRows; ++row)
	{
		const CellParam_t *pRow = &p.pRP[row * p.nCols];

		for (int col = 0; col < p.nCols; ++col)
		{
			bool b = ((pRow[col].dwState & COL_VALUE) && pRow[col].nIDStrValue);
			CString str = (b ? CString(MAKEINTRESOURCE(pRow[col].nIDStrValue)) : _T(""));
			if (col == 0)
			{
				p.pList->InsertItem(row, (b ? str.GetString() : LPSTR_TEXTCALLBACK));
			}
			else
			{
				p.pList->SetItem(row, col, LVIF_TEXT, (b ? str.GetString() : LPSTR_TEXTCALLBACK), 0, 0, 0, 0);
			}

			// можно задавать свойства отдельных ячеек, только это почему-то не работает
// 			if (pRow[col].dwState & COL_COLOR)
// 			{
// 				p.pList->SetItemBkColor(p.pCP[col].color, row, col);
// 			}
// 
// 			p.pList->EnableEdit(!!(p.pCP[col].dwState & COL_EDITABLE), row, col);
		}
	}

	// задаём свойства колонок, их можно применять только к уже созданным элементам,
	// поэтому повторный цикл уже после создания строк
	for (int col = 0; col < p.nCols; ++col)
	{
		if (p.pCP[col].dwState & COL_COLOR)
		{
			p.pList->SetColumnBkColor(p.pCP[col].color, col);
		}

		p.pList->EnableColumnEdit(!!(p.pCP[col].dwState & COL_EDITABLE), col);
	}
}

void CRegDumpDocPaneDlgViewHelper::ResizeList(ListParam_t &p, CPoint &ptLT, int &maxGW)
{
	CRect listRect, grpRect, itemRect;
	p.pList->GetWindowRect(&listRect);      // текущие размеры списка
	ScreenToClient(&listRect);

	if (ptLT.x)
	{
		listRect.left = ptLT.x;
	}

	if (ptLT.y)
	{
		listRect.top = ptLT.y;
	}

	CWnd *grp = p.nGrpId ? GetDlgItem(p.nGrpId) : nullptr;

	if (grp)
	{
		grp->GetWindowRect(&grpRect);   // текущие размеры группы
		ScreenToClient(&grpRect);
	}

	p.pList->GetItemRect(0, itemRect, LVIR_BOUNDS); // получим размеры элемента строки списка
	// и на их основе расчитаем новые размеры списка, чтобы был точно по размерам элементов
	register int cx = itemRect.Width() + ::GetSystemMetrics(SM_CXDLGFRAME);
	register int cy = itemRect.Height() * p.nRows + ::GetSystemMetrics(SM_CYDLGFRAME);
	p.pList->SetWindowPos(nullptr, listRect.left, listRect.top, cx, cy, SWP_SHOWWINDOW); // изменяем размеры списка

	if (grp)
	{
		grpRect.left = listRect.left - m_padX;
		grpRect.top = listRect.top - ::GetSystemMetrics(SM_CYCAPTION) / 2 - m_padY;
		grpRect.right = listRect.left + cx + m_padX;
		grpRect.bottom = listRect.top + cy + m_padY;
		grp->SetWindowPos(nullptr, grpRect.left, grpRect.top, grpRect.Width(), grpRect.Height(), SWP_SHOWWINDOW); // изменяем размеры группы

		if (maxGW < grpRect.Width())
		{
			maxGW = grpRect.Width();
		}

		ptLT.x = listRect.left;
		ptLT.y = grpRect.bottom + ::GetSystemMetrics(SM_CYCAPTION) / 2 + m_padY;
	}
}

void CRegDumpDocPaneDlgViewHelper::SetGrpWidth(CWnd *grp, int width)
{
	CRect grpRect;
	grp->GetWindowRect(&grpRect);   // текущие размеры группы
	ScreenToClient(&grpRect);
	grp->SetWindowPos(nullptr, grpRect.left, grpRect.top, width, grpRect.Height(), SWP_SHOWWINDOW); // изменяем размеры группы
}

LRESULT CRegDumpDocPaneDlgViewHelper::HandleInitDialog(WPARAM wp, LPARAM lp)
{
	CDocPaneDlgViewBase::HandleInitDialog(wp, lp);
	m_nPixelW = ::GetDeviceCaps(GetDC()->GetSafeHdc(), LOGPIXELSX);
	m_nPixelH = ::GetDeviceCaps(GetDC()->GetSafeHdc(), LOGPIXELSY);
	m_padX = ::MulDiv(4, m_nPixelW, DEFAULT_DPIX); // отступ группы от списка слева и справа
	m_padY = ::MulDiv(5, m_nPixelH, DEFAULT_DPIY); // отступ группы от списка сверху и снизу
	return TRUE;
}

