// ClassInfoDlg_Gui_Grid.cpp : implementation file
//

#include "stdafx.h"
#include "ClassInfoDlg_Gui_Grid.h"
#include "XmlClassInfo.h"
#include "XmlMemberInfo.h"
#include "GridColumnSelectorDlg.h"
#include "GridCellCheck.h"
#include "GridCellNumeric.h"

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

/////////////////////////////////////////////////////////////////////////////
// CClassInfoDlg_Gui_Grid dialog


CClassInfoDlg_Gui_Grid::CClassInfoDlg_Gui_Grid(CWnd* pParent /*=NULL*/)
	: CPropertyEditorDlg(CClassInfoDlg_Gui_Grid::IDD, pParent),
	classInfo_(NULL),
	zeroAlignedCount_(false)
{
	//{{AFX_DATA_INIT(CClassInfoDlg_Gui_Grid)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CClassInfoDlg_Gui_Grid::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClassInfoDlg_Gui_Grid)
	DDX_Control(pDX, IDC_CMD_REMOVE_COLUMN, cmdRemoveColumn_);
	DDX_Control(pDX, IDC_CMD_MOVE_RIGHT, cmdMoveRight_);
	DDX_Control(pDX, IDC_CMD_MOVE_LEFT, cmdMoveLeft_);
	DDX_Control(pDX, IDC_CMD_ADD_COLUMN, cmdAddColumn_);
	DDX_Control(pDX, IDC_CHK_DISPLAY_NUMBER_COLUMN, chkDisplayNumberColumn_);
	DDX_Control(pDX, IDC_CHK_DISPLAY_BUTTON_BAR, chkDisplayButtonBar_);
	DDX_Control(pDX, IDC_OPT_NUMBERING_ZERO, optZeroAlignedCount_);
	DDX_Control(pDX, IDC_OPT_NUMBERING_ONE, optOneAlignedCount_);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CClassInfoDlg_Gui_Grid, CPropertyEditorDlg)
	//{{AFX_MSG_MAP(CClassInfoDlg_Gui_Grid)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_CMD_ADD_COLUMN, OnCmdAddColumn)
	ON_BN_CLICKED(IDC_CHK_DISPLAY_NUMBER_COLUMN, OnChkDisplayNumberColumn)
	ON_BN_CLICKED(IDC_CMD_REMOVE_COLUMN, OnCmdRemoveColumn)
	ON_BN_CLICKED(IDC_CMD_MOVE_LEFT, OnCmdMoveLeft)
	ON_BN_CLICKED(IDC_CMD_MOVE_RIGHT, OnCmdMoveRight)
	ON_BN_CLICKED(IDC_OPT_NUMBERING_ZERO, OnOptNumberingZero)
	ON_BN_CLICKED(IDC_OPT_NUMBERING_ONE, OnOptNumberingOne)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClassInfoDlg_Gui_Grid message handlers
void CClassInfoDlg_Gui_Grid::StoreData()
{
	CXmlGuiGridInfo* gridInfo;
	GridColumns* columns;

	gridInfo = classInfo_->GetGridInfo();
	
	gridInfo->SetButtonBarEnabled(chkDisplayButtonBar_.GetCheck() == TRUE);
	gridInfo->SetColumnCountEnabled(chkDisplayNumberColumn_.GetCheck() == TRUE);

	columns = gridInfo->GetColumns();
	gridInfo->SetZeroAlignedCount(zeroAlignedCount_);

	columns->clear();
	for (int i = 0; i < usedMembersId_.size(); i++)
		columns->push_back(usedMembersId_[i]);
}

void CClassInfoDlg_Gui_Grid::SetData(CXmlBaseElement* element)
{
	classInfo_ = dynamic_cast<CXmlClassInfo*>(element);
	assert(classInfo_);
	if (classInfo_ == NULL)
		return;

	GridColumns* columns;

	columns = classInfo_->GetGridInfo()->GetColumns();
	usedMembersId_.clear();
	for (int i = 0; i < columns->size(); i++)
		usedMembersId_.push_back((*columns)[i]);

	zeroAlignedCount_ = classInfo_->GetGridInfo()->GetZeroAlignedCount();

	chkDisplayButtonBar_.SetCheck(classInfo_->GetGridInfo()->GetButtonBarEnabled());
	chkDisplayNumberColumn_.SetCheck(classInfo_->GetGridInfo()->GetColumnCountEnabled());
	
	// set option button state
	//
	UpdateOptions();
	EnableOptions();
	
	DisplayGridPreview();
}

void CClassInfoDlg_Gui_Grid::OnDataUpdate()
{
	SetData(classInfo_);
}

BOOL CClassInfoDlg_Gui_Grid::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	grid_.Create(CRect(0,0,0,0), this, -1);
	grid_.ModifyStyle(WS_BORDER, 0);

	UpdateWindowSize();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CClassInfoDlg_Gui_Grid::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	if (grid_.GetSafeHwnd())
		UpdateWindowSize();
		
}

