
#ifndef _COL_VALUE_DESIGNATION_H_
#define _COL_VALUE_DESIGNATION_H_

#define CVD_CATE_ROW_BUILT_IN 	0
#define CVD_CATE_ROW_ORIGIN_C 	1
#define CVD_CATE_ROW_FO 		2
#define CVD_CATE_ROW_COLUMN		(m_CateList.GetRows()-1)

enum { 	CVD_CONTENT_FUNCTION_NAME, 
		CVD_CONTENT_FUNCTION_ARGS, 
		CVD_CONTENT_FUNCTION_RETURNS,
		CVD_CONTENT_FUNCTION_DESC,
		CVD_CONTENT_FUNCTION_LOCATION,
		CVD_CONTENT_TOTAL_COLS
};

#define STR_GETTREE_ATTRIB 				"Category_Insered"

#define CVD_CONTENT_ROW_HEADER	0
#define CVD_CONTENT_EMPTY 		0
#define CVD_CATE_LIST 			0,0
#define CVD_CONTENT_LIST 		0,1

class ColCateList : public GridTreeControl
{
public :
	void Init(int nID, TreeNode trList, WndContainer& dlg)
	{
		GridTreeControl::Init(nID, dlg);
		m_flx.SelectionMode = flexSelectionByRow;

		m_trList = trList;
		m_nID = nID;

		//AddTreeNodes(m_trList, ATRN_STOP_LEVEL | 1);
		//AddTreeNodes(m_trList, 1);	///DG 4/18/05 REWRITE_TREE_GET_NODE
		AddTreeNodes(m_trList, ATRN_STOP_LEVEL | 1);
		
		//------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
		//SetSelectRowCollapsed(CVD_CATE_ROW_FO, flexOutlineCollapsed);
		SetCollapsed(CVD_CATE_ROW_FO, true);
		//-------
	}
	
private :
	int						m_nID;
	TreeNode				m_trList;
};

class ColDetail : public GridListControl
{
public :
	void Init(int nID, TreeNode trCate, WndContainer &dlg)
	{
		GridListControl::Init(nID, dlg);
		SetupRowsCols(1, 0, 1, CVD_CONTENT_TOTAL_COLS);
		m_trCate = trCate;
		m_nID = nID;
		m_nRows=m_flx.Rows;
		
		m_flx.SelectionMode = flexSelectionByRow;
		m_flx.ExplorerBar = flexExSortShow;
		m_flx.WordWrap = true;
		
		vector<string> vs = {"Name", "Arguments", "Returns", "Description", "Location"};
		SetCell(CVD_CONTENT_ROW_HEADER, CVD_CONTENT_FUNCTION_NAME, 		vs[CVD_CONTENT_FUNCTION_NAME]);
		SetCell(CVD_CONTENT_ROW_HEADER, CVD_CONTENT_FUNCTION_ARGS, 		vs[CVD_CONTENT_FUNCTION_ARGS]);
		SetCell(CVD_CONTENT_ROW_HEADER, CVD_CONTENT_FUNCTION_RETURNS, 	vs[CVD_CONTENT_FUNCTION_RETURNS]);
		SetCell(CVD_CONTENT_ROW_HEADER, CVD_CONTENT_FUNCTION_DESC, 		vs[CVD_CONTENT_FUNCTION_DESC]);
		SetCell(CVD_CONTENT_ROW_HEADER, CVD_CONTENT_FUNCTION_LOCATION, 	vs[CVD_CONTENT_FUNCTION_LOCATION]);
	}
	
	void RemoveRow(vector<uint> vuRows)
	{
		int nSize = vuRows.GetSize();
		for(int ii=0; ii<nSize; ii++)
		{
			m_flx.RemoveItem(vuRows[ii]);
			m_nRows--;
		}
	}

	int GetBuildInFunction()
	{
		vector<string> vsNames, vsDesc, vsIns;
		vector<uint> vunArgs;
		int nCount = GetLTMathFunctionList(&vsNames, &vsDesc, &vunArgs, &vsIns);
		vector<string> vsReturns(nCount);
		if(nCount > 0)
		{
			displayFunction(vsNames, vunArgs, vsReturns, vsDesc, vsIns);
		}
		return nCount;
	}
	
	int GetOriginCFunction()
	{
		EmptyContent();	//temp, origin c function is not used.
		return 0;
	}
	
	int AddColumns(const vector<string> &vsColNames, const vector<string>& vsLongNames)
	{
		int nSize=vsColNames.GetSize();
		adjustRowNum(nSize);
		vector<uint> vnEmpty(nSize);
		vector<string> vsEmpty(nSize);
		displayFunction(vsColNames, vnEmpty, vsEmpty, vsLongNames, vsColNames);
		return nSize;
	}
	
