// MemberInfoDlg_Gui.cpp : implementation file
//

#include "stdafx.h"
#include "AsCfgBuilder.h"
#include "memberinfodlg_gui.h"
#include "XmlMemberInfo.h"
#include "GuiDefs.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMemberInfoDlg_Gui dialog


CMemberInfoDlg_Gui::CMemberInfoDlg_Gui(CWnd* pParent /*=NULL*/)
	: CPropertyEditorDlg(CMemberInfoDlg_Gui::IDD, pParent),
	memberInfo_(NULL),
	currentDataType_(enDataType_None),
	activeChild_(NULL),
	initialized_(false)
{
	//{{AFX_DATA_INIT(CMemberInfoDlg_Gui)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CMemberInfoDlg_Gui::DoDataExchange(CDataExchange* pDX)
{
	CPropertyEditorDlg::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMemberInfoDlg_Gui)
	DDX_Control(pDX, IDC_CHK_READONLY, chkReadOnly_);
	DDX_Control(pDX, IDC_CBO_DISPLAY_MODE, cboDisplayMode_);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMemberInfoDlg_Gui, CPropertyEditorDlg)
	//{{AFX_MSG_MAP(CMemberInfoDlg_Gui)
	ON_WM_SIZE()
	ON_CBN_SELCHANGE(IDC_CBO_DISPLAY_MODE, OnSelchangeCboDisplayMode)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMemberInfoDlg_Gui message handlers

void CMemberInfoDlg_Gui::SetData(CXmlBaseElement* element)
{
	memberInfo_ = dynamic_cast<CXmlMemberInfo*>(element);
	assert(memberInfo_);
	if (memberInfo_ == NULL)
		return;

	currentDataType_ = memberInfo_->GetDataType();

	DisplayData();
}

void CMemberInfoDlg_Gui::StoreData()
{
	switch (currentDataType_) {
		case enDataType_String:
			StoreStringGuiInfo();
			break;

		case enDataType_Long:
			StoreLongGuiInfo();
			break;

		case enDataType_Boolean:
			StoreBooleanGuiInfo();
			break;

		case enDataType_Double:
			StoreDoubleGuiInfo();
			break;
	}
}

void CMemberInfoDlg_Gui::OnDataUpdate()
{
	if (memberInfo_->GetDataType() == currentDataType_)
		return;

	StoreData();
	
	currentDataType_ = memberInfo_->GetDataType();

	DisplayData();
}

void CMemberInfoDlg_Gui::StoreStringGuiInfo()
{
	enStringMemberDisplayMode displayMode;

	cboDisplayMode_.GetSelKey((int&)displayMode);
	memberInfo_->GetStringMemberGuiInfo()->SetDisplayMode(displayMode);
	memberInfo_->SetReadOnly(chkReadOnly_.GetCheck() == TRUE);
	if (activeChild_)
		activeChild_->StoreData();

}

void CMemberInfoDlg_Gui::StoreLongGuiInfo()
{
	enLongMemberDisplayMode displayMode;

	cboDisplayMode_.GetSelKey((int&)displayMode);
	memberInfo_->GetLongMemberGuiInfo()->SetDisplayMode(displayMode);
	memberInfo_->SetReadOnly(chkReadOnly_.GetCheck() == TRUE);
	if (activeChild_)
		activeChild_->StoreData();
}

void CMemberInfoDlg_Gui::StoreBooleanGuiInfo()
{
	enBooleanMemberDisplayMode displayMode;

	cboDisplayMode_.GetSelKey((int&)displayMode);
	memberInfo_->GetBooleanMemberGuiInfo()->SetDisplayMode(displayMode);
	memberInfo_->SetReadOnly(chkReadOnly_.GetCheck() == TRUE);
	if (activeChild_)
		activeChild_->StoreData();
}

void CMemberInfoDlg_Gui::StoreDoubleGuiInfo()
{
	enDoubleMemberDisplayMode displayMode;

	cboDisplayMode_.GetSelKey((int&)displayMode);
	memberInfo_->GetDoubleMemberGuiInfo()->SetDisplayMode(displayMode);
	memberInfo_->SetReadOnly(chkReadOnly_.GetCheck() == TRUE);
	if (activeChild_)
		activeChild_->StoreData();
}

void CMemberInfoDlg_Gui::DisplayStringGuiInfo()
{
	SwitchChild(activeChild_, NULL);

	cboDisplayMode_.Clear();
	cboDisplayMode_.AddItem(_T("Keep hidden"), enStringMemberDisplayMode_None);
	cboDisplayMode_.AddItem(_T("Generic String"), enStringMemberDisplayMode_GenericString);
	
	cboDisplayMode_.SelectItem(memberInfo_->GetStringMemberGuiInfo()->GetDisplayMode());

	UpdateReadOnlyCheckBox();
}

