#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	mode_auto,
	mode_concat,
	mode_global,
	mode_cons,
};
enum{
	pnotation_para,
	pnotation_abbr,
	pnotation_both,
};
enum{
	init_auto,
	init_enable,
	init_disable,
};
enum{
	option_init_all,
	option_change_data,
};
//put additional include files here
#include <operation.h>
#include <..\originlab\nlsf_utils.h>
#ifdef _FOR_SMART_LOADING_ONLY
#include <xfgraph_utils.h> //CPY 5/1/08 op_utils.c compile err in nlbegin after Hong 01/29/08 QA80-10929 LT_NL_ALLOW_UPDATE_PARAMS_BY_DIALOG

#include <..\originlab\wksOperation.h>
#include <stats_utils.h>
#include <..\originlab\stats_guis.h>
#include <event_utils.h>
#include <report_utils.h>
#include <..\originlab\graph_utils.h>
#include <..\originlab\stats_operations.h>
#include <..\originlab\StatsOpBase.h>
#include <FitterOperation.h>
#include <..\originlab\FitNL.h>
#endif
#include <..\originlab\op_utils.h>
///===================end of include headers=============================

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Folger 08/26/09 QA80-13859 UPDATE_INPUT_RANGE_BY_FUNC_NUM_DEPS_INDEPS		*
 *	Folger 12/08/09 QA81-14819 CHANGE_PARAM_FROM_OPERATION_CREATED_BY_NLBEGIN_FAILS
 *------------------------------------------------------------------------------*/

///------ Folger 08/26/09 QA80-13859 UPDATE_INPUT_RANGE_BY_FUNC_NUM_DEPS_INDEPS
//static		void	_reconstruct_range_by_column_designations(DataRange& dr, const DataRange& drInput)
//{
	//vector<string>		vsColDesignations = {"Y", "", "ED", "X", "L", "Z"};
	//
	//dr.Create();
	//int		nNumRanges  =drInput.GetNumRanges();
	//for ( int ii=0; ii<nNumRanges; ++ii )
	//{
		//Worksheet		wks;
		//int				r1, c1, r2, c2;
		//string			strName;
		//drInput.GetRange(ii, r1, c1, r2, c2, wks, &strName);
		//for ( ; c1<=c2; ++c1 )
		//{
			//Column	col(wks, c1);
			//if ( col.GetType() < vsColDesignations.GetSize() )
				//strName = vsColDesignations[col.GetType()];
			//dr.Add(strName, wks, r1, c1, r2, c1);
		//}
	//}
//}

static		void	_reconstruct_range_by_func_num_deps_indeps(DataRange& dr, const DataRange& drInput, int nNumIndeps, int nNumDeps)
{
	vector<string>		vs(nNumIndeps + nNumDeps);
	int		ii;
	for ( ii=0; ii<nNumIndeps; ++ii )
		vs[ii] = "X";
	for ( ; ii<nNumIndeps + nNumDeps; ++ii )
		vs[ii] = "Y";
	
	dr.Create();
	int		nNumRanges  =drInput.GetNumRanges();
	int		nCount = 0;
	for ( ii=0; ii<nNumRanges; ++ii )
	{
		Worksheet		wks;
		int				r1, c1, r2, c2;
		string			strName;
		drInput.GetRange(ii, r1, c1, r2, c2, wks, &strName);
		for ( ; c1<=c2; ++c1 )
		{
			Column	col(wks, c1);
			dr.Add(vs[(nCount++)%(nNumIndeps + nNumDeps)], wks, r1, c1, r2, c1);
		}
	}
}
///------ End UPDATE_INPUT_RANGE_BY_FUNC_NUM_DEPS_INDEPS


void nlbeginr(const Range& irng, const string& func, TreeNode& nltree, const int& mode, const string& theme, const int& pnotation, const int& init, const int& option)
{
	
	LPCSTR lpcstr = NULL;
	if ( theme && !theme.IsEmpty() )
		lpcstr = theme;		
	
	bool bAutoInit;
	bool* pbAutoInit = NULL;	
	if( init_auto != init )
	{
		bAutoInit = init_enable == init? true : false;
		pbAutoInit = &bAutoInit;
	}
	///Sophy 9/18/2009 QA80-14072 SUPPORT_CHANGE_INPUTDATA_IN_NLFIT_FROM_LABTALK
	string strFuncName(func);
	if ( option == NLFIT_CHANGE_DATA )
	{
		int nErrCode = lt_nlf_get_function_name(strFuncName);
		if ( nErrCode != OP_NOERROR )
			XF_THROW(cvt_op_err_to_nlf_xf_err(nErrCode));
	}
	///end SUPPORT_CHANGE_INPUTDATA_IN_NLFIT_FROM_LABTALK
	vector<string>		vstrIndepVars, vstrDepVars;
	int 	nNumIndep = nlf_get_independent_variables(strFuncName, &vstrIndepVars);
	int 	nNumDep = nlf_get_dependent_variables(strFuncName, &vstrDepVars);
	
	DataRange			dr;
	///------ Folger 08/26/09 QA80-13859 UPDATE_INPUT_RANGE_BY_FUNC_NUM_DEPS_INDEPS
	//_reconstruct_range_by_column_designations(dr, irng);
	_reconstruct_range_by_func_num_deps_indeps(dr, irng, nNumIndep, nNumDep);
	///------ End UPDATE_INPUT_RANGE_BY_FUNC_NUM_DEPS_INDEPS
	
	///------ Folger 12/08/09 QA81-14819 CHANGE_PARAM_FROM_OPERATION_CREATED_BY_NLBEGIN_FAILS
	//if ( nNumIndep >= 1 && nNumDep >= 1 )
	//{
		//Tree			tr;
		//dr.GetTree(tr);
		//if ( okutil_create_fitter_data_node_ex(&tr, NULL, STR_INPUT_RANGE_NAME, STR_INPUT_RANGE_LABEL, &vstrIndepVars, &vstrDepVars, WEIGHT_NONE) )
		//{
			//dr.SetTree(tr);
		//}
	//}
	///------ End CHANGE_PARAM_FROM_OPERATION_CREATED_BY_NLBEGIN_FAILS
	///Sophy 8/5/2009 QA80-14072 SUPPORT_CHANGE_INPUTDATA_IN_NLFIT_FROM_LABTALK
	//int		nErr = lt_nlf_nlbegin(dr, func, nltree, mode, 0, lpcstr, pnotation, NLFIT_GENERAL_XY_FITTING, pbAutoInit);
	int		nErr = OP_NOERROR;
	if ( option == NLFIT_CHANGE_DATA )
		nErr = lt_nlf_change_inputdata(dr);
	else
		nErr = lt_nlf_nlbegin(dr, strFuncName, nltree, mode, 0, lpcstr, pnotation, NLFIT_GENERAL_XY_FITTING, pbAutoInit);
	///end SUPPORT_CHANGE_INPUTDATA_IN_NLFIT_FROM_LABTALK
	if ( OP_NOERROR != nErr )
		XF_THROW(cvt_op_err_to_nlf_xf_err(nErr));
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int nlbeginr_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return nlbeginr_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return false;

}

int nlbeginr_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void nlbeginr_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int nlbeginr_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
