// CategoryFieldEditorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "XmlClassInfo.h"
#include "XmlGuiCategoryField.h"
#include "XmlGuiCategoryInfoList.h"
#include "XmlGuiCategoryInfo.h"
#include "XmlMemberInfo.h"
#include "CategoryFieldEditorDlg.h"
#include "GuiDefs.h"

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

/////////////////////////////////////////////////////////////////////////////
// CCategoryFieldEditorDlg dialog


CCategoryFieldEditorDlg::CCategoryFieldEditorDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCategoryFieldEditorDlg::IDD, pParent),
	classInfo_(NULL),
	categoryField_(NULL),
	categoryList_(NULL),
	editMode_(false),
	initialized_(false)
{
	//{{AFX_DATA_INIT(CCategoryFieldEditorDlg)
	//}}AFX_DATA_INIT
}


void CCategoryFieldEditorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCategoryFieldEditorDlg)
	DDX_Control(pDX, IDC_LBL_DESCRIPTION, lblDescription_);
	DDX_Control(pDX, IDC_TXT_CATEGORY, txtCategory_);
	DDX_Control(pDX, IDC_LBL_RELATED, lblRelated_);
	DDX_Control(pDX, IDC_LBL_CAPTION, lblCaption_);
	DDX_Control(pDX, IDOK, cmdOk_);
	DDX_Control(pDX, IDCANCEL, cmdCancel_);
	DDX_Control(pDX, IDC_TXT_DESCRIPTION, txtDescription_);
	DDX_Control(pDX, IDC_TXT_CAPTION, txtCaption_);
	DDX_Control(pDX, IDC_LBL_CATEGORY, lblCategoryName_);
	DDX_Control(pDX, IDC_CBO_RELATED_CLASS_MEMBER, cboRelatedClassMember_);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CCategoryFieldEditorDlg, CDialog)
	//{{AFX_MSG_MAP(CCategoryFieldEditorDlg)
	ON_CBN_SELCHANGE(IDC_CBO_RELATED_CLASS_MEMBER, OnSelChangeField)
	ON_WM_SIZE()
	ON_WM_GETMINMAXINFO()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCategoryFieldEditorDlg message handlers

void CCategoryFieldEditorDlg::Init(CXmlClassInfo* classInfo, 
								   CXmlGuiCategoryField* categoryField,
								   CXmlGuiCategoryInfoList* categoryList,
								   const cmString& categoryName)
{
	classInfo_ = classInfo;
	categoryField_ = categoryField;
	categoryField_->SetClassInfo(classInfo);
	categoryList_ = categoryList;
	categoryName_ = categoryName;

	editMode_ = (categoryField->GetMemberName().GetLength() != 0);
}

BOOL CCategoryFieldEditorDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// Fill up combo box
	//
	ClassMemberMap* members;
	ClassMemberMap::iterator it;
	CXmlBaseElement* member;
	int selIndex;
	int i;

	members = classInfo_->GetMembers();
	selIndex  = (cboRelatedClassMember_.GetCount() ? 0 : -1);
	i = 0;
	for (it = members->begin(); it != members->end(); it++) {
		member = it->second;

		if (member->GetDataType() != enDataType_Class) {
			cboRelatedClassMember_.AddString(member->GetName());
			if (member->GetId() == categoryField_->GetMemberId())
				selIndex = i;
			i++;
		}
	}
	cboRelatedClassMember_.SetCurSel(selIndex);
	
	txtCategory_.SetWindowText(categoryName_);

	if (categoryField_->GetMemberId() != _T(""))  {
		SetWindowText(_T("Edit Category Field"));
				
		txtCaption_.SetWindowText(categoryField_->GetCaption());
		txtDescription_.SetWindowText(categoryField_->GetDescription());
		
		cboRelatedClassMember_.SelectString(-1, categoryField_->GetCaption());
	} else {
		SetWindowText(_T("Add Category Field"));

		txtCaption_.SetWindowText(_T(""));
		txtDescription_.SetWindowText(_T(""));
	}

	initialized_ = true;

	UpdateWindowSize();

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

