// CppMapDialogGenerator.cpp
//

#include "stdafx.h"
#include "CppMapDialogGenerator.h"
#include "XmlClassInfo.h"
#include "XmlMemberInfo.h"
#include "XmlProjectSettings.h"
#include "XmlProject.h"

CCppMapDialogGenerator::CCppMapDialogGenerator()
{}

CCppMapDialogGenerator::~CCppMapDialogGenerator()
{}

void CCppMapDialogGenerator::Generate()
{
	cmString fileName;
	cmString pathName;

	// header file generation
	//
	headCode_ = _T("");
	Head_generateHeader();
	Head_generateIfDefBegin();
	Head_generateIncludeSection();
	Head_generateForwardDeclarations();
	Head_generateDefineSection();
	Head_generateClassBegin();
	Head_generateConstructor();
	Head_generateDestructor();
	Head_generatePublicMethods();
	Head_generateDialogData();
	Head_generateOverrides();
	Head_generateMessageMap();
	Head_generateProtectedMembers();
	Head_generateDataMembers();
	Head_generateClassEnd();
	Head_generateIfDefEnd();

	// save implementation file
	//
	pathName = BuildGeneratedSourcePath() + _T("include\\");
	fileName = GetMapDialogName() + _T(".h");
	SaveFile(cmString(pathName + fileName), headCode_);

	hGeneratedFiles_[fileName] = pathName + fileName;

	// generate implementation file
	//
	implCode_ = _T("");
	Impl_generateHeader();
	Impl_generateIncludeSection();
	Impl_generateDebugSymbols();
	Impl_generateMainTitle();
	Impl_generateConstructor();
	Impl_generateDestructor();
	Impl_generatePublicMethods();
	Impl_generateMessageMap();
	Impl_generateOnInitDialog();
	Impl_generateProtectedMembers();

	// save implementation file
	//
	pathName = BuildGeneratedSourcePath() + _T("src\\");
	fileName = GetMapDialogName() + _T(".cpp");
	SaveFile(pathName + fileName, implCode_);

	cppGeneratedFiles_[fileName] = pathName + fileName;
}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// HEADER FILE GENERATORS
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

void CCppMapDialogGenerator::Head_generateHeader()
{
	headCode_ += _T("// ") + GetMapDialogName() + _T(".h : header file") + xCrLf;
	headCode_ += _T("//") + xCrLf + xCrLf;
	headCode_ += GetGenerationTimeStamp();
}

