#include "StdAfx.h"
#include "zLayout.h"

#define MAX(x, y) ((x) > (y) ? (x) : (y))

class CBox
{
private:
	CBox(const CBox&);
	CBox& operator=(const CBox&);

public:
	CBox(CWnd* item, int fromRow, int fromCol, int spanRow, int spanCol) 
		:m_item(item), m_Row(fromRow), m_Col(fromCol), 
		m_spanRow(spanRow), m_spanCol(spanCol)
	{}

	~CBox() 
	{}

	int GetRow(){return m_Row;}
	int GetCol(){return m_Col;}
	CWnd* GetItem(){return m_item;}

	void Update(int iCellWidth, int iCellHeight)
	{
		const int iWndLeft = m_Col * iCellWidth;
		const int iWndTop = m_Row * iCellHeight;
		const int iWndWidth = m_spanCol * iCellWidth;
		const int iWndHeight = m_spanRow * iCellHeight;
		m_item->SetWindowPos(NULL, iWndLeft, iWndTop, iWndWidth, iWndHeight, 
			SWP_SHOWWINDOW | SWP_NOZORDER);		
	}

private:
	CWnd* m_item;
	int m_Row, m_Col;
	int m_spanRow, m_spanCol;
};

CzLayout::CzLayout(CWnd* pOwner)
: m_pOwner(pOwner), m_iCurRowCnt(0), m_iCurColCnt(0)
{
	m_pOwner->GetWindowRect(&m_OwnerRect);
}

CzLayout::~CzLayout(void)
{
	std::list<CBox*>::const_iterator iter = m_things.begin();
	for (; iter != m_things.end(); iter++)
	{
		delete *iter;
	}
}

void CzLayout::AddThings(CWnd* pThing, 
						 int fromRow, int fromCol, int spanRow, int spanCol)
{
	ASSERT(pThing != NULL);
	if (pThing == NULL)
	{
		return;
	}

	CBox *box = new CBox(pThing, fromRow, fromCol, spanRow, spanCol);
	m_things.push_back(box);

	UpdateMaxRowCol(fromRow + spanRow, fromCol + spanCol);
	UpdateChildPos();
}

void CzLayout::UpdateChildPos()
{
	const int iCellWidth = m_OwnerRect.Width() / m_iCurColCnt;
	const int iCellHeight = m_OwnerRect.Height() / m_iCurRowCnt;

	std::list<CBox*>::const_iterator iter = m_things.begin();
	for (; iter != m_things.end(); ++iter)
	{
		(*iter)->Update(iCellWidth, iCellHeight);
	}
}

void CzLayout::UpdateMaxRowCol(int iRowCnt, int iColCnt)
{
	m_iCurRowCnt = MAX(iRowCnt, m_iCurRowCnt);	
	m_iCurColCnt = MAX(iColCnt, m_iCurColCnt);
}

void CzLayout::Resize()
{
	m_pOwner->GetWindowRect(&m_OwnerRect);
	UpdateChildPos();
}