 /*-----------------------------------------------------------------------------*
 * File Name: CallStack.h			 											*
 * Creation: CPY 2/20/05														*
 * Purpose: OriginC Source C file												*
 * Copyright (c) Originlab Corp.	2005, 2006, 2007, 2008, 2009, 2010			*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	RVD 4/15/2005 QA70-7597 v8.0223 MARKER_GROBJ								*
 *	YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE							*
 *	YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS							*
 *	RVD 11/22/2006 QA70-9148 v8.0515 IMPLEMENT_RECTINFO							*
 *------------------------------------------------------------------------------*/

#ifndef _CALLSTACK_H
#define _CALLSTACK_H

/** >
		The CallStack is base class for CallStackEx class which provides methods to make function call when
		function prototype is not known during development time.
		Example:
		void test_call_stack(LPCSTR lpcszFunctionName, LPCSTR lpcszFunctionPath, BOOL bPushInt)
		{
			CallStackEx oStack;
			if( bPushInt )
			{
				int nVal = 10;
				oStack.Push(nVal);
			}
			else
			{
				double dVal = 10.0;
				oStack.Push(dVal);
			}
			Function fn = Project.FindFunction(lpcszFunctionName, lpcszFunctionPath, false, true, true);
			DoFunctionCall(&fn, &oStack);
		}
 */
 
class	CallStack
{
public:
	/**
	Remarks:
		Constructor of CallStack class
	*/
	CallStack();
	
	/**
	Remarks:
		Destructor of CallStack class
	*/
	~CallStack();
	
public:
	/**
	Remarks:
		Push vector on stack
	*/
	int		Push(vector& var);
	
	/**
	Remarks:
		Push matrix on stack
	*/
	int		Push(matrix& var);
	
	/**
	Remarks:
		Push int on stack
	*/
	int		Push(int& var);
	
	/**
	Remarks:
		Push string on stack
	*/
	int		Push(string& var);
	
	/**
	Remarks:
		Push double on stack
	*/
	int		Push(double& var);
	
	/**
	Remarks:
		Push DataRange on stack
	*/
	int		Push(DataRange& var);
	
#ifndef SELF_CREATING_RANGE_VC_BASED
	/**
	Remarks:
		Push XYRange on stack
	*/
	int		Push(XYRange& var);
	
	/**
	Remarks:
		Push XYZRange on stack
	*/
	int		Push(XYZRange& var);
#endif // SELF_CREATING_RANGE_VC_BASED	

	/**
	Remarks:
		Push MatrixObject on stack
	*/
	int		Push(OriginObject& var);
	
	/**
	Remarks:
		Push ButtonInfo on stack
	*/
	int		Push(ButtonInfo& var);
	
	/**
	Remarks:
		Push LineInfo on stack
	*/
	int		Push(LineInfo& var);
	
	/**
	Remarks:
		Push TextInfo on stack
	*/
	int		Push(TextInfo& var);
	
	/**
	Remarks:
		Push EventInfo on stack
	*/
	int		Push(EventInfo& var);

	/// RVD 4/15/2005 QA70-7597 v8.0223 MARKER_GROBJ
	int		Push(MarkerInfo& var);
	/// end MARKER_GROBJ
	
	/// RVD 11/22/2006 QA70-9148 v8.0515 IMPLEMENT_RECTINFO
	int		Push(RectInfo& var);
	/// end IMPLEMENT_RECTINFO

	/// YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE
	int		Push(TreeNode& var);
	/// end XFUNCTION_AND_TREE_VARIABLE
	/// YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS
	int		Push(FileLink& var);
	/// end FILE_IMPORTING_XFUCNTIONS
	/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
	int		Push(ReportTree& var);
	int		Push(ReportData& var);
	/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES
};


#define MAX_FUNC_ARG_CALLSTACK	20
class CallStackEx : public CallStack
{
public:
	CallStackEx(bool bOwnMemory = true) 
	{
		if(bOwnMemory)
		{
			m_avArgs.SetAsOwner(TRUE);
			m_adrArgs.SetAsOwner(TRUE);
			m_aXYDrArgs.SetAsOwner(TRUE);
			m_aXYZDrArgs.SetAsOwner(TRUE);
			m_amatArgs.SetAsOwner(TRUE);
			m_aOriginObjArgs.SetAsOwner(TRUE);
			m_aButtonInfoArgs.SetAsOwner(TRUE);
			m_aLineInfoArgs.SetAsOwner(TRUE);
			m_aTextInfoArgs.SetAsOwner(TRUE);
			m_aEventInfoArgs.SetAsOwner(TRUE);
			m_arrStringArguments.SetAsOwner(TRUE);
			m_aMarkerInfoArgs.SetAsOwner(TRUE);
			/// YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE
			m_aTreeArgs.SetAsOwner(TRUE);
			/// end XFUNCTION_AND_TREE_VARIABLE
			/// YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS
			m_aFileLinkArgs.SetAsOwner(TRUE);
			/// end FILE_IMPORTING_XFUCNTIONS
			/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
			m_aReportTreeArgs.SetAsOwner(TRUE);
			m_aReportDataArgs.SetAsOwner(TRUE);
			/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES
			/// RVD 11/22/2006 QA70-9148 v8.0515 IMPLEMENT_RECTINFO
			m_aRectInfoArgs.SetAsOwner(TRUE);
			/// end IMPLEMENT_RECTINFO
		}
	}
	