	int GetFOFunction(TreeNode trCategory)
	{
		vector<string> vsNames, vsReturns, vsDesc, vsLocation;
		vector<uint> vunArgs;
		string strName;
		int nArgs;
		foreach(TreeNode trFunction in trCategory.Children)
		{
			if(trFunction.GetAttribute(STR_LABEL_ATTRIB, strName))
			{
				vsNames.Add(strName);
				nArgs=trFunction.GeneralInformation.NumberOfParameters.nVal;
				vunArgs.Add(nArgs);
				vsReturns.Add("");
				vsDesc.Add(trFunction.GeneralInformation.BriefDescription.strVal);
				string strTemp(',', nArgs-1);
				vsLocation.Add(okutil_separate_composite_name(strName)+"("+strTemp+")");
			}
		}
		displayFunction(vsNames, vunArgs, vsReturns, vsDesc, vsLocation);
		return vsNames.GetSize();
	}
	
	void EmptyContent()
	{
		adjustRowNum(CVD_CONTENT_EMPTY);
	}
private :
	void displayFunction(const vector<string> &vsNames, const vector<uint> &vunArgs, const vector<string> &vsReturns, const vector<string> &vsDesc, const vector<string> &vsLocation)
	{
		int nCount = vsNames.GetSize(), nFixedRows=m_flx.FixedRows;
		adjustRowNum(nCount);
		for(int nRow=0; nRow<nCount; nRow++)
		{
			SetCell(nRow+nFixedRows, CVD_CONTENT_FUNCTION_NAME, 	vsNames[nRow]);
			SetCell(nRow+nFixedRows, CVD_CONTENT_FUNCTION_ARGS, 	(string)vunArgs[nRow]);
			SetCell(nRow+nFixedRows, CVD_CONTENT_FUNCTION_RETURNS, 	vsReturns[nRow]);
			SetCell(nRow+nFixedRows, CVD_CONTENT_FUNCTION_DESC, 	vsDesc[nRow]);
			SetCell(nRow+nFixedRows, CVD_CONTENT_FUNCTION_LOCATION,	vsLocation[nRow]);
		}
	}
	
	void adjustRowNum(int nNeededRows)
	{
		int nFixedRows = m_flx.FixedRows;
		if(nNeededRows != m_nRows-nFixedRows)
		{
			if(nNeededRows>m_nRows-nFixedRows)
			{
				for(; nNeededRows != m_nRows-nFixedRows; m_nRows++)
					m_flx.AddItem("", m_nRows);
			}
			else
			{
				for(; nNeededRows != m_nRows-nFixedRows; m_nRows--)
					m_flx.RemoveItem(m_nRows-1);
			}
		}
	}
	
private :
	TreeNode	m_trCate;
	int 		m_nID;
	int			m_nRows;
};

class ColValueDesignation : public SplitterControl
{
public :
	ColValueDesignation()
	{
		m_bReady = false;
		SetGridSize(1,2);
		m_IDLeft = GetDlgCtrlID(CVD_CATE_LIST);
		m_IDRight = GetDlgCtrlID(CVD_CONTENT_LIST);

		InitMsgMap();
	}
	
	void Init(int nCntrlID, Worksheet &Wks, WndContainer& wndParent, bool bVisible = true)
	{
		SplitterControl::Init(nCntrlID, wndParent, 1);
		Visible = bVisible;
		
		GetWorksheet(Wks);
	}
	///Jasmine 10/28/05 v8.0324 SPLITTER_INIT_SIZE_ON_READY
	void OnReady()
	{
		SplitterControl::OnReady();
	}
	///End SPLITTER_INIT_SIZE_ON_READY
	void GetWorksheet(Worksheet &Wks)
	{
		m_Wks=Wks;
		if(CVD_CATE_ROW_COLUMN == m_CateList.GetSelectedRow())
			GetWksColumn();
	}
	
	string AddSelection(int nRow)
	{
		return m_ContentList.GetCell(nRow, CVD_CONTENT_FUNCTION_LOCATION);
	}
	
protected:
EVENTS_BEGIN
	ON_INIT(OnInitSplitter)
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnCtrlResize)
	
	ON_GRID_ROW_COL_CHANGE(m_IDLeft, OnListRowChange)
	ON_GRID_DBLCLICK(m_IDRight, OnDbClick)
	ON_GRID_MOUSE_MOVE(m_IDRight, OnMouseMove)