void CClassInfoDlg_Gui_Grid::UpdateWindowSize()
{
	CRect rc;
		
	// setup buttons
	//
	CSize btnSize;
	CRect btnRect;
	int btnTop;
	int btnLeft;

	GetClientRect(rc);

	cmdAddColumn_.GetWindowRect(btnRect);
	btnSize = btnRect.Size();

	btnTop = rc.bottom - btnSize.cy;	
	btnLeft = rc.Width() - btnSize.cx;
	
	cmdMoveRight_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, btnSize.cx, btnSize.cy, 0);
	btnLeft -= btnSize.cx;
	
	cmdMoveLeft_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, btnSize.cx, btnSize.cy, 0);
	btnLeft -= btnSize.cx;

	cmdRemoveColumn_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, btnSize.cx, btnSize.cy, 0);
	btnLeft -= btnSize.cx;
	
	cmdAddColumn_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, btnSize.cx, btnSize.cy, 0);
	btnLeft -= btnSize.cx;
		
	// option buttons
	//
	CWnd* optZeroWnd;
	CWnd* optOneWnd;
	CRect tmpRc;

	btnTop -= btnSize.cy;
	btnLeft = 30;
	optOneWnd = GetDlgItem(IDC_OPT_NUMBERING_ONE);
	optOneWnd->SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, 0,0, SWP_NOSIZE);
	optOneWnd->GetWindowRect(tmpRc);
	ScreenToClient(tmpRc);

	btnTop -= (tmpRc.Height() + 5);
	optZeroWnd = GetDlgItem(IDC_OPT_NUMBERING_ZERO);
	optZeroWnd->SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, 0,0, SWP_NOSIZE);

	// checkboxes
	//
	btnTop -= (tmpRc.Height() + 5);
	btnLeft = 0;
	chkDisplayNumberColumn_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, 0, 0, SWP_NOSIZE);
	btnTop -= btnSize.cy;

	chkDisplayButtonBar_.SetWindowPos(&CWnd::wndTop, btnLeft, btnTop, 0, 0, SWP_NOSIZE);


	// setup grid_
	//
	GetClientRect(rc);
	rc.DeflateRect(0, 20, 0, 0);
	rc.bottom = btnTop - 5;
	if (rc.Width() < 0 || rc.Height() < 0)
		rc = CRect(0,20,0,0);

	grid_.SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), 0);

}

void CClassInfoDlg_Gui_Grid::OnCmdAddColumn() 
{
	CGridColumnSelectorDlg dlg;
	int ret;

	dlg.SetData(classInfo_, &usedMembersId_);
	ret = dlg.DoModal();
	int i = usedMembersId_.size();
	if (ret == IDOK)
		DisplayGridPreview();
}

void CClassInfoDlg_Gui_Grid::DisplayGridPreview()
{
	CXmlMemberInfo* member;
	int i;
	CString tmp;
	int firstColumnIndex;
	CGridCellNumeric* cellNum;

	grid_.DeleteAllItems();
	
	firstColumnIndex = chkDisplayNumberColumn_.GetCheck();
	grid_.SetColumnCount(firstColumnIndex + usedMembersId_.size());
	grid_.SetFixedColumnCount(firstColumnIndex);
	grid_.SetFixedRowCount(1);
	grid_.SetFixedRowSelection(FALSE);

	// set headers
	//
	vector<cmString>::iterator it;
	
	i = firstColumnIndex;
	for (it = usedMembersId_.begin(); it != usedMembersId_.end();) {
		member = dynamic_cast<CXmlMemberInfo*>(classInfo_->GetMemberById(*it, false));
		if (member) {
			grid_.GetCell(0, i)->SetText(member->GetCaption());
			it++;
			i++;
		} else {
			it = usedMembersId_.erase(it);
		}
	}

	
	/*for (i = 0; i < usedMembersId_.size(); i++) {
		member = dynamic_cast<CXmlMemberInfo*>(classInfo_->GetMemberById(usedMembersId_[i], false));
		grid_.GetCell(0, firstColumnIndex + i)->SetText(member->GetCaption());
	}
	*/
	// add sample rows
	//
	int startColumnIndex = 0;
	
	/*
	if (chkDisplayNumberColumn_.GetCheck()) {
		for (i = 1; i < 11; i++) {
			tmp.Format("%d", i);
			grid_.InsertRow(tmp);
		}
		startColumnIndex = 1;
	} 
	*/

	if (usedMembersId_.size() || chkDisplayNumberColumn_.GetCheck()) {

		for (int row = 1; row < 11; row++) {
			
				grid_.InsertRow(_T(""));

			if (chkDisplayNumberColumn_.GetCheck()) {
				if (zeroAlignedCount_)
					tmp.Format(_T("%d"), row - 1);
				else
					tmp.Format(_T("%d"), row);
				grid_.GetCell(row, 0)->SetText(tmp);
				startColumnIndex = 1;
			} 

			for (int col = 0; col < usedMembersId_.size(); col++) {
				member = dynamic_cast<CXmlMemberInfo*>(classInfo_->GetMemberById(usedMembersId_[col], false));
				
				switch(member->GetDataType()) {
					case enDataType_String:
						grid_.GetCell(row, startColumnIndex + col)->SetText(member->GetName());
						break;

					case enDataType_Long:
						grid_.SetCellType(row, startColumnIndex + col, RUNTIME_CLASS(CGridCellNumeric));
						cellNum = dynamic_cast<CGridCellNumeric*>(grid_.GetCell(row, startColumnIndex + col));
						cellNum->SetFormat(1, 0);
						grid_.GetCell(row, startColumnIndex + col)->SetText(member->GetName());
						break;

					case enDataType_Double:
						grid_.SetCellType(row, startColumnIndex + col, RUNTIME_CLASS(CGridCellNumeric));
						cellNum = dynamic_cast<CGridCellNumeric*>(grid_.GetCell(row, firstColumnIndex + col));
						cellNum->SetFormat(member->GetDigitPlaces(), member->GetDecimalPlaces());
						cellNum->SetSeparators('.',',');
						grid_.GetCell(row, startColumnIndex + col)->SetText(member->GetName());
						break;

					case enDataType_Boolean:
						grid_.SetCellType(row ,startColumnIndex + col, RUNTIME_CLASS(CGridCellCheck));
						grid_.GetCell(row, startColumnIndex + col)->SetText(member->GetName());
						break;
				}
				grid_.GetCell(row, col + startColumnIndex)->SetText(member->GetName());
			}
		}	
	}
	
	//grid_.RedrawWindow();
}

