/*------------------------------------------------------------------------------*
 * File Name: XFCore.c															*
 * Creation: Sim 03-20-2007														*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	Sim 08-19-2008 QA80-12050 GET_GUI_GETN_TREE_FOR_CHANGE_PARAM_MODE			*
 *	Sim 08-26-2008 QA80-12093 REUSE_REPORT_DATA_IN_XFWIZ_WHEN_RECALCULATE		*
 *	Folger 11/26/08 v8.0980 WIZARD_SHOULD_FULLY_DEPEND_ON_SELF_THEME_MANAGER_INSTEAD_OF_INDIVIDUAL_XF_THEME_FILE
 *	Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE							*
 *	Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE				*
 *	Sim 01-13-2009 XFWIZ_CHANGE_PARAM_MAY_CHANGE_THEME_AND_IO_RANGE				*
 *	Folger 01/19/09 QA80-12969 PA_FITTING_SUPPORT_ANALYSIS_TEMPLATE				*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.
#include <XFBase.h>
#include <GetNBox.h>

#include <..\OriginLab\XFunctionEx.h>
#include <..\OriginLab\XFCore.h>
#include <..\OriginLab\XFWiz.h>
////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
///---Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
//#define STR_VAR_GETN_HANDLER	"getnhandler"
///---END QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE

//static bool _error_report_to_user_and_developer(LPCSTR lpcszErr)
//{
	//warning_msg_box(lpcszErr, true);
	//return error_report(lpcszErr);
//}

XFCore::XFCore()
{
	//m_drInput.Create();
	m_arrdrInputs.SetAsOwner(TRUE);
	//m_arrdrInputs.SetSize(1);
	
	m_arrdrOutputs.SetAsOwner(TRUE);
	
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	m_bIsRecalculateShown = false;
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	
	m_dwUIDOp = 0;		///------ Folger 01/19/09 QA80-12969 PA_FITTING_SUPPORT_ANALYSIS_TEMPLATE
}

//virtual
//double XFCore::GetVersion()
//{
	//return DEFAULT_VERSION_NUMBER;
//}
	
bool XFCore::Load(LPCSTR lpcszXFName)
{
	m_arrdrInputs.SetSize(0);
	m_arrdrOutputs.SetSize(0);
		
	string strXFName = lpcszXFName;
	if ( strXFName.IsEmpty() )
		error_report_to_user_and_developer("XFunction name is empty!");
	
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	m_bIsRecalculateShown = ( m_vsXFsRecalculateShown.Find(lpcszXFName) >= 0 );
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	if( !m_XF.Load(lpcszXFName, m_dwXFMode, m_trXF) )
	{
		string strErr;
		strErr.Format("Fail to load xfunction %s!", lpcszXFName);
		return error_report_to_user_and_developer(strErr);
	}
	
	//TreeNode trJunk;
	///---Sim 08-19-2008 QA80-12050 GET_GUI_GETN_TREE_FOR_CHANGE_PARAM_MODE
	//if ( !m_XF.GetGUI(m_trRootGetN, m_trGetN, m_nAddRecalculate, m_nAddResultsLogOutput) )
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	//if ( !m_XF.GetGUI(m_trRootGetN, m_trGetN, m_nAddRecalculate, m_nAddResultsLogOutput, m_dwXFMode) )
	if ( !m_XF.GetGUI(m_trRootGetN, m_trGetN, ( m_bIsRecalculateShown ? XFGETN_EX_FOLLOW_XF : m_nAddRecalculate ), m_nAddResultsLogOutput, m_dwXFMode) )
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	///---END QA80-12050 GET_GUI_GETN_TREE_FOR_CHANGE_PARAM_MODE
	{
		string strErr;
		strErr.Format("Fail to load GetN tree of xfunction %s!", lpcszXFName);
		return error_report_to_user_and_developer(strErr);
	}
	//OnSetGetN(trGetN);
	InitGetNSetting(m_trGetN);
	
	return true;
}
void XFCore::InitGetNSetting(TreeNode& trGetN)
{
	if ( !m_strClassName.IsEmpty() )
		trGetN.SetAttribute(STR_CLASS_OPTION_NAME_ATTRIB, m_strClassName);
	//------ Folger 11/26/08 v8.0980 WIZARD_SHOULD_FULLY_DEPEND_ON_SELF_THEME_MANAGER_INSTEAD_OF_INDIVIDUAL_XF_THEME_FILE
	tree_set_theme_file_name(trGetN, STR_NONE);
	//------
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	TreeNode trAutoUpdate = trGetN.GetNode(STR_NODE_NAME_AUTO_UPDATE);
	if ( m_bIsRecalculateShown && trAutoUpdate )
	{
		if ( m_dwXFMode & LTXF_CHANGE_PARAM )
			trAutoUpdate.Enable = false;
	}	
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
}

/// virtual
bool XFCore::Apply()
{
	if ( m_XF )
	{
		//TreeNode trGetN;
		//if ( !GetGetN(trGetN) )
			//return false;
		
		//m_XF.InvokeBeforeExecute(trGetN, m_dwExecute, m_nGetNType);
		OnBeforeExecute(-2); //-2 to indicate the call is from OC
		m_XF.SetGUI(m_trGetN);
		
		//if ( !m_trExecuteGetN.IsEmpty() )
			//m_XF.ApplyTheme(NULL, m_trExecuteGetN, true, true);
		
		// clear and prepare
		m_arrdrInputs.SetSize(0);
		DataRange *pdrInput = new DataRange;
		m_arrdrInputs.Add(*pdrInput);
		
		m_arrdrOutputs.SetSize(0);
		DataRange* pdrOutput = new DataRange;
		m_arrdrOutputs.Add(*pdrOutput);
		
		///---Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
		//if ( m_trGetN.GetNode(STR_VAR_GETN_HANDLER) ) // fix runtime error
			//m_XF.SetArg(STR_VAR_GETN_HANDLER, m_trGetN); // for xf body get trGetN tree back
		///---END QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
		//bool bRet = m_XF.Evaluate(0, m_trExecuteGetN);
		bool bRet = m_XF.Evaluate(pdrInput, &m_arrdrOutputs, m_dwExecute | LTXF_SUPPRESS_BEFORE_EXECUTE);
		
		//if ( !bRet )
			//m_trExecuteGetN.Reset();
		//SetExecValsInfo2GetNTree(m_trGetN, m_trExecuteGetN);
		
		return bRet;
	}
	return false;
}

//void XFCore::GetInputOutputs(DataRange& drInput, Array<DataRange&>& arrdrOutputs)
//{
	//drInput = m_drInput;
	//arrdrOutputs = m_arrdrOutputs;
//}
const Array<DataRange&>* XFCore::GetInputs()
{
	return &m_arrdrInputs;
}
const Array<DataRange&>* XFCore::GetOutputs()
{
	return &m_arrdrOutputs;
}
///---Sim 08-26-2008 QA80-12093 REUSE_REPORT_DATA_IN_XFWIZ_WHEN_RECALCULATE
bool XFCore::UpdateOutputUIDs(vector<int>& vUIDs)
{
	return m_XF.UpdateOutputUIDs(vUIDs);
}
///---END QA80-12093 REUSE_REPORT_DATA_IN_XFWIZ_WHEN_RECALCULATE

//bool XFCore::Undo()
//{
	//// need to do;
	//return true;
//}

int XFCore::OnBeforeExecute(int nEventID)// = XF_GETN_SIMPLE
{
	int nRet = -1;
	if ( m_XF )
		//nRet = m_XF.InvokeBeforeExecute(m_trGetN, LTXF_XFBAR, nEventID);
		nRet = m_XF.InvokeBeforeExecute(m_trGetN, m_dwXFMode, nEventID);
		
	return nRet;
}
Function XFCore::GetEventHandler()
{
	if(!m_trXF.IsValid())
    {	
    	out_str("The Event Handler Tree is not Invalid!");
    	return NULL;
    }
    return xf_get_event(m_trXF, 1);
}
	
bool XFCore::GetGetN(TreeNode &trGetN)
{
	if ( !m_XF )
		return false;
	
	trGetN = m_trGetN;
	return true;
}
string  XFCore::GetXFName(string& strXFDescription) // = NULL
{
	string strXFName, strXFDesp;
	
	TreeNode trDesc;
	if ( octree_get_localization_node(&trDesc, &m_trXF, IDV_HELP_DESCRIPTION, IDXF_DESCRIPTION, IDV_HELP_BRANCH) )
	{
		xf_seperate_description(trDesc.strVal, strXFName, strXFDesp);	
	}
	
	if ( NULL != (&strXFDescription) )
		strXFDescription = strXFDesp;
	
	return strXFName;
}

bool XFCore::SetDefautlValue()
{
	//TreeNode trJunk;
	//return m_XF.GetGUI(m_trRootGetN, m_trGetN, m_nAddRecalculate, m_nAddResultsLogOutput);
	///---Sim 01-12-2009 QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	//bool bRet = m_XF.GetGUI(m_trRootGetN, m_trGetN, m_nAddRecalculate, m_nAddResultsLogOutput, m_dwXFMode);
	bool bRet = m_XF.GetGUI(m_trRootGetN, m_trGetN, ( m_bIsRecalculateShown ? XFGETN_EX_FOLLOW_XF : m_nAddRecalculate ), m_nAddResultsLogOutput, m_dwXFMode);
	///---END QA80-12946 XFWIZ_SUPPORT_CHANGE_RECALCULATE_MODE
	if ( bRet )
		InitGetNSetting(m_trGetN);
	
	return bRet;	
}

void XFCore::SetXFMode(DWORD dwXFMode)
{
	m_dwXFMode = dwXFMode;
}
void XFCore::SetExecute(DWORD dwExecute)
{
	m_dwExecute = dwExecute;
}
void XFCore::SetRecalculate(int nAddRecalculate)
{
	m_nAddRecalculate = nAddRecalculate;
}
void XFCore::SetResultsLogOutput(int nAddResultsLogOutput)
{
	m_nAddResultsLogOutput = nAddResultsLogOutput;
}

//void XFCore::SetTargetPage(const Page& pg)
//{
	//m_TargetPage = pg;
//}
//bool XFCore::GetTargetPage(Page& pg)
//{
	//if ( m_TargetPage )
	//{
		//pg = m_TargetPage;
		//return true;
	//}
		//
	//return false;
//}
	
//bool XFCore::SetExecValsInfo2GetNTree(TreeNode& trGetN, const TreeNode& trExecuteGetN)
//{
	//TreeNode trExecutionVals = get_external_settings_branch(trGetN, EX_SETTING_EXEC_VALS, true);
	//if ( !trExecutionVals )
		//return false;
	//
	//trExecutionVals.Replace(trExecuteGetN, true, true, true);
	//tree_remove_attribute(trExecutionVals, STR_DATAID_ATTRIB);
	//return true;
//}

void XFCore::SetXFWizNavigation(DWORD dwXFWizNavigationHandler)
{
	m_dwXFWizNavigationHandler = dwXFWizNavigationHandler;
}
DWORD XFCore::GetXFWizNavigation()
{
	return m_dwXFWizNavigationHandler;
}

//bool XFCore::SetMapStepLabels(const StringArray& saMapXFNames, const StringArray& saMapXFLabels)
//{
	//if ( saMapXFNames.GetSize() == saMapXFLabels.GetSize() )
	//{
		//m_saMapXFNames = saMapXFNames;
		//m_saMapXFLabels = saMapXFLabels;
		//return true;
	//}
	//return false;
//}

//bool XFCore::GetStepLabels(const StringArray& saXFNames, StringArray& saXFLables)
//{
	//saXFLables = saXFNames;
	//for ( int ii = 0; ii < saXFNames.GetSize(); ii++ )
	//{
		//int nIndex = m_saMapXFNames.Find(saXFNames[ii]);
		//if ( nIndex >= 0 )
		//{
			//if ( nIndex > m_saMapXFNames.GetSize() - 1 || nIndex > m_saMapXFLabels.GetSize() - 1)
				//return false;
		//
			//saXFLables[ii] = m_saMapXFLabels[nIndex];
		//}
	//}
	//
	//return true;
//}
