// MemberInfoDlg_Validation.cpp : implementation file
//

#include "stdafx.h"
#include "MemberInfoDlg_Validation.h"
#include "XmlMemberInfo.h"
#include "MemDC.h"
#include "enums.h"
#include "MemberInfoDlg_ValidationInterval.h"
#include "MemberInfoDlg_ValidationStaticEnum.h"
#include "MemberInfoDlg_ValidationDynamicEnum.h"
#include "DrawUtils.h"

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

#define TIP_RECT_HEIGHT 200

/////////////////////////////////////////////////////////////////////////////
// CMemberInfoDlg_Validation dialog


CMemberInfoDlg_Validation::CMemberInfoDlg_Validation(CWnd* pParent /*=NULL*/)
	: CPropertyEditorDlg(CMemberInfoDlg_Validation::IDD, pParent),
	intervalDlg_(NULL),
	staticEnumDlg_(NULL),
	dynamicEnumDlg_(NULL),
	selDialog_(NULL),
	initialized_(false),
	dataType_(enDataType_None),
	showTipRect_(true)
{
	//{{AFX_DATA_INIT(CMemberInfoDlg_Validation)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CMemberInfoDlg_Validation::~CMemberInfoDlg_Validation()
{
	if (intervalDlg_)
		delete intervalDlg_;

	if (staticEnumDlg_)
		delete staticEnumDlg_;

	if (dynamicEnumDlg_)
		delete dynamicEnumDlg_;
}

void CMemberInfoDlg_Validation::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMemberInfoDlg_Validation)
	DDX_Control(pDX, IDC_CBO_VALIDATION_MODE, cboValidationMode_);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMemberInfoDlg_Validation, CPropertyEditorDlg)
	//{{AFX_MSG_MAP(CMemberInfoDlg_Validation)
	ON_CBN_SELCHANGE(IDC_CBO_VALIDATION_MODE, OnSelchangeCboValidationMode)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMemberInfoDlg_Validation message handlers
void CMemberInfoDlg_Validation::StoreData()
{
	enValidationMode validationMode;

	cboValidationMode_.GetSelKey((int&)validationMode);

	memberInfo_->GetValidationInfo()->SetValidationMode(validationMode);
	switch (validationMode) {
	
		case enValidationMode_None:
			selDialog_ = NULL;
			break;

		case enValidationMode_Interval:
			if (dataType_ == enDataType_Long || dataType_ == enDataType_Double)
				intervalDlg_->StoreData();
			else
				memberInfo_->GetValidationInfo()->SetValidationMode(enValidationMode_None);
			break;

		case enValidationMode_StaticEnum:
			if (dataType_ == enDataType_Long || dataType_ == enDataType_Double || dataType_ == enDataType_String)
				staticEnumDlg_->StoreData();
			else
				memberInfo_->GetValidationInfo()->SetValidationMode(enValidationMode_None);
			break;

		case enValidationMode_DynamicEnum:
			dynamicEnumDlg_->StoreData();
			break;
	}
}

void CMemberInfoDlg_Validation::SetData(CXmlBaseElement* element)
{
	memberInfo_ = dynamic_cast<CXmlMemberInfo*>(element);

	intervalDlg_->SetData(element);
	staticEnumDlg_->SetData(element);
	dynamicEnumDlg_->SetData(element);

	if (memberInfo_) {
		cboValidationMode_.SelectItem(memberInfo_->GetValidationInfo()->GetValidationMode());
		dataType_ = memberInfo_->GetDataType();
	} else {
		cboValidationMode_.SelectItem(enValidationMode_None);
		dataType_ = enDataType_None;
	}

	OnSelchangeCboValidationMode();
}

void CMemberInfoDlg_Validation::OnDataUpdate()
{
	if (memberInfo_ && memberInfo_->GetDataType() != dataType_) {
		intervalDlg_->OnDataUpdate();
		staticEnumDlg_->OnDataUpdate();
		dynamicEnumDlg_->OnDataUpdate();

		dataType_ = memberInfo_->GetDataType();

		OnSelchangeCboValidationMode();
	}
}



void CMemberInfoDlg_Validation::DrawBackground(CDC* pDC)
{
	CBaseDialog::DrawBackground(pDC);
	
	DrawTipRect(pDC);
}