void CMemberInfoDlg_Gui::DisplayLongGuiInfo()
{
	cboDisplayMode_.Clear();
	cboDisplayMode_.AddItem(_T("Keep hidden"), enLongMemberDisplayMode_None);
	cboDisplayMode_.AddItem(_T("Decimal Number"), enLongMemberDisplayMode_Decimal);
	cboDisplayMode_.AddItem(_T("Hexadecimal Number"), enLongMemberDisplayMode_Hex);
	cboDisplayMode_.AddItem(_T("Smart Hexadecimal/Long Number"), enLongMemberDisplayMode_Smart);

	cboDisplayMode_.SelectItem(memberInfo_->GetLongMemberGuiInfo()->GetDisplayMode());

	switch (memberInfo_->GetLongMemberGuiInfo()->GetDisplayMode()) {
		case enLongMemberDisplayMode_None:
			SwitchChild(activeChild_, NULL);
			break;

		case enLongMemberDisplayMode_Decimal:
			SwitchChild(activeChild_, NULL);
			break;

		case enLongMemberDisplayMode_Hex:
			SwitchChild(activeChild_, &longHexDlg_);
			longHexDlg_.SetData(memberInfo_->GetLongMemberGuiInfo());
			break;

		case enLongMemberDisplayMode_Smart:
			SwitchChild(activeChild_, NULL);
			break;

	}

	UpdateReadOnlyCheckBox();
}

void CMemberInfoDlg_Gui::DisplayBooleanGuiInfo()
{
	SwitchChild(activeChild_, NULL);

	cboDisplayMode_.Clear();
	cboDisplayMode_.AddItem(_T("Keep hidden"), enBooleanMemberDisplayMode_None);
	cboDisplayMode_.AddItem(_T("CheckBox"), enBooleanMemberDisplayMode_CheckBox);
	
	cboDisplayMode_.SelectItem(memberInfo_->GetBooleanMemberGuiInfo()->GetDisplayMode());

	UpdateReadOnlyCheckBox();
}

void CMemberInfoDlg_Gui::DisplayDoubleGuiInfo()
{
	SwitchChild(activeChild_, NULL);

	cboDisplayMode_.Clear();
	cboDisplayMode_.AddItem(_T("Keep hidden"), enDoubleMemberDisplayMode_None);
	cboDisplayMode_.AddItem(_T("Generic number"), enDoubleMemberDisplayMode_GenericNumber);
	
	cboDisplayMode_.SelectItem(memberInfo_->GetDoubleMemberGuiInfo()->GetDisplayMode());

	UpdateReadOnlyCheckBox();
}

BOOL CMemberInfoDlg_Gui::OnInitDialog() 
{
	CPropertyEditorDlg::OnInitDialog();
	
	longHexDlg_.Create(longHexDlg_.IDD, this);

	initialized_ = true;

	UpdateWindowSize();

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

void CMemberInfoDlg_Gui::UpdateWindowSize()
{
	if (!initialized_)
		return;

	if (activeChild_) {
		CRect cboRect;
		CRect rc;
		CRect childRect;

		cboDisplayMode_.GetWindowRect(cboRect);
		ScreenToClient(cboRect);
		GetClientRect(rc);

		childRect.left = BORDER;
		childRect.top = cboRect.bottom + BORDER;
		childRect.right = rc.right - BORDER;
		childRect.bottom = rc.bottom - BORDER;

		activeChild_->SetWindowPos(&CWnd::wndTop, childRect.left, childRect.top, childRect.Width(), childRect.Height(), SWP_SHOWWINDOW);
	}
}

void CMemberInfoDlg_Gui::OnSize(UINT nType, int cx, int cy) 
{
	CPropertyEditorDlg::OnSize(nType, cx, cy);
	
	UpdateWindowSize();	
}

void CMemberInfoDlg_Gui::OnSelchangeCboDisplayMode() 
{
	StoreData();
	DisplayData();
}

void CMemberInfoDlg_Gui::DisplayData()
{
	chkReadOnly_.SetCheck(memberInfo_->IsReadOnly());
	switch (currentDataType_) {
		case enDataType_String:
			DisplayStringGuiInfo();
			break;

		case enDataType_Long:
			DisplayLongGuiInfo();
			break;

		case enDataType_Boolean:
			DisplayBooleanGuiInfo();
			break;

		case enDataType_Double:
			DisplayDoubleGuiInfo();
			break;
	}

	UpdateReadOnlyCheckBox();
}

void CMemberInfoDlg_Gui::SwitchChild(CPropertyEditorDlg* oldChild, CPropertyEditorDlg* newChild)
{
	if (activeChild_)
		activeChild_->ShowWindow(SW_HIDE);

	activeChild_ = newChild;

	UpdateWindowSize();
}

void CMemberInfoDlg_Gui::OnOK()
{
	
}

void CMemberInfoDlg_Gui::OnCancel()
{
	
}

void CMemberInfoDlg_Gui::UpdateReadOnlyCheckBox()
{
	bool enable = false;

	switch (currentDataType_) {
		case enDataType_String:
			enable = (memberInfo_->GetStringMemberGuiInfo()->GetDisplayMode() != enStringMemberDisplayMode_None);
			break;

		case enDataType_Long:
			enable = (memberInfo_->GetLongMemberGuiInfo()->GetDisplayMode() != enLongMemberDisplayMode_None);
			break;

		case enDataType_Double:
			enable = (memberInfo_->GetDoubleMemberGuiInfo()->GetDisplayMode() != enDoubleMemberDisplayMode_None);
			break;

		case enDataType_Boolean:
			enable = (memberInfo_->GetBooleanMemberGuiInfo()->GetDisplayMode() != enBooleanMemberDisplayMode_None);
			break;
	}

	chkReadOnly_.EnableWindow(enable);
}