	~CallStackEx()
	{
	}
	int Push(vector& var)
	{
		if( m_nVectorCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_avArgs.Add(var);
		m_nVectorCounter++;
		return CallStack::Push(var);
	}
	
	/// ML 3/6/2005
	int Push(matrix& var)
	{
		if( m_nMatrixCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_amatArgs.Add(var);
		m_nMatrixCounter++;
		return CallStack::Push(var);
	}
	
	int Push(OriginObject& var)
	{
		if( m_nOriginObjectCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aOriginObjArgs.Add(var);
		m_nOriginObjectCounter++;
		return CallStack::Push(var);
	}
	/// end ML 3/6/2005

	
	int		Push(int& var)
	{
		if( m_nIntCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_intArgs[m_nIntCounter] = var;
		return CallStack::Push(m_intArgs[m_nIntCounter++]);
	}
	
	int		Push(string& var)
	{
		if( m_nStringCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_arrStringArguments.Add(var);
		m_nStringCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(double& var)
	{
		if( m_nDoubleCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_dbArgs[m_nDoubleCounter] = var;
		return CallStack::Push(m_dbArgs[m_nDoubleCounter++]);
	}
	
	/// ML 3/21/2005 OPERATIONTREE_UPDATING_BACK_AND_FORTH
	//int		Push(DataRange& var)
	//{
	//	if( m_nDataRangeCounter >= MAX_FUNC_ARG_CALLSTACK )
	//		return -1;
	//	
	//	m_adrArgs.Add(var);
	//	m_nDataRangeCounter++;
	//	return CallStack::Push(var);
	//}
	int		PushSCDR(SelfCreatingDataRange& var)
	{
		if( m_nDataRangeCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_adrArgs.Add(var);
		m_nDataRangeCounter++;
		return CallStack::Push(var);
	}
	/// end OPERATIONTREE_UPDATING_BACK_AND_FORTH
	
	int		Push(XYRange& var)
	{
		if( m_nXYRangeCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aXYDrArgs.Add(var);
		m_nXYRangeCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(XYZRange& var)
	{
		if( m_nXYZRangeCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aXYZDrArgs.Add(var);
		m_nXYZRangeCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(ButtonInfo& var)
	{
		if( m_nButtonInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aButtonInfoArgs.Add(var);
		m_nButtonInfoCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(LineInfo& var)
	{
		if( m_nLineInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aLineInfoArgs.Add(var);
		m_nLineInfoCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(TextInfo& var)
	{
		if( m_nTextInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aTextInfoArgs.Add(var);
		m_nTextInfoCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(EventInfo& var)
	{
		if( m_nEventInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aEventInfoArgs.Add(var);
		m_nEventInfoCounter++;
		return CallStack::Push(var);
	}
	
	/// YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE
	int		Push(TreeNode& var)
	{
		if( m_nTreeCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aTreeArgs.Add(var);
		m_nTreeCounter++;
		return CallStack::Push(var);
	}
	/// end XFUNCTION_AND_TREE_VARIABLE
	
	/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
	int		Push(ReportTree& var)
	{
		if( m_nReportTreeCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aReportTreeArgs.Add(var);
		m_nReportTreeCounter++;
		return CallStack::Push(var);
	}
	
	int		Push(ReportData& var)
	{
		if( m_nReportDataCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aReportDataArgs.Add(var);
		m_nReportDataCounter++;
		return CallStack::Push(var);
	}
	/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES
	
	/// YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS
	int		Push(FileLink& var)
	{
		if( m_nFileLinkCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aFileLinkArgs.Add(var);
		m_nFileLinkCounter++;
		return CallStack::Push(var);
	}
	/// end FILE_IMPORTING_XFUCNTIONS
	//////////////////////////////////////////////////////
	// Pops start here:
	BOOL 	Pop(vector*& pVar)
	{
		m_nVectorCounter--;
		vector& vTemp = m_avArgs.GetAt(m_nVectorCounter);
		pVar = &vTemp;
		return TRUE;
	}
	/// ML 3/6/2005
	int		Pop(matrix*& pVar)
	{
		m_nMatrixCounter--;
		matrix&	mTemp = m_amatArgs.GetAt(m_nMatrixCounter);
		pVar = &mTemp;
		return TRUE;
	}
	
	int		Pop(OriginObject*& pVar)
	{
		m_nOriginObjectCounter--;
		OriginObject&	objTemp = m_aOriginObjArgs.GetAt(m_nOriginObjectCounter);
		pVar = &objTemp;
		return TRUE;
	}
	/// end ML 3/6/2005
	
	BOOL 	Pop(int*& pVar)
	{
		m_nIntCounter--;
		pVar = &m_intArgs[m_nIntCounter];
		return TRUE;
	}
	
	BOOL 	Pop(string*& pVar)
	{
		m_nStringCounter--;
		string& strTemp = m_arrStringArguments.GetAt(m_nStringCounter);
		pVar = &strTemp;
		return TRUE;
	}
	
	BOOL 	Pop(double*& pVar)
	{
		m_nDoubleCounter--;
		pVar = &m_dbArgs[m_nDoubleCounter];
		return TRUE;
	}
	
	/// YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE
	BOOL 	Pop(TreeNode*& pVar)
	{
		m_nTreeCounter--;
		TreeNode& trTemp = m_aTreeArgs.GetAt(m_nTreeCounter);
		pVar = &trTemp;
		return TRUE;
	}
	/// end XFUNCTION_AND_TREE_VARIABLE

	/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
	BOOL 	PopReportTree(ReportTree*& pVar)
	{
		m_nReportTreeCounter--;
		ReportTree& trTemp = m_aReportTreeArgs.GetAt(m_nReportTreeCounter);
		pVar = &trTemp;
		return TRUE;
	}
	
	BOOL 	PopReportData(ReportData*& pVar)
	{
		m_nReportDataCounter--;
		ReportData& dataTemp = m_aReportDataArgs.GetAt(m_nReportDataCounter);
		pVar = &dataTemp;
		return TRUE;
	}
	/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES

	/// YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS
	BOOL 	Pop(FileLink*& pVar)
	{
		m_nFileLinkCounter--;
		FileLink& flTemp = m_aFileLinkArgs.GetAt(m_nFileLinkCounter);
		pVar = &flTemp;
		return TRUE;
	}
	/// end FILE_IMPORTING_XFUCNTIONS

	/// ML 3/21/2005 OPERATIONTREE_UPDATING_BACK_AND_FORTH
	//BOOL 	Pop(DataRange*& pVar)
	//{
	//	m_nDataRangeCounter--;
	//	DataRange& drTemp = m_adrArgs.GetAt(m_nDataRangeCounter);
	//	pVar = &drTemp;
	//	return TRUE;
	//}
	
	// Must have special name because otherwise the compiler complains about too
	// many overload matches:
	BOOL 	PopSCDR(SelfCreatingDataRange*& pVar)
	{
		m_nDataRangeCounter--;
		DataRange& drTemp = m_adrArgs.GetAt(m_nDataRangeCounter);
		pVar = &drTemp;
		return TRUE;
	}
	/// end OPERATIONTREE_UPDATING_BACK_AND_FORTH

	
	/// ML 3/21/2005 OPERATIONTREE_UPDATING_BACK_AND_FORTH
	//BOOL 	Pop(XYRange*& pVar)
	BOOL 	PopXY(XYRange*& pVar)
	/// end OPERATIONTREE_UPDATING_BACK_AND_FORTH
	{
		m_nXYRangeCounter--;
		XYRange& drTemp = m_aXYDrArgs.GetAt(m_nXYRangeCounter);
		pVar = &drTemp;
		return TRUE;
	}
	
	/// ML 3/21/2005 OPERATIONTREE_UPDATING_BACK_AND_FORTH
	//BOOL 	Pop(XYZRange*& pVar)
	BOOL 	PopXYZ(XYZRange*& pVar)
	/// end OPERATIONTREE_UPDATING_BACK_AND_FORTH
	{
		m_nXYZRangeCounter--;
		XYZRange& drTemp = m_aXYZDrArgs.GetAt(m_nXYZRangeCounter);
		pVar = &drTemp;
		return TRUE;
	}
	
	BOOL 	PopButtonInfo(ButtonInfo*& pVar)
	{
		m_nButtonInfoCounter--;
		ButtonInfo& biTemp = m_aButtonInfoArgs.GetAt(m_nButtonInfoCounter);
		pVar = &biTemp;
		return TRUE;
	}
	
	BOOL 	PopLineInfo(LineInfo*& pVar)
	{
		m_nLineInfoCounter--;
		LineInfo& liTemp = m_aLineInfoArgs.GetAt(m_nLineInfoCounter);
		pVar = &liTemp;
		return TRUE;
	}
	
	BOOL 	PopTextInfo(TextInfo*& pVar)
	{
		m_nTextInfoCounter--;
		TextInfo& tiTemp = m_aTextInfoArgs.GetAt(m_nTextInfoCounter);
		pVar = &tiTemp;
		return TRUE;
	}
	
	BOOL 	PopEventInfo(EventInfo*& pVar)
	{
		m_nEventInfoCounter--;
		EventInfo& eiTemp = m_aEventInfoArgs.GetAt(m_nEventInfoCounter);
		pVar = &eiTemp;
		return TRUE;
	}
	
	/// RVD 4/15/2005 QA70-7597 v8.0223 MARKER_GROBJ
	int		Push(MarkerInfo& var)
	{
		if( m_nMarkerInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aMarkerInfoArgs.Add(var);
		m_nMarkerInfoCounter++;
		return CallStack::Push(var);
	}

	BOOL 	PopMarkerInfo(MarkerInfo*& pVar)
	{
		m_nMarkerInfoCounter--;
		MarkerInfo& miTemp = m_aMarkerInfoArgs.GetAt(m_nMarkerInfoCounter);
		pVar = &miTemp;
		return TRUE;
	}
	/// end MARKER_GROBJ

	/// RVD 11/22/2006 QA70-9148 v8.0515 IMPLEMENT_RECTINFO
	int		Push(RectInfo& var)
	{
		if( m_nRectInfoCounter >= MAX_FUNC_ARG_CALLSTACK )
			return -1;
		
		m_aRectInfoArgs.Add(var);
		m_nRectInfoCounter++;
		return CallStack::Push(var);
	}

	BOOL 	PopRectInfo(RectInfo*& pVar)
	{
		m_nRectInfoCounter--;
		RectInfo& riTemp = m_aRectInfoArgs.GetAt(m_nRectInfoCounter);
		pVar = &riTemp;
		return TRUE;
	}
	/// end IMPLEMENT_RECTINFO

private:
	int					m_nVectorCounter;
	int					m_nDataRangeCounter;
	int					m_nXYRangeCounter;
	int					m_nXYZRangeCounter;
	int					m_nIntCounter;
	int					m_nDoubleCounter;
	int					m_nStringCounter;
	/// ML 3/6/2005
	int					m_nMatrixCounter;
	int					m_nOriginObjectCounter;
	/// end ML 3/6/2005
	
	int					m_nButtonInfoCounter;
	int					m_nLineInfoCounter;
	int					m_nTextInfoCounter;
	
	int					m_nEventInfoCounter;
	
	Array<vector&>		m_avArgs;
	
	/// YuI 08/12/05 QA70-8006 XFUNCTION_AND_TREE_VARIABLE
	int					m_nTreeCounter;
	Array<TreeNode&>	m_aTreeArgs;
	/// end XFUNCTION_AND_TREE_VARIABLE
	
	/// YuI 11/09/05 QA70-8279 REPORT_TREE_AND_REPORT_DATA_XVARIABLES
	int					m_nReportTreeCounter;
	Array<ReportTree&>	m_aReportTreeArgs;
	
	int					m_nReportDataCounter;
	Array<ReportData&>	m_aReportDataArgs;
	/// end REPORT_TREE_AND_REPORT_DATA_XVARIABLES

	/// YuI 08/29/05 QA70-7921 FILE_IMPORTING_XFUCNTIONS
	int					m_nFileLinkCounter;
	Array<FileLink&>	m_aFileLinkArgs;
	/// end FILE_IMPORTING_XFUCNTIONS

	/// ML 3/6/2005
	Array<matrix&>		m_amatArgs;
	Array<OriginObject&>	m_aOriginObjArgs;
	/// end ML 3/6/2005
	
	Array<ButtonInfo&>	m_aButtonInfoArgs;
	Array<LineInfo&>	m_aLineInfoArgs;
	Array<TextInfo&>	m_aTextInfoArgs;
	
	Array<EventInfo&>	m_aEventInfoArgs;
	
	Array<DataRange&>	m_adrArgs;
	Array<XYRange&>		m_aXYDrArgs;
	Array<XYZRange&>	m_aXYZDrArgs;
	Array<string&>		m_arrStringArguments;
	double				m_dbArgs[MAX_FUNC_ARG_CALLSTACK];
	int					m_intArgs[MAX_FUNC_ARG_CALLSTACK];

	/// RVD 4/15/2005 QA70-7597 v8.0223 MARKER_GROBJ
	int					m_nMarkerInfoCounter;
	Array<MarkerInfo&>	m_aMarkerInfoArgs;
	/// end MARKER_GROBJ

	/// RVD 11/22/2006 QA70-9148 v8.0515 IMPLEMENT_RECTINFO
	int					m_nRectInfoCounter;
	Array<RectInfo&>	m_aRectInfoArgs;
	/// end IMPLEMENT_RECTINFO
};
//---------


#endif //_CALLSTACK_H