void CMemberInfoDlg_Validation::DrawTipRect(CDC* pDC)
{
	if (!showTipRect_)
		return;

	CBrush b(::GetSysColor(COLOR_INFOBK));

	CRect rc;
	CRect cboRect;
	CPoint topLeft;
	CRect tipRect;

	cboValidationMode_.GetWindowRect(cboRect);
	ScreenToClient(cboRect);

	GetClientRect(rc);
	tipRect = rc;
	tipRect.top = rc.bottom - TIP_RECT_HEIGHT;
	if (tipRect.top < cboRect.bottom + 5)
		tipRect.top = cboRect.bottom + 5;

	tipRect.DeflateRect(5, 0, 5, 5);

	if (tipRect.Height() < 36)
		return;

	pDC->FillRect(tipRect, &b);
	DrawUtils::DrawRect(pDC, tipRect, ::GetSysColor(COLOR_3DSHADOW));
	
	topLeft = tipRect.TopLeft();
	topLeft.Offset(10, 10);

	DrawUtils::DrawIcon(pDC, IDI_INFO, topLeft, 16);

	tipRect.DeflateRect(36, 10, 10, 10);
	DrawUtils::DrawString(pDC, tipText_, tipRect, DT_LEFT, ::GetSysColor(COLOR_INFOTEXT), GetFont());
}



BOOL CMemberInfoDlg_Validation::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	ModifyStyle(0, WS_CLIPCHILDREN);

	cboValidationMode_.AddItem(_T("No validation"), enValidationMode_None);
	cboValidationMode_.AddItem(_T("Numeric interval"), enValidationMode_Interval);
	cboValidationMode_.AddItem(_T("Static Enumerative"), enValidationMode_StaticEnum);
	cboValidationMode_.AddItem(_T("Dynamic Enumerative"), enValidationMode_DynamicEnum);

	cboValidationMode_.SelectItem(enValidationMode_None);

	intervalDlg_ = new CMemberInfoDlg_ValidationInterval;
	staticEnumDlg_ = new CMemberInfoDlg_ValidationStaticEnum;
	dynamicEnumDlg_ = new CMemberInfoDlg_ValidationDynamicEnum;

	intervalDlg_->Create(intervalDlg_->IDD, this);
	staticEnumDlg_->Create(staticEnumDlg_->IDD, this);
	dynamicEnumDlg_->Create(dynamicEnumDlg_->IDD, this);

	initialized_ = true;
	
	tipText_ = _T("No validation selected");
	UpdateWindowSize();

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

void CMemberInfoDlg_Validation::OnSelchangeCboValidationMode() 
{
	enValidationMode validationMode;
	enDataType dataType;

	cboValidationMode_.GetSelKey((int&)validationMode);

	if (selDialog_)
		selDialog_->ShowWindow(SW_HIDE);

	dataType = memberInfo_->GetDataType();

	switch (validationMode) {
	
		case enValidationMode_None:
			selDialog_ = NULL;
			showTipRect_ = true;
			tipText_ = _T("No validation selected");
			break;

		case enValidationMode_Interval:
			if (memberInfo_ && (dataType == enDataType_Long || dataType == enDataType_Double)) {
				selDialog_ = intervalDlg_;
				showTipRect_ = false;
				tipText_ = _T("");
			} else {
				selDialog_ = NULL;
				showTipRect_ = true;
				tipText_ = _T("The data type currently selected does not support this kind of validation.");
			}
			break;

		case enValidationMode_StaticEnum:
			if (memberInfo_ && (dataType == enDataType_Long || dataType == enDataType_Double || dataType == enDataType_String)) {
				selDialog_ = staticEnumDlg_;
				showTipRect_ = false;
				tipText_ = _T("");
			} else {
				selDialog_ = NULL;
				showTipRect_ = true;
				tipText_ = _T("The data type currently selected does not support this kind of validation.");
			}
			break;

		case enValidationMode_DynamicEnum:
			selDialog_ = dynamicEnumDlg_;
			showTipRect_ = false;
			tipText_ = _T("");
			break;
	}

	//cboValidationMode_.RedrawWindow();

	UpdateWindowSize();
}


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

	if (selDialog_) {
		CRect rc;
		CRect cboRect;

		cboValidationMode_.GetWindowRect(cboRect);
		ScreenToClient(cboRect);

		GetClientRect(rc);
		rc.DeflateRect(5, cboRect.bottom + 5, 5, 5);

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

	RedrawWindow();
}

void CMemberInfoDlg_Validation::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	UpdateWindowSize();	
}

BOOL CMemberInfoDlg_Validation::PreTranslateMessage(MSG* pMsg) 
{
	
	return CDialog::PreTranslateMessage(pMsg);
}