void CCppMapDialogGenerator::Head_generateIfDefBegin()
{
	headCode_ += _T("#if !defined(") + DefineOf(GetMapDialogName()) + _T(")") + xCrLf;
	headCode_ += _T("#define ") + DefineOf(GetMapDialogName()) + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Head_generateIncludeSection()
{
	headCode_ += _T("#include \"stdafx.h\"") + xCrLf;
	headCode_ += _T("#include \"resource.h\"") + xCrLf;
	headCode_ += _T("#include \"") + GetResourceFileName() + _T(".h\"") + xCrLf;
	headCode_ += _T("#include <vector>") + xCrLf;
	headCode_ += _T("#include \"cmString.h\"") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += _T("using namespace std;") + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateForwardDeclarations()
{
	headCode_ += _T("class ") + GetMainDlgName() + _T(";") + xCrLf; 
}

void CCppMapDialogGenerator::Head_generateClassBegin()
{
	headCode_ += _T("/////////////////////////////////////////////////////////////////////////////") + xCrLf;
	headCode_ += _T("// ") + GetMapDialogName() + _T(" dialog") + xCrLf + xCrLf;

	headCode_ += _T("class ") + GetMapDialogName() + _T(" : public CDialog")  + xCrLf;
	headCode_ += _T("{")  + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateConstructor()
{
	headCode_ += _T("public:") + xCrLf;
	headCode_ += xTab + GetMapDialogName() + _T("(CWnd* pParent = NULL);") + xCrLf;
}

void CCppMapDialogGenerator::Head_generateDestructor()
{
	headCode_ += xTab + _T("virtual ~") + GetMapDialogName() + _T("();") + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Head_generatePublicMethods()
{
	headCode_ += xTab + _T("public:") + xCrLf;
	headCode_ += xTab + _T("virtual void SetData(") + GetClassName() + _T("Map* ") + GetCamelCase(classInfo_->GetName()) + _T("Map, HTREEITEM parentItem, ") + GetMainDlgName() + _T("* mainDialog);") + xCrLf;
	headCode_ += xTab + _T("virtual void StoreData();") + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateDialogData()
{
	// dialog data section
	//
	headCode_ += _T("// Dialog Data") + xCrLf;
	headCode_ += xTab + _T("//{{AFX_DATA(") +  GetDlgName() + _T(")") + xCrLf;
	headCode_ += xTab + _T("enum { IDD = 0 };")  + xCrLf;
	//headCode_ += xTab + "enum { IDD = IDD_CONTAINER_TEMPLATE };"  + xCrLf;
	headCode_ += xTab + _T("CListCtrl	lvwItemList_;") + xCrLf;
	headCode_ += xTab + _T("CButton	cmdInsert_;") + xCrLf;
	headCode_ += xTab + _T("CButton	cmdEdit_;") + xCrLf;
	headCode_ += xTab + _T("CButton	cmdDelete_;") + xCrLf;
	headCode_ += xTab + _T("CButton	cmdAppend_;") + xCrLf;
	headCode_ += xTab + _T("//}}AFX_DATA")  + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Head_generateOverrides()
{
	headCode_ += _T("// Overrides") + xCrLf;
	headCode_ += xTab + _T("// ClassWizard generated virtual function overrides") + xCrLf;
	headCode_ += xTab + _T("//{{AFX_VIRTUAL(") + GetMapDialogName() + _T(")") + xCrLf;
	headCode_ += xTab + _T("protected:") + xCrLf;
	headCode_ += xTab + _T("virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support")+ xCrLf;
	headCode_ += xTab + _T("//}}AFX_VIRTUAL") + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Head_generateMessageMap()
{
	headCode_ += _T("// Implementation") + xCrLf;
	headCode_ += _T("//") + xCrLf;
	headCode_ += _T("protected:") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("// Generated message map functions") + xCrLf;
	headCode_ += xTab + _T("//{{AFX_MSG(") + GetDlgName() + _T(")") + xCrLf;
	headCode_ += xTab + _T("afx_msg BOOL OnEraseBkgnd(CDC* pDC);") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnSize(UINT nType, int cx, int cy);") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnPaint();") + xCrLf;
	//headCode_ += xTab + "afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);" + xCrLf;
	headCode_ += xTab + _T("virtual BOOL OnInitDialog();") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnCmdDelete();") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnCmdEdit();") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnCmdInsert();") + xCrLf;
	headCode_ += xTab + _T("afx_msg void OnDblclkItemlist(NMHDR* pNMHDR, LRESULT* pResult);") + xCrLf;
	headCode_ += xTab + _T("//}}AFX_MSG") + xCrLf;
	headCode_ += xTab + _T("DECLARE_MESSAGE_MAP()") + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateProtectedMembers()
{
	headCode_ += xTab + _T("// Implementation") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("protected:") + xCrLf;
	headCode_ += xTab + _T("DECLARE_DYNCREATE(") + GetMapDialogName() + _T(");") + xCrLf;
	headCode_ += xTab + _T("void UpdateWindowSize();") + xCrLf;
	headCode_ += xTab + _T("void DisplayData();") + xCrLf;
	headCode_ += xTab + _T("int GetSelectedItemIndex();") + xCrLf;
	headCode_ += xTab + _T("void GetSelectedItems(vector<cmString>& indexList);") + xCrLf;
	headCode_ += xCrLf;
	headCode_ += xTab + _T("CBrush bkBrush_;") + xCrLf;
	headCode_ += xTab + _T("CImageList imageList_;") + xCrLf;
	headCode_ += xTab + _T("CImageList lvwImageList_;") + xCrLf;
	headCode_ += xTab + _T("cmString title_;") + xCrLf;
	headCode_ += xTab + GetMainDlgName() + _T("* mainDialog_;") + xCrLf;
	headCode_ += xTab + _T("HTREEITEM parentItem_;") + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateDataMembers()
{
	headCode_ += xTab + _T("// data members") + xCrLf;
	headCode_ += xTab + _T("//") + xCrLf;
	headCode_ += _T("protected:") + xCrLf;
	headCode_ += xTab + GetClassName() + _T("Map* map_;") + xCrLf;
	headCode_ += xTab + _T("bool initialized_;") + xCrLf;
	headCode_ += xCrLf;
}

void CCppMapDialogGenerator::Head_generateClassEnd()
{
	headCode_ += _T("};") + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Head_generateIfDefEnd()
{
	headCode_ += _T("#endif // !defined(") + DefineOf(GetMapDialogName()) + _T(")") + xCrLf + xCrLf;
}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION FILE GENERATORS
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

void CCppMapDialogGenerator::Impl_generateHeader()
{
	implCode_ += _T("// ") + GetDlgName() + _T(".cpp : implementation file") + xCrLf;
	implCode_ += _T("//") + xCrLf;
	implCode_ += GetGenerationTimeStamp();
	implCode_ += xCrLf;
}

void CCppMapDialogGenerator::Impl_generateIncludeSection()
{
	implCode_ += _T("#include \"stdafx.h\"") + xCrLf;
	implCode_ += _T("#include \"") + GetMapDialogName() + _T(".h\"") + xCrLf;
	implCode_ += _T("#include \"") + GetClassName() + _T(".h\"") + xCrLf;
	implCode_ += _T("#include \"") + GetClassName() + _T("Map.h\"") + xCrLf;
	implCode_ += _T("#include \"resource.h\"") + xCrLf;
	implCode_ += _T("#include \"MemDC.h\"") + xCrLf;
	implCode_ += _T("#include \"DrawUtils.h\"") + xCrLf;
	implCode_ += _T("#include \"InputBox.h\"") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("#define BACK_COLOR ::GetSysColor(COLOR_WINDOW)") + xCrLf;
	implCode_ += xCrLf;	
}

void CCppMapDialogGenerator::Impl_generateDebugSymbols()
{
	/*implCode_ += "#ifdef _DEBUG" + xCrLf;
	implCode_ += "#define new DEBUG_NEW" + xCrLf;
	implCode_ += "#undef THIS_FILE" + xCrLf;
	implCode_ += "static char THIS_FILE[] = __FILE__;" + xCrLf;
	implCode_ += "#endif" + xCrLf;
	implCode_ += xCrLf;*/
}

void CCppMapDialogGenerator::Impl_generateMainTitle()
{
	implCode_ += _T("/////////////////////////////////////////////////////////////////////////////") + xCrLf;
	implCode_ += _T("// ") + GetClassName() + _T(" dialog") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("IMPLEMENT_DYNCREATE(") + GetMapDialogName() + _T(", CDialog)") + xCrLf;
	implCode_ += xCrLf;
}

void CCppMapDialogGenerator::Impl_generateConstructor()
{
	implCode_ += GetMapDialogName() + _T("::") + GetMapDialogName() + _T("(CWnd* pParent /*=NULL*/):") + xCrLf;
	implCode_ += xTab + _T("CDialog(") + GetMapDialogName() + _T("::IDD, pParent),") + xCrLf;
	implCode_ += xTab + _T("map_(NULL),") + xCrLf;
	implCode_ += xTab + _T("initialized_(false),") + xCrLf;
	implCode_ += xTab + _T("parentItem_(NULL),") + xCrLf;
	implCode_ += xTab + _T("mainDialog_(NULL)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("//{{AFX_DATA_INIT(") + GetMapDialogName() + _T(")") + xCrLf;
	implCode_ += xTab + xTab + _T("// NOTE: the ClassWizard will add member initialization here") + xCrLf;
	implCode_ += xTab + _T("//}}AFX_DATA_INIT") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
	
	implCode_ += _T("void ") + GetMapDialogName() + _T("::DoDataExchange(CDataExchange* pDX)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("CDialog::DoDataExchange(pDX);") + xCrLf;
	implCode_ += xTab + _T("//{{AFX_DATA_MAP(") + GetMapDialogName() + _T(")") + xCrLf;
	implCode_ += xTab + _T("DDX_Control(pDX, IDC_ITEMLIST, lvwItemList_);") + xCrLf;
	implCode_ += xTab + _T("DDX_Control(pDX, IDC_CMD_INSERT, cmdInsert_);") + xCrLf;
	implCode_ += xTab + _T("DDX_Control(pDX, IDC_CMD_EDIT, cmdEdit_);") + xCrLf;
	implCode_ += xTab + _T("DDX_Control(pDX, IDC_CMD_DELETE, cmdDelete_);") + xCrLf;
	implCode_ += xTab + _T("DDX_Control(pDX, IDC_CMD_APPEND, cmdAppend_);") + xCrLf;
	implCode_ += xTab + _T("//}}AFX_DATA_MAP") + xCrLf;
	implCode_ += _T("}") + xCrLf;
}

void CCppMapDialogGenerator::Impl_generateDestructor()
{
	implCode_ += GetMapDialogName() + _T("::~") + GetMapDialogName() + _T("()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("}") + xCrLf + xCrLf;
}

void CCppMapDialogGenerator::Impl_generatePublicMethods()
{
	// SetData
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::SetData(") + GetClassName() + _T("Map* ") + GetCamelCase(classInfo_->GetName()) + _T("Map, HTREEITEM parentItem, ") + GetMainDlgName() + _T("* mainDialog)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("if (!initialized_)") + xCrLf;
	implCode_ += xTab + xTab + _T("OnInitDialog();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("map_ = ") + GetCamelCase(classInfo_->GetName()) + _T("Map;") + xCrLf;
	implCode_ += xTab + _T("mainDialog_ = mainDialog;") + xCrLf;
	implCode_ += xTab + _T("parentItem_ = parentItem;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("// display data") + xCrLf;
	implCode_ += xTab + _T("//") + xCrLf;
	implCode_ += xTab + _T("DisplayData();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// StoreData
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::StoreData()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
}

void CCppMapDialogGenerator::Impl_generateMessageMap()
{
	implCode_ += _T("BEGIN_MESSAGE_MAP(") + GetMapDialogName() + _T(", CDialog)") + xCrLf;
	implCode_ += xTab + _T("//{{AFX_MSG_MAP(CContainerDlg)") + xCrLf;
	implCode_ += xTab + _T("ON_WM_ERASEBKGND()") + xCrLf;
	implCode_ += xTab + _T("ON_WM_SIZE()") + xCrLf;
	implCode_ += xTab + _T("ON_WM_PAINT()") + xCrLf;
	//implCode_ += xTab + "ON_WM_CTLCOLOR()" + xCrLf;
	implCode_ += xTab + _T("ON_BN_CLICKED(IDC_CMD_DELETE, OnCmdDelete)") + xCrLf;
	implCode_ += xTab + _T("ON_BN_CLICKED(IDC_CMD_EDIT, OnCmdEdit)") + xCrLf;
	implCode_ += xTab + _T("ON_BN_CLICKED(IDC_CMD_INSERT, OnCmdInsert)") + xCrLf;
	implCode_ += xTab + _T("ON_NOTIFY(NM_DBLCLK, IDC_ITEMLIST, OnDblclkItemlist)") + xCrLf;
	implCode_ += xTab + _T("//}}AFX_MSG_MAP") + xCrLf;
	implCode_ += _T("END_MESSAGE_MAP()") + xCrLf;
	implCode_ += xCrLf;
}

void CCppMapDialogGenerator::Impl_generateOnInitDialog()
{
	implCode_ += _T("/////////////////////////////////////////////////////////////////////////////") + xCrLf;
	implCode_ += _T("// ") + GetMapDialogName() + _T(" message handlers") + xCrLf + xCrLf;

	implCode_ += _T("BOOL ") + GetMapDialogName() + _T("::OnInitDialog()") + xCrLf ;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("initialized_ = true;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("CDialog::OnInitDialog();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("imageList_.Create(32, 32, ILC_COLOR32 | ILC_MASK, 4, 10);") + xCrLf;
	implCode_ += xTab + _T("imageList_.Add(AfxGetApp()->LoadIcon(") + project_->GetProjectIcons()->GetIconKey(classInfo_->GetMapTreeIcons()->GetIconExpandedSelected())  + _T("));") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("lvwImageList_.Create(16, 16, ILC_COLOR32 | ILC_MASK, 4, 10);") + xCrLf;
	implCode_ += xTab + _T("lvwImageList_.Add(AfxGetApp()->LoadIcon(") + project_->GetProjectIcons()->GetIconKey(classInfo_->GetTreeIcons()->GetIconExpandedSelected())  + _T("));") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("lvwItemList_.SetImageList(&lvwImageList_, LVSIL_SMALL);") + xCrLf;
	implCode_ += xTab + _T("lvwItemList_.SetExtendedStyle(LVS_EX_FULLROWSELECT);") + xCrLf;
	implCode_ += xTab + _T("title_ = _T(\"") + classInfo_->GetContainerCaption() + _T("\");") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("lvwItemList_.InsertColumn(0, _T(\"\"), LVCFMT_LEFT, 200);") + xCrLf;
	implCode_ += xCrLf;
	if (!classInfo_->GetCardinalityInfo()->GetDisplayToolbar()) {
		implCode_ += xTab + _T("cmdEdit_.ShowWindow(SW_HIDE);") + xCrLf;
		implCode_ += xTab + _T("cmdInsert_.ShowWindow(SW_HIDE);") + xCrLf;
		implCode_ += xTab + _T("cmdDelete_.ShowWindow(SW_HIDE);") + xCrLf;
	}
	implCode_ += xTab + _T("cmdAppend_.ShowWindow(SW_HIDE);") + xCrLf;
	implCode_ += xTab + _T("// display data") + xCrLf;
	implCode_ += xTab + _T("//") + xCrLf;
	implCode_ += xTab + _T("DisplayData();") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("return TRUE;  // return TRUE unless you set the focus to a control") + xCrLf;
	implCode_ += xTab + _T("			   // EXCEPTION: OCX Property Pages should return FALSE")  + xCrLf;
	implCode_ += _T("}") + xCrLf + xCrLf;

}

void CCppMapDialogGenerator::Impl_generateProtectedMembers()
{
	CXmlMemberInfo* sortKeyMember;

	sortKeyMember = dynamic_cast<CXmlMemberInfo*>(classInfo_->GetMember(classInfo_->GetCardinalityInfo()->GetMapSortKey()));

	// DisplayData
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::DisplayData()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("if (!GetSafeHwnd() || map_ == NULL)") + xCrLf;
	implCode_ += xTab + xTab + _T("return;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + TypeOf(sortKeyMember->GetDataType()) + _T(" key;") + xCrLf;
	implCode_ += xTab + GetClassName() + _T("* item;") + xCrLf;
	implCode_ += xTab + _T("int i = 0;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("lvwItemList_.DeleteAllItems();") + xCrLf;
	implCode_ += xTab + _T("map_->MoveFirst();") + xCrLf;
	implCode_ += xTab + _T("while(map_->GetPair(key, &item)) {") + xCrLf;
	implCode_ += xTab + xTab + _T("lvwItemList_.InsertItem(i, key, 0);") + xCrLf;
	implCode_ += xTab + xTab + _T("i++;") + xCrLf;
	implCode_ += xTab + xTab + _T("map_->MoveNext();") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += _T("}") + xCrLf;

	// OnEraseBkgnd
	//
	implCode_ += _T("BOOL ") + GetMapDialogName() + _T("::OnEraseBkgnd(CDC* pDC)") + xCrLf; 
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("return TRUE;") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// OnSize
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnSize(UINT nType, int cx, int cy)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("CDialog::OnSize(nType, cx, cy);") + xCrLf;
	implCode_ += xCrLf;		
	implCode_ += xTab + _T("UpdateWindowSize();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// OnPaint
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnPaint()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("CPaintDC dc(this); // device context for painting") + xCrLf;
	implCode_ += xTab + _T("CMemDC memDC(&dc);") + xCrLf;
	implCode_ += xTab + _T("CBrush b(BACK_COLOR);") + xCrLf;
	implCode_ += xTab + _T("CRect rc;") + xCrLf;
	implCode_ += xTab + _T("CRect txtRect;") + xCrLf;
	implCode_ += xTab + _T("CRect border;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("GetClientRect(rc);") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("// paint background") + xCrLf;
	implCode_ += xTab + _T("//") + xCrLf;
	implCode_ += xTab + _T("memDC.FillRect(rc, &b);") + xCrLf;
	implCode_ += xTab + _T("border = rc;") + xCrLf;
	implCode_ += xTab + _T("border.DeflateRect(0, 0, 1, 1);") + xCrLf;
	implCode_ += xTab + _T("DrawUtils::DrawRect(memDC, border, ::GetSysColor(COLOR_3DSHADOW));") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("// draw icon") + xCrLf;
	implCode_ += xTab + _T("//") + xCrLf;
	implCode_ += xTab + _T("imageList_.Draw(memDC, 0, CPoint(5,5), ILD_NORMAL);") + xCrLf;
	implCode_ += xCrLf;	
	implCode_ += xTab + _T("// draw title") + xCrLf;
	implCode_ += xTab + _T("//") + xCrLf;
	implCode_ += xTab + _T("txtRect.left = 42;") + xCrLf;
	implCode_ += xTab + _T("txtRect.top = 0;") + xCrLf;
	implCode_ += xTab + _T("txtRect.right = rc.right;") + xCrLf;
	implCode_ += xTab + _T("txtRect.bottom = 37;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("DrawUtils::DrawString(memDC, title_, txtRect, DT_VCENTER | DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, _T(\"tahoma\"), -24, ::GetSysColor(COLOR_BTNTEXT));") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("CRect lvwRect;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("lvwItemList_.GetWindowRect(lvwRect);") + xCrLf;
	implCode_ += xTab + _T("ScreenToClient(lvwRect);") + xCrLf;
	implCode_ += xTab + _T("lvwRect.InflateRect(1,1,0,0);") + xCrLf;
	implCode_ += xCrLf;	
	implCode_ += xTab + _T("DrawUtils::DrawRect(memDC, lvwRect, ::GetSysColor(COLOR_BTNFACE));") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("cmdEdit_.RedrawWindow();") + xCrLf;
	implCode_ += xTab + _T("cmdInsert_.RedrawWindow();") + xCrLf;
	implCode_ += xTab + _T("cmdDelete_.RedrawWindow();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// UpdateWindowSize
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::UpdateWindowSize()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("if (GetSafeHwnd() && cmdEdit_.GetSafeHwnd()) {") + xCrLf;
	implCode_ += xTab + xTab + _T("CRect rc;") + xCrLf;
	implCode_ += xTab + xTab + _T("CRect btnRect;") + xCrLf;
	implCode_ += xTab + xTab + _T("CPoint pt;") + xCrLf;
	implCode_ += xTab + xTab + _T("GetClientRect(rc);") + xCrLf;
	implCode_ += xCrLf;	
	if (classInfo_->GetCardinalityInfo()->GetDisplayToolbar()) {
		implCode_ += xTab + xTab + _T("cmdEdit_.GetWindowRect(btnRect);") + xCrLf;
		implCode_ += xTab + xTab + _T("ScreenToClient(btnRect);") + xCrLf;
		implCode_ += xTab + xTab + _T("pt.x = rc.right - 10 - btnRect.Width();") + xCrLf;
		implCode_ += xTab + xTab + _T("pt.y = rc.bottom - 5 - btnRect.Height();") + xCrLf;
		implCode_ += xTab + xTab + _T("cmdEdit_.SetWindowPos(&CWnd::wndTop, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);") + xCrLf;
		implCode_ += xCrLf;	
		implCode_ += xTab + xTab + _T("pt.Offset(- btnRect.Width() - 5, 0);") + xCrLf;
		implCode_ += xTab + xTab + _T("cmdInsert_.SetWindowPos(&CWnd::wndTop, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);") + xCrLf;
		implCode_ += xCrLf;	
		implCode_ += xTab + xTab + _T("pt.Offset(- btnRect.Width() - 5, 0);") + xCrLf;
		implCode_ += xTab + xTab + _T("cmdDelete_.SetWindowPos(&CWnd::wndTop, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);") + xCrLf;
		implCode_ += xCrLf;	
		implCode_ += xTab + xTab + _T("CRect lvwRect;") + xCrLf;
		implCode_ += xCrLf;	
		implCode_ += xTab + xTab + _T("lvwRect.left = 20;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.top = 57;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.right = rc.right - 20;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.bottom = rc.bottom - 42;") + xCrLf;
		implCode_ += xTab + xTab + _T("if (lvwRect.Width() > 0 && lvwRect.Height() > 0)") + xCrLf;
		implCode_ += xTab + xTab + xTab + _T("lvwItemList_.SetWindowPos(&CWnd::wndTop, lvwRect.left, lvwRect.top, lvwRect.Width(), lvwRect.Height(), SWP_SHOWWINDOW);") + xCrLf;
		implCode_ += xTab + xTab + _T("else") + xCrLf;
		implCode_ += xTab + xTab + xTab + _T("lvwItemList_.ShowWindow(SW_HIDE);") + xCrLf;
	} else {
		implCode_ += xTab + xTab + _T("CRect lvwRect;") + xCrLf;
		implCode_ += xCrLf;	
		implCode_ += xTab + xTab + _T("lvwRect.left = 20;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.top = 57;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.right = rc.right - 20;") + xCrLf;
		implCode_ += xTab + xTab + _T("lvwRect.bottom = rc.bottom - 20;") + xCrLf;
		implCode_ += xTab + xTab + _T("if (lvwRect.Width() > 0 && lvwRect.Height() > 0)") + xCrLf;
		implCode_ += xTab + xTab + xTab + _T("lvwItemList_.SetWindowPos(&CWnd::wndTop, lvwRect.left, lvwRect.top, lvwRect.Width(), lvwRect.Height(), SWP_SHOWWINDOW);") + xCrLf;
		implCode_ += xTab + xTab + _T("else") + xCrLf;
		implCode_ += xTab + xTab + xTab + _T("lvwItemList_.ShowWindow(SW_HIDE);") + xCrLf;
	}
	implCode_ += xCrLf;	
	implCode_ += xTab + xTab + _T("lvwItemList_.SetColumnWidth(0, lvwRect.Width());") + xCrLf;
	implCode_ += xTab + xTab + _T("RedrawWindow();") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// OnCmdDelete
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnCmdDelete()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("vector<cmString> selectedItems;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("GetSelectedItems(selectedItems);") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("for (int i = selectedItems.size() - 1; i >= 0; i--)") + xCrLf;
	implCode_ += xTab + xTab + _T("map_->Delete(selectedItems[i]);") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("mainDialog_->DeleteMapItemNode(parentItem_, selectedItems);") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("DisplayData();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;
	
	cmString parentPath;
	cmString n;
	cmString p;
	cmString tmp;

	n = classInfo_->GetName();
	p = GetCardinalityPostfix(classInfo_);
	parentPath = GetParentPath(NULL, parentStack_);

	tmp = _T("_") + n + p;
	
	// OnCmdEdit
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnCmdEdit()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("int index;") + xCrLf;
	implCode_ += xTab + _T("cmString tmp;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("index = GetSelectedItemIndex();") + xCrLf;
	implCode_ += xTab + _T("if (index == -1)") + xCrLf;
	implCode_ += xTab + xTab + _T("return;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("tmp = lvwItemList_.GetItemText(index, 0);") + xCrLf;
	implCode_ += xTab + _T("mainDialog_->SelectMapItemNode(parentItem_, tmp);") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// OnCmdInsert
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnCmdInsert()") + xCrLf;
	implCode_ += _T("{")+ xCrLf;
	implCode_ += xTab + GetClassName() + _T(" newItem;") + xCrLf;
	implCode_ += xTab + GetClassName() + _T("* tmp;") + xCrLf;
	implCode_ += xTab + TypeOf(sortKeyMember->GetDataType()) + _T(" newItemKey;") + xCrLf;
	implCode_ += xTab + _T("bool itemFound;") + xCrLf;
	implCode_ += xTab + _T("DWORD ret;") + xCrLf;
	implCode_ += xTab + _T("CInputBox inputBox;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("inputBox.Init(_T(\"Create new item\"), _T(\"Please enter \'") + sortKeyMember->GetCaption() + _T("\'\"), _T(\"\"));") + xCrLf;
	implCode_ += xTab + _T("ret = inputBox.DoModal();") + xCrLf;
	implCode_ += xTab + _T("if (ret != IDOK)") + xCrLf;
	implCode_ += xTab + xTab + _T("return;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("newItemKey = inputBox.GetValueString();") + xCrLf;
	implCode_ += xTab + _T("itemFound = map_->Find(newItemKey, &tmp);") + xCrLf;
	implCode_ += xTab + _T("if (itemFound) {") + xCrLf;
	implCode_ += xTab + xTab + _T("MessageBox(_T(\"Item already exists!\"), _T(\"Create new item\"));") + xCrLf;
	implCode_ += xTab + xTab + _T("return;") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("newItem.Set") + sortKeyMember->GetName() + _T("(newItemKey);") + xCrLf;
	implCode_ += xTab + _T("map_->Insert(newItem);") + xCrLf;
	
	implCode_ += xTab + _T("mainDialog_->InsertMapItem") + parentPath + tmp + _T("(newItem, parentItem_, newItemKey);") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("DisplayData();") + xCrLf;
	implCode_ += _T("}") + xCrLf;
	implCode_ += xCrLf;

	// OnDblclkItemlist
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::OnDblclkItemlist(NMHDR* pNMHDR, LRESULT* pResult)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("OnCmdEdit();") + xCrLf;
	implCode_ += xTab + _T("*pResult = 0;") + xCrLf;
	implCode_ += _T("}") + xCrLf;

	// GetSelectedItemIndex
	//
	implCode_ += _T("int ") + GetMapDialogName() + _T("::GetSelectedItemIndex()") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("return lvwItemList_.GetNextItem(-1, LVNI_SELECTED);") + xCrLf;
	implCode_ += _T("}") + xCrLf;

	// GetSelectedItems
	//
	implCode_ += _T("void ") + GetMapDialogName() + _T("::GetSelectedItems(vector<cmString>& indexList)") + xCrLf;
	implCode_ += _T("{") + xCrLf;
	implCode_ += xTab + _T("int index = -1;") + xCrLf;
	implCode_ += xTab + _T("cmString tmp;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + _T("indexList.clear();") + xCrLf;
	implCode_ += xTab + _T("while(true) {") + xCrLf;
	implCode_ += xTab + xTab + _T("index = lvwItemList_.GetNextItem(index, LVNI_SELECTED);") + xCrLf;
	implCode_ += xTab + xTab + _T("if (index == -1)") + xCrLf;
	implCode_ += xTab + xTab + xTab + _T("break;") + xCrLf;
	implCode_ += xCrLf;
	implCode_ += xTab + xTab + _T("tmp = lvwItemList_.GetItemText(index, 0);") + xCrLf;
	implCode_ += xTab + xTab + _T("indexList.push_back(tmp);") + xCrLf;
	implCode_ += xTab + _T("}") + xCrLf;
	implCode_ += _T("}") + xCrLf;
}

void CCppMapDialogGenerator::Head_generateDefineSection()
{

}
