// AsOptionRow.cpp: implementation of the CAsOptionRow class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "AsOptionRow.h"
#include "AsBaseCell.h"
#include "AsGenericTextCell.h"
#include "AsCheckBoxCell.h"
#include "AsComboBoxCell.h"
#include "AsNumericTextCell.h"
#include "AsHexadecimalTextCell.h"
#include "AsBinaryWildCardsCell.h"
#include "IAsOptionRowListener.h"

/*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
*/
int CAsOptionRow::SplitterArea_ = 4;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAsOptionRow::CAsOptionRow():
	valueCell_(NULL),
	verticalSplitterPos_(200),
	borderColor_(::GetSysColor(COLOR_3DSHADOW)),
	parentWnd_(NULL),
	selected_(false),
	listener_(NULL)
{
	
}

CAsOptionRow::~CAsOptionRow()
{
	if (valueCell_)
		delete valueCell_;
}

CAsBaseCell* CAsOptionRow::GetCaptionCell()
{
	return &captionCell_;
}


CAsBaseCell* CAsOptionRow::GetValueCell()
{
	return valueCell_;
}

void CAsOptionRow::Draw(CDC* pDC)
{
	captionCell_.Draw(pDC);
	//if (!selected_)
	valueCell_->Draw(pDC);

	// draw vertical divider
	//
	CPen pen(PS_SOLID, 1, borderColor_);
	CPen* oldPen;
	
	oldPen = pDC->SelectObject(&pen);

	pDC->MoveTo(verticalSplitterPos_, drawArea_.top);
	pDC->LineTo(verticalSplitterPos_, drawArea_.bottom + 1);
	
	pDC->MoveTo(drawArea_.right, drawArea_.top);
	pDC->MoveTo(drawArea_.right, drawArea_.bottom + 1);

	pDC->SelectObject(oldPen);

	//TRACE1("DrawRow caption =%s\n", caption_.c_str());
}

void CAsOptionRow::SetValueCellType(enCellType cellType)
{
	CreateCell(cellType);

}

CAsBaseCell* CAsOptionRow::CreateCell(enCellType cellType)
{
	if(valueCell_)
		delete valueCell_;

	switch (cellType) {
		case enCellType_Caption:
			valueCell_ = new CAsBaseCell;
			break;

		case enCellType_TextBox:
			valueCell_ = new CAsGenericTextCell;
			break;

		case enCellType_NumTextBox:
			valueCell_ = new CAsNumericTextCell;
			break;

		case enCellType_CheckBox:
			valueCell_ = new CAsCheckBoxCell;
			break;

		case enCellType_ComboBox:
			valueCell_ = new CAsComboBoxCell;
			break;

		case enCellType_HexTextBox:
			valueCell_ = new CAsHexadecimalTextCell;
			break;

		case enCellType_BinaryWildCards:
			valueCell_ = new CAsBinaryWildCardsCell;
			break;
	}

	valueCell_->SetParentWindow(parentWnd_);
	valueCell_->SetFontInfo(fontInfo_);

	return valueCell_;
}

void CAsOptionRow::SetDrawArea(const CRect& drawArea)
{
	drawArea_ = drawArea;

	CRect tmp;

	tmp = drawArea_;
	tmp.right = verticalSplitterPos_;
	captionCell_.SetDrawArea(tmp);

	tmp = drawArea_;
	tmp.left = verticalSplitterPos_ + 1;
	valueCell_->SetDrawArea(tmp);
}

CRect CAsOptionRow::GetDrawArea() const
{
	return drawArea_;
}

void CAsOptionRow::SetVerticalSplitterPos(int pos)
{
	verticalSplitterPos_ = pos;

	SetDrawArea(drawArea_);
}

int CAsOptionRow::GetVerticalSplitterPos() const
{
	return verticalSplitterPos_;
}

void CAsOptionRow::SetParentWindow(CWnd* parentWnd)
{
	parentWnd_ = parentWnd;
	
	captionCell_.SetParentWindow(parentWnd_);
}

bool CAsOptionRow::ProcessMessage(DWORD msg, DWORD lParam, DWORD wParam, const CPoint& pt, const CRect& parentRect, bool& needRedraw)
{
	bool processed = false;
	bool oldSelection;

	oldSelection = selected_;
	processed = captionCell_.ProcessMessage(msg, lParam, wParam, pt, parentRect, needRedraw);
	processed = valueCell_->ProcessMessage(msg, lParam, wParam, pt, parentRect, needRedraw);
	
	if (oldSelection != selected_)
		needRedraw = true;

	Select(valueCell_->IsSelected() || captionCell_.IsSelected(), false);
	UpdateColors();

	return processed;
}

void CAsOptionRow::SetFontInfo(const cmString& fontName, int fontSize, bool fontBold)
{
	CAsFontInfo tmp;

	tmp.SetFontName(fontName);
	tmp.SetFontSize(fontSize);
	tmp.SetFontBold(fontBold);

	SetFontInfo(tmp);
}

void CAsOptionRow::SetFontInfo(const CAsFontInfo& fontInfo)
{
	fontInfo_ = fontInfo;

	captionCell_.SetFontInfo(fontInfo);

	if(valueCell_)
		valueCell_->SetFontInfo(fontInfo);
}

CAsOptionRow::enOptionRowHitTest CAsOptionRow::HitTest(const CPoint& pt)
{
	if (pt.x >= verticalSplitterPos_ - SplitterArea_ && pt.x <= verticalSplitterPos_ + SplitterArea_)
		return enOptionRowHitTest_Splitter;

	if (captionCell_.HitTest(pt))
		return enOptionRowHitTest_Caption;

	if (valueCell_->HitTest(pt))
		return enOptionRowHitTest_Value;

	return enOptionRowHitTest_None;
}

void CAsOptionRow::Select(bool selection, bool redraw)
{
	if (selected_ == selection && (valueCell_->IsSelected() == selection || valueCell_->HasFocus() == selection))
		return;

	selected_ = selection;

	UpdateColors();
	
	if (selected_) {
		if (listener_)
			listener_->OnRowSelection(this, redraw);
		captionCell_.SetSelection(redraw);
		if (!valueCell_->IsSelected() && !valueCell_->HasFocus())
			valueCell_->SetSelection(redraw);
	} else {
		valueCell_->KillFocus(true, redraw);
		valueCell_->KillSelection(redraw);
		captionCell_.KillSelection(redraw);
		//parentWnd_->SetFocus();
	}

	if (redraw && parentWnd_)
		parentWnd_->RedrawWindow(captionCell_.GetDrawArea());
}

void CAsOptionRow::UpdateColors()
{
	if (selected_) {
		captionCell_.SetBackColor(::GetSysColor(COLOR_HIGHLIGHT));
		captionCell_.SetForeColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
	} else {
		captionCell_.SetBackColor(::GetSysColor(COLOR_WINDOW));
		captionCell_.SetForeColor(::GetSysColor(COLOR_WINDOWTEXT));
	}	
}

bool CAsOptionRow::IsSelected() const
{
	return selected_;
}

bool CAsOptionRow::HasFocus()
{
	return valueCell_->HasFocus();
}

void CAsOptionRow::SetCaption(const cmString& caption)
{
	caption_ = caption;

	captionCell_.SetText(caption);
}

cmString CAsOptionRow::GetCaption() const
{
	return caption_;
}

void CAsOptionRow::SetDescription(const cmString& description)
{
	description_ = description;
}

cmString CAsOptionRow::GetDescription() const
{
	return description_;
}

void CAsOptionRow::RegisterListener(IAsOptionRowListener* listener)
{
	listener_ = listener;
}