void CCategoryFieldEditorDlg::OnOK()
{
	int selIndex;
	CXmlBaseElement* member;
	cmString caption;
	cmString description;
	cmString memberName;
	CXmlGuiCategoryField* field;

	// verify that there is a selected field
	//
	selIndex = cboRelatedClassMember_.GetCurSel();
	if (selIndex == CB_ERR) {
		MessageBox(_T("No member selected"));
		return;
	}

	// verify that this variable is not already in use
	//
	cboRelatedClassMember_.GetLBText(selIndex, memberName);
	categoryList_->SetClassInfo(classInfo_);
	field = categoryList_->GetFieldByMemberName(memberName);
	if (field != categoryField_ && field != NULL) {
		cmString msg;
		
		msg = _T("Member \"") + memberName + _T("\" already in use");
		MessageBox(msg);
		return;
	}

	// verify that the caption is not empty
	//
	txtCaption_.GetWindowText(caption);
	if (caption == _T("")) {
		MessageBox(_T("Invalid caption"));
		return;
	}

	// verify that the selected caption is not already used into the
	// selected category
	//
	/***
	CXmlGuiCategoryInfo* info;

	info = categoryList_->GetCategoryByName(categoryName_);
	if (info == NULL) {
		MessageBox(_T("Category not found!!!"));
		return;
	}

	field = info->GetFieldByCaption(caption);
	if (field != categoryField_ && field != NULL) {
		CString tmp;
		tmp = _T("Caption \"") + caption + _T("\" already in use");
		MessageBox(tmp);
		return;
	}
	***/

	// store selected member
	//
	member = classInfo_->GetMember( memberName);
	categoryField_->SetMemberId(member->GetId());
			
	txtDescription_.GetWindowText(description);
	categoryField_->SetDescription(description);

	CDialog::OnOK();
}

void CCategoryFieldEditorDlg::OnSelChangeField()
{
	cmString memberName;
	CXmlMemberInfo* member;

	cboRelatedClassMember_.GetLBText(cboRelatedClassMember_.GetCurSel(), memberName);

	member = dynamic_cast<CXmlMemberInfo*>(classInfo_->GetMember(memberName));
	if (member) 
		txtCaption_.SetWindowText(member->GetCaption());
}

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

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

	CRect rc;
	CRect lblRect;
	CRect txtRect;
	CRect chkRect;
	CRect btnRect;
	int lblWidth;
	int txtWidth;
	int txtHeight;
	int top;
	int i;
	int left;
	vector<CWnd*> wndList;
	
	GetClientRect(rc);

	cmdCancel_.GetWindowRect(btnRect);

	lblCategoryName_.GetWindowRect(lblRect);
	ScreenToClient(lblRect);
	
	lblWidth = lblRect.Width();
	txtWidth = rc.Width() - 3 * BORDER - lblWidth;
	
	wndList.push_back(&lblCategoryName_);
	wndList.push_back(&lblRelated_);
	wndList.push_back(&lblCaption_);
	wndList.push_back(&lblDescription_);

	top = BORDER;
	for (i = 0; i < wndList.size(); i++) {
		wndList[i]->SetWindowPos(&CWnd::wndTop, BORDER, top, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);
		top += lblRect.Height() + BORDER;
	}

	wndList.clear();
	wndList.push_back(&txtCategory_);
	wndList.push_back(&cboRelatedClassMember_);
	wndList.push_back(&txtCaption_);
	//wndList.push_back(&txtDescription_);
	
	top = BORDER;
	left = 2 * BORDER + lblWidth;
	for (i = 0; i < wndList.size(); i++) {
		wndList[i]->GetWindowRect(txtRect);
		wndList[i]->SetWindowPos(&CWnd::wndTop, left, top, txtWidth, txtRect.Height(), SWP_SHOWWINDOW);
		top += txtRect.Height() + BORDER;
	}

	txtHeight = rc.Height() - top - 2 * BORDER - btnRect.Height();
	txtDescription_.SetWindowPos(&CWnd::wndTop, left, top, txtWidth, txtHeight, SWP_SHOWWINDOW);

	cmdCancel_.SetWindowPos(&CWnd::wndTop, 
							rc.right - BORDER - btnRect.Width(), 
							rc.bottom - BORDER- btnRect.Height(), 
							0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);
	cmdOk_.SetWindowPos(&CWnd::wndTop, 
						rc.right - 2 * BORDER - 2 * btnRect.Width(), 
						rc.bottom - BORDER- btnRect.Height(), 
						0, 0, SWP_SHOWWINDOW | SWP_NOSIZE);

	cmdCancel_.RedrawWindow();
	cmdOk_.RedrawWindow();
}

void CCategoryFieldEditorDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
{
	lpMMI->ptMinTrackSize.x = 350;
	lpMMI->ptMinTrackSize.y = 200;
	
	CDialog::OnGetMinMaxInfo(lpMMI);
}