void CClassInfoDlg_Gui_Grid::OnChkDisplayNumberColumn() 
{
	DisplayGridPreview();
	EnableOptions();
}

void CClassInfoDlg_Gui_Grid::OnCmdRemoveColumn() 
{
	CCellRange r;
	int columnIndex;

	r = grid_.GetSelectedCellRange();

	columnIndex = r.GetMaxCol();

	if (columnIndex == -1)
		return;

	if (columnIndex == 0 && chkDisplayNumberColumn_.GetCheck()) {
		chkDisplayNumberColumn_.SetCheck(FALSE);
	} else {
		if (chkDisplayNumberColumn_.GetCheck())
			columnIndex--;

		usedMembersId_.erase(usedMembersId_.begin() + columnIndex);
	}
	
	DisplayGridPreview();
}

void CClassInfoDlg_Gui_Grid::OnCmdMoveLeft() 
{
	CCellRange r;
	int columnIndex;

	r = grid_.GetSelectedCellRange();

	columnIndex = r.GetMaxCol();

	if (columnIndex == -1 || columnIndex == 0)
		return;

	if (columnIndex == 1 && chkDisplayNumberColumn_.GetCheck())
		return;

	cmString id;

	if (chkDisplayNumberColumn_.GetCheck())
		columnIndex--;

	id = usedMembersId_[columnIndex];
	usedMembersId_.erase(usedMembersId_.begin() + columnIndex);
	columnIndex--;
	usedMembersId_.insert(usedMembersId_.begin() + columnIndex, id);

	DisplayGridPreview();

	grid_.SetSelectedRange(0, 
						   columnIndex + chkDisplayNumberColumn_.GetCheck(), 
						   0,
						   columnIndex + chkDisplayNumberColumn_.GetCheck(), TRUE);
}

void CClassInfoDlg_Gui_Grid::OnCmdMoveRight() 
{
	CCellRange r;
	int columnIndex;

	r = grid_.GetSelectedCellRange();

	columnIndex = r.GetMaxCol();

	if (columnIndex == -1)
		return;

	if (columnIndex == grid_.GetColumnCount() - 1 && chkDisplayNumberColumn_.GetCheck())
		return;

	cmString id;

	if (chkDisplayNumberColumn_.GetCheck())
		columnIndex--;

	id = usedMembersId_[columnIndex];
	usedMembersId_.erase(usedMembersId_.begin() + columnIndex);
	columnIndex++;
	usedMembersId_.insert(usedMembersId_.begin() + columnIndex, id);

	DisplayGridPreview();

	grid_.SetSelectedRange(0, 
						   columnIndex + chkDisplayNumberColumn_.GetCheck(), 
						   0,
						   columnIndex + chkDisplayNumberColumn_.GetCheck(), TRUE);
	
}

void CClassInfoDlg_Gui_Grid::OnOptNumberingZero() 
{
	zeroAlignedCount_ = true;
	UpdateOptions();
	DisplayGridPreview();
}

void CClassInfoDlg_Gui_Grid::OnOptNumberingOne() 
{
	zeroAlignedCount_ = false;
	UpdateOptions();
	DisplayGridPreview();
}

void CClassInfoDlg_Gui_Grid::UpdateOptions()
{
	optZeroAlignedCount_.SetCheck(zeroAlignedCount_);
	optOneAlignedCount_.SetCheck(!zeroAlignedCount_);	
}

void CClassInfoDlg_Gui_Grid::EnableOptions()
{
	optZeroAlignedCount_.EnableWindow(chkDisplayNumberColumn_.GetCheck());
	optOneAlignedCount_.EnableWindow(chkDisplayNumberColumn_.GetCheck());	
}