EVENTS_END

	BOOL OnInitSplitter()
	{
		m_bReady = false;
		getTree(m_trDesignation);
		
		GUID clsid;
		CreateActiveXPane(clsid, CVD_CATE_LIST);
		m_CateList.Init(m_IDLeft, m_trDesignation, *this);
		
		CreateActiveXPane(clsid, CVD_CONTENT_LIST);
		m_ContentList.Init(m_IDRight, m_trDesignation, *this);
		
		SetReady();
		m_bReady = true;
		return TRUE;
	}
	
	BOOL OnCtrlResize(int nType, int cx, int cy)
	{
		SplitterControl::OnResize(nType, cx, cy);
		return TRUE;
	}
	
	void OnListRowChange(Control ctrl)
	{
		if(!m_bReady)
			return;
		
		PROFILE_HRGLASS
		
		int nRow = m_CateList.GetSelectedRow();
		switch(nRow)
		{
		case CVD_CATE_ROW_BUILT_IN:
			m_ContentList.GetBuildInFunction();
			break;
		case CVD_CATE_ROW_ORIGIN_C:
			m_ContentList.GetOriginCFunction();
			break;
		case CVD_CATE_ROW_FO:	//select FO category
			m_ContentList.EmptyContent();
			break;
		default :
			if(nRow == CVD_CATE_ROW_COLUMN)
				GetWksColumn();
			else
				GetFOFunction(nRow);
			break;
		}
	}
	
	void OnDbClick(Control ctrl)
	{
		int nMouseRow, nMouseCol, nSelRow=m_ContentList.GetSelectedRow();
		m_ContentList.GetMouseCell(nMouseRow, nMouseCol);
		if(nMouseRow==nSelRow && 0<=nMouseRow)
		{
			Window Wnd = GetParent();
			if(Wnd)
				Wnd.PostMessage(WM_USER_ADD_VALUE_BY_SELECTION, m_ContentList.GetSelectedRow(), m_CateList.GetRows()-1 == m_CateList.GetSelectedRow());
		}
	}
	
	void OnMouseMove(Control flxControl, short nButton, short nShift, float X, float Y)
	{
		int nMouseRow, nMouseCol;
		m_ContentList.GetMouseCell(nMouseRow, nMouseCol);
		//string strTips=m_ContentList.GetCell(nMouseRow, CVD_CONTENT_FUNCTION_DESC);
		string strTips="hello";
		show_tooltip_text(strTips);
	}
	
	void GetWksColumn()
	{
		vector<string> vsColNames, vsLongNames;
		foreach(Column Col in m_Wks.Columns)
		{
			vsColNames.Add("Col("+Col.GetName()+")");
			vsLongNames.Add(Col.GetLongName());
		}
		m_ContentList.AddColumns(vsColNames, vsLongNames);
	}
	
	void GetFOFunction(int nRow)
	{
		//TreeNode trCategory = tree_get_node(m_trDesignation, nRow, 1);	///DG 4/18/05 REWRITE_TREE_GET_NODE
		TreeNode trCategory = tree_get_node(m_trDesignation, nRow, ATRN_STOP_LEVEL | 1);
		if(trCategory)
		{
			string strTemp;
			if(!trCategory.GetAttribute(STR_GETTREE_ATTRIB, strTemp))
			{
				vector<int> vnInValidRows;
				m_NFO.LoadCategory(trCategory, vnInValidRows);
				m_ContentList.RemoveRow(vnInValidRows);
				trCategory.SetAttribute(STR_GETTREE_ATTRIB, "Done");
			}
			m_ContentList.GetFOFunction(trCategory);
		}
	}
	
private :
	void getTree(TreeNode &trDesignation)
	{
		trDesignation.Reset();
		TreeNode trTemp;
		
		trTemp = trDesignation.AddNode("List1");
		trTemp.SetAttribute(STR_LABEL_ATTRIB, "Built-in Functions");
		
		trTemp = trDesignation.AddNode("List2");
		trTemp.SetAttribute(STR_LABEL_ATTRIB, "Origin C Functions");
		
		Tree trCate;
		m_NFO.GetCategoryList(trCate);
		///------Frank 11/11/05 REMOVE_XF_FROM_FO_TREE
		///Temp, current just remove the top level node.
		//trDesignation.AddNode(trCate.GetNode(STR_FIT_FUNCTION_NODE));
		trDesignation.AddNode(trCate);
		///------End REMOVE_XF_FROM_FO_TREE
		trTemp = trTemp.NextNode;
		trTemp.SetAttribute(STR_LABEL_ATTRIB, "Function Organizer");
		
		trTemp = trDesignation.AddNode("List4");
		trTemp.SetAttribute(STR_LABEL_ATTRIB, "Columns");
	}
	
	void show_tooltip_text(string& str)
	{
		m_ContentList.SetToolTipsText(str);
	}
	
private :
	NumFunctionOrganizer	m_NFO;
	ColCateList				m_CateList;
	ColDetail				m_ContentList;
	Tree					m_trDesignation;
	Worksheet				m_Wks;
	
	bool					m_bReady;
	int 					m_IDLeft;
	int						m_IDRight;
};
#endif _COL_VALUE_DESIGNATION_H_