// TreeDialog.cpp : implementation file
//

#include "stdafx.h"
#include "DiagramEng.h"
#include "TreeDialog.h"

// DiagramEng (start)
#include "DiagramEngDoc.h"		// rqd. since EBlockType e_block_type, used in OnDblclkTreeDlgTree().
// DiagramEng (end)

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

/////////////////////////////////////////////////////////////////////////////
// CTreeDialog dialog


//CTreeDialog::CTreeDialog(CWnd* pParent /*=NULL*/)
//	: CDialog(CTreeDialog::IDD, pParent)
CTreeDialog::CTreeDialog()							// -- STEP 2: CONVERSION of CDialog to CDialogBar
{
	//{{AFX_DATA_INIT(CTreeDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CTreeDialog::DoDataExchange(CDataExchange* pDX)
{
	//CDialog::DoDataExchange(pDX);
	CDialogBar::DoDataExchange(pDX);				// -- STEP 2: CONVERSION of CDialog to CDialogBar
	//{{AFX_DATA_MAP(CTreeDialog)
	DDX_Control(pDX, ID_TREE_DLG_TREE, m_TreeCtrl);
	//}}AFX_DATA_MAP
}


//BEGIN_MESSAGE_MAP(CTreeDialog, CDialog)
BEGIN_MESSAGE_MAP(CTreeDialog, CDialogBar)			// -- STEP 1: CONVERSION of CDialog to CDialogBar
	//{{AFX_MSG_MAP(CTreeDialog)
	ON_NOTIFY(NM_DBLCLK, ID_TREE_DLG_TREE, OnDblclkTreeDlgTree)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_INITDIALOG, OnInitDialog)			// -- STEP 4: CONVERSION of CDialog to CDialogBar
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTreeDialog message handlers

// -- STEP 3: CONVERSION of CDialog to CDialogBar
/*BOOL CTreeDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here

	// DiagramEng (start)
	
	// Specifically initialize the Tree control
	InitTreeControl();

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

// -- STEP 3: CONVERSION of CDialog to CDialogBar
LONG CTreeDialog::OnInitDialog(UINT wParam, LONG lParam)
{
	//CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
		
	// -- STEP 5: CONVERSION of CDialog to CDialogBar
	BOOL bRet = HandleInitDialog(wParam, lParam);			
	if(!UpdateData(FALSE))
	{
		TRACE0("Warning: UpdateData failed during dialog init.\n");
	}	

	// DiagramEng (start)

	// Specifically initialize the Tree control
	InitTreeControl();

	// DiagramEng (end)

	return bRet;											// -- STEP 5: CONVERSION of CDialog to CDialogBar

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


void CTreeDialog::InitTreeControl()
{
	// DiagramEng (start)
	int icon_flag = 1;		// flag indicating whether tree has image icons associated with it (0) no, (1) yes.
	int i_selected;			// index of the selected image in the image list
	int i_unselected;		// index of the unselected image in the image list
	int n_images = 4;		// no. of images contained side-by-side in the bitmap resource.
	int	width = 16;			// width (and height) of the square sub-image in the bitmap resource
	HTREEITEM hInsertAfter = TVI_LAST;	// handle of item after which new item should be inserted.

	//AfxMessageBox("\n CTreeDialog::InitTreeControl()\n", MB_OK, 0);
	
	// Tree label vars - Blocks level
	HTREEITEM hBlocks;
	HTREEITEM hContinuousBlocks;
	HTREEITEM hMathOperationsBlocks;
	HTREEITEM hSinkBlocks;
	HTREEITEM hSourceBlocks;
	HTREEITEM hSubsystemBlocks;

	// Tree label vars - ContinuousBlocks level
	HTREEITEM hDerivativeBlock;
	HTREEITEM hIntegratorBlock;
	HTREEITEM hTransferFnBlock;

	// Tree label vars - MathOperationsBlocks level
	HTREEITEM hDivideBlock;
	HTREEITEM hGainBlock;
	HTREEITEM hSumBlock;

	// Tree label vars - SinkBlocks level
	HTREEITEM hOutputBlock;
	//HTREEITEM hSubsystemOutBlock;		// defined under SubsystemBlocks
	
	// Tree label vars - SourceBlocks level
	HTREEITEM hConstantBlock;
	HTREEITEM hLinearFnBlock;
	HTREEITEM hSignalGeneratorBlock;
	//HTREEITEM hSubsystemInBlock;		// defined under SubsystemBlocks

	// Tree label vars - SubsystemBlocks level
	HTREEITEM hSubsystemBlock;
	HTREEITEM hSubsystemInBlock;
	HTREEITEM hSubsystemOutBlock;		

	// Display Tree with/without icons.
	if(icon_flag == 0)
	{
		// Specification of vars - Blocks level
		hBlocks = m_TreeCtrl.InsertItem("DiagramEng Blocks", TVI_ROOT);
		hContinuousBlocks = m_TreeCtrl.InsertItem("ContinuousBlocks", hBlocks);
		hMathOperationsBlocks = m_TreeCtrl.InsertItem("MathOperationsBlocks", hBlocks);
		hSinkBlocks = m_TreeCtrl.InsertItem("SinkBlocks", hBlocks);
		hSourceBlocks = m_TreeCtrl.InsertItem("SourceBlocks", hBlocks);
		hSubsystemBlocks = m_TreeCtrl.InsertItem("SubsystemBlocks", hBlocks);

		// Specification of vars - ContinuousBlocks level
		//hContinuousBlocks = m_TreeCtrl.InsertItem("ContinuousBlocks", TVI_ROOT);
		hDerivativeBlock = m_TreeCtrl.InsertItem("DerivativeBlock", hContinuousBlocks);
		hIntegratorBlock = m_TreeCtrl.InsertItem("IntegratorBlock", hContinuousBlocks);
		hTransferFnBlock = m_TreeCtrl.InsertItem("TransferFnBlock", hContinuousBlocks);

		// Specification of vars - MathOperationsBlocks level
		//hMathOperationsBlocks = m_TreeCtrl.InsertItem("MathOperationsBlocks", TVI_ROOT);
		hDivideBlock = m_TreeCtrl.InsertItem("DivideBlock", hMathOperationsBlocks);
		hGainBlock = m_TreeCtrl.InsertItem("GainBlock", hMathOperationsBlocks);
		hSumBlock = m_TreeCtrl.InsertItem("SumBlock", hMathOperationsBlocks);

		// Specification of vars - SinkBlocks level
		//hSinkBlocks = m_TreeCtrl.InsertItem("SinkBlocks", TVI_ROOT);
		hOutputBlock = m_TreeCtrl.InsertItem("OutputBlock", hSinkBlocks);
		hSubsystemOutBlock = m_TreeCtrl.InsertItem("SubsystemOutBlock", hSinkBlocks);

		// Specification of vars - SourceBlocks level
		//hSourceBlocks = m_TreeCtrl.InsertItem("SourceBlocks", TVI_ROOT);
		hConstantBlock = m_TreeCtrl.InsertItem("ConstantBlock", hSourceBlocks);
		hLinearFnBlock = m_TreeCtrl.InsertItem("LinearFnBlock", hSourceBlocks);
		hSignalGeneratorBlock = m_TreeCtrl.InsertItem("SignalGeneratorBlock", hSourceBlocks);
		hSubsystemInBlock = m_TreeCtrl.InsertItem("SubsystemInBlock", hSourceBlocks);

		// Specification of vars - SubsystemBlocks level
		//hSubsystemBlocks = m_TreeCtrl.InsertItem("SubsystemBlocks", TVI_ROOT);
		hSubsystemBlock = m_TreeCtrl.InsertItem("SubsystemBlock", hSubsystemBlocks);
		hSubsystemInBlock = m_TreeCtrl.InsertItem("SubsystemInBlock", hSubsystemBlocks);
		hSubsystemOutBlock = m_TreeCtrl.InsertItem("SubsystemOutBlock", hSubsystemBlocks);
	}
	else
	{
		// -- Create the Image List
		m_TreeImageList.Create(IDB_BITMAP_TREE, width, n_images, RGB(255,255,255));

		// -- Set the Image List
		// TVSIL_NORMAL = sets the normal image list for unselected (image 1) and selected (image 2) node items.
		// TVSIL_STATE = sets the stage image list for Tree View items in a partic. user-defined state

		m_TreeCtrl.SetImageList(&m_TreeImageList, TVSIL_NORMAL);
		//m_TreeCtrl.SetImageList(&m_TreeImageList, TVSIL_STATE);

		// -- Specification of vars - Blocks level
		// Prototype: HTREEITEM InsertItem(UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam, HTREEITEM hParent, HTREEITEM hInsertAfter );
		
		// Choose which image to display for the parent node, based on whether the parent's child nodes are expanded
		i_unselected = 0;
		i_selected = 1;
		hBlocks = m_TreeCtrl.InsertItem("DiagramEng Blocks", i_unselected, i_selected, TVI_ROOT);
		//hBlocks = m_TreeCtrl.InsertItem(TVIF_STATE | TVIF_TEXT | TVIF_IMAGE, "DiagramEng Blocks", i_unselected, i_selected, TVIS_EXPANDED, TVIS_STATEIMAGEMASK, 0, TVI_ROOT, hInsertAfter);
		//hBlocks = m_TreeCtrl.InsertItem(TVIF_TEXT, "DiagramEng Blocks", i_unselected, i_selected, TVIS_EXPANDED, TVIS_STATEIMAGEMASK, 0, TVI_ROOT, hInsertAfter);
		hContinuousBlocks = m_TreeCtrl.InsertItem("ContinuousBlocks", i_unselected, i_selected, hBlocks, hInsertAfter);
		hMathOperationsBlocks = m_TreeCtrl.InsertItem("MathOperationsBlocks", i_unselected, i_selected, hBlocks, hInsertAfter);
		hSinkBlocks = m_TreeCtrl.InsertItem("SinkBlocks", i_unselected, i_selected, hBlocks, hInsertAfter);
		hSourceBlocks = m_TreeCtrl.InsertItem("SourceBlocks", i_unselected, i_selected, hBlocks, hInsertAfter);
		hSubsystemBlocks = m_TreeCtrl.InsertItem("SubsystemBlocks", i_unselected, i_selected, hBlocks, hInsertAfter);

		// Specification of vars - ContinuousBlocks level
		i_unselected = 2;
		i_selected = 3;
		//hContinuousBlocks = m_TreeCtrl.InsertItem("ContinuousBlocks", TVI_ROOT);
		hDerivativeBlock = m_TreeCtrl.InsertItem("DerivativeBlock", i_unselected, i_selected, hContinuousBlocks, hInsertAfter);
		hIntegratorBlock = m_TreeCtrl.InsertItem("IntegratorBlock", i_unselected, i_selected, hContinuousBlocks, hInsertAfter);
		hTransferFnBlock = m_TreeCtrl.InsertItem("TransferFnBlock", i_unselected, i_selected, hContinuousBlocks, hInsertAfter);

		// Specification of vars - MathOperationsBlocks level
		//hMathOperationsBlocks = m_TreeCtrl.InsertItem("MathOperationsBlocks", TVI_ROOT);
		hDivideBlock = m_TreeCtrl.InsertItem("DivideBlock", i_unselected, i_selected, hMathOperationsBlocks, hInsertAfter);
		hGainBlock = m_TreeCtrl.InsertItem("GainBlock", i_unselected, i_selected, hMathOperationsBlocks, hInsertAfter);
		hSumBlock = m_TreeCtrl.InsertItem("SumBlock", i_unselected, i_selected, hMathOperationsBlocks, hInsertAfter);

		// Specification of vars - SinkBlocks level
		//hSinkBlocks = m_TreeCtrl.InsertItem("SinkBlocks", TVI_ROOT);
		hOutputBlock = m_TreeCtrl.InsertItem("OutputBlock", i_unselected, i_selected, hSinkBlocks, hInsertAfter);
		hSubsystemOutBlock = m_TreeCtrl.InsertItem("SubsystemOutBlock", i_unselected, i_selected, hSinkBlocks, hInsertAfter);

		// Specification of vars - SourceBlocks level
		//hSourceBlocks = m_TreeCtrl.InsertItem("SourceBlocks", TVI_ROOT);
		hConstantBlock = m_TreeCtrl.InsertItem("ConstantBlock", i_unselected, i_selected, hSourceBlocks, hInsertAfter);
		hLinearFnBlock = m_TreeCtrl.InsertItem("LinearFnBlock", i_unselected, i_selected, hSourceBlocks, hInsertAfter);
		hSignalGeneratorBlock = m_TreeCtrl.InsertItem("SignalGeneratorBlock", i_unselected, i_selected, hSourceBlocks, hInsertAfter);
		hSubsystemInBlock = m_TreeCtrl.InsertItem("SubsystemInBlock", i_unselected, i_selected, hSourceBlocks);

		// Specification of vars - SubsystemBlocks level
		//hSubsystemBlocks = m_TreeCtrl.InsertItem("SubsystemBlocks", TVI_ROOT);
		hSubsystemBlock = m_TreeCtrl.InsertItem("SubsystemBlock", i_unselected, i_selected, hSubsystemBlocks, hInsertAfter);
		hSubsystemInBlock = m_TreeCtrl.InsertItem("SubsystemInBlock", i_unselected, i_selected, hSubsystemBlocks, hInsertAfter);
		hSubsystemOutBlock = m_TreeCtrl.InsertItem("SubsystemOutBlock", i_unselected, i_selected, hSubsystemBlocks, hInsertAfter);
	}

	// DiagramEng (end)
}

void CTreeDialog::OnDblclkTreeDlgTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	
	// DiagramEng (start)
	CDiagramEngDoc *pDoc = NULL;	// declare pDoc to be a ptr to CDiagramEngDoc.
	CString item_text;				// text label of tree ctrl item
	CString sMsg;					// main msg string
	CString sMsg1;					// substring
	EBlockType e_block_type;		// enum block type defined in DiagramEngDoc.cpp	
	HTREEITEM handle_1;				// tree ctrl. item handle
	HTREEITEM handle_2;				// tree ctrl. item handle
	UINT nType = MB_OK;				// style of msg. box
	UINT nIDhelp = 0;				// help context ID for the msg.
	
	// Print a msg.
	//sMsg.Format("\n CTreeDialog::OnDblclkTreeDlgTree(), code = %d, idFrom = %d\n", pNMHDR->code, pNMHDR->idFrom);
	//AfxMessageBox(sMsg, nType, nIDhelp);

	// Get the selected tree ctrl item.
	handle_1 = m_TreeCtrl.GetSelectedItem();

	// Get the children nodes of the selected item.
	handle_2 = m_TreeCtrl.GetChildItem(handle_1);

	// If the node has no children, then it's a leaf node.
	if(handle_2 == NULL)
	{
		// -- Get the item's text string
		item_text = m_TreeCtrl.GetItemText(handle_1);

		// Print the item's text string.
		//sMsg1.Format("\n CTreeDialog::OnDblclkTreeDlgTree(), name = %s\n", item_text);
		//sMsg += sMsg1;
		//AfxMessageBox(sMsg, nType, nIDhelp);

		// -- GET A PTR TO THE DOC, i.e. pDoc. 
		// This can be done calleing CDiagramEngView::GetDocument().
		// However, from within the Dlg class, in the absence of a View obj., a global fn is rqd that returns pDoc.
		// This global fn header is declared in DiagramEngDoc.h and defined in DiagramEngDoc.cpp
		
		pDoc = GetDocumentGlobalFn();

		// -- SET THE BLOCK ENUMERATED TYPE based on the "item_text" CString value.
		
		// -- CONTINUOUS BLOCKS
		if(item_text == "DerivativeBlock")
		{
			e_block_type = eDerivativeBlock;	
		}
		else if(item_text == "IntegratorBlock")
		{
			e_block_type = eIntegratorBlock;
		}
		else if(item_text == "TransferFnBlock")
		{
			e_block_type = eTransferFnBlock;
		}
		
		// -- MATH OPS BLOCKS
		else if(item_text == "DivideBlock")
		{
			e_block_type = eDivideBlock;
		}
		else if(item_text == "GainBlock")
		{
			e_block_type = eGainBlock;
		}
		else if(item_text == "SumBlock")
		{
			e_block_type = eSumBlock;
		}

		// -- SINK BLOCKS
		else if(item_text == "OutputBlock")
		{
			e_block_type = eOutputBlock;
		}
	
		// -- SOURCE BLOCKS
		else if(item_text == "ConstantBlock")
		{
			e_block_type = eConstBlock;
		}
		else if(item_text == "LinearFnBlock")
		{
			e_block_type = eLinearFnBlock;
		}
		else if(item_text == "SignalGeneratorBlock")
		{
			e_block_type = eSignalGenBlock;
		}

		// -- SUBSYSTEM BLOCKS
		else if(item_text == "SubsystemBlock")
		{
			e_block_type = eSubsysBlock;
		}
		else if(item_text == "SubsystemInBlock")
		{
			e_block_type = eSubsysInBlock;
		}
		else if(item_text == "SubsystemOutBlock")
		{
			e_block_type = eSubsysOutBlock;
		}// end if block type

		// -- CONSTRUCT BLOCK based on the enumerated type value.
		pDoc->ConstructBlock(e_block_type);
		
		// Print the final concatenated msg. using a msg. box.
		//AfxMessageBox(sMsg, nType, nIDhelp);
	}// end if leaf node

	// DiagramEng (end)

	*pResult = 0;
}
