#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
////for temp include
#include <..\OriginLab\PAWizCore.h>

//put additional include files here
#include <..\OriginLab\XFWizard_utils.h>
#include <o8dlg.h>
#include <oc_debug.h>

//Sandy 2008-10-16 add subtract baseline goal
//#define _STR_COMBO_LIST_GOAL_IN_REG  _L("Integrate Peaks|Create Baseline|Find Peaks")
//#define _STR_COMBO_LIST_GOAL_IN_PRO  _L("Integrate Peaks|Create Baseline|Find Peaks|Fit Peaks")
///------ Folger 08/21/09 QA80-14165 PA_GOAL_DISABLE_FIT_PEAK_FOR_REGULAR
//#define _STR_COMBO_LIST_GOAL_IN_REG  _L("Integrate Peaks|Create Baseline|Subtract Baseline|Find Peaks")
/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
/*
#define _STR_COMBO_LIST_GOAL_IN_REG  _L("Integrate Peaks|Create Baseline|Subtract Baseline|Find Peaks|Fit Peaks (Pro)")
///------ End PA_GOAL_DISABLE_FIT_PEAK_FOR_REGULAR
#define _STR_COMBO_LIST_GOAL_IN_PRO  _L("Integrate Peaks|Create Baseline|Subtract Baseline|Find Peaks|Fit Peaks")
*/
#define _STR_COMBO_LIST_GOAL  _L("Integrate Peaks|Create Baseline|Subtract Baseline|Find Peaks|Fit Peaks (Pro)")
///End ALSO_SHOW_PRO_IN_PRO_VERSION


/*------------------------------------------------------------------------------*
 * Modification Log:  															*
 *  Iris 11/04/2008 v8.0965b PA_FIT_ADD_INPUT_REPORT_TABLE						*
 *  Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE		*
 *	Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE							*
 *	Folger 08/21/09 QA80-14165 PA_GOAL_DISABLE_FIT_PEAK_FOR_REGULAR				*
 *------------------------------------------------------------------------------*/

// 
static void _update_hints(TreeNode trGetN)
{
	if(!trGetN || !trGetN.goal || !trGetN.hint_int ||!trGetN.hint_base ||!trGetN.hint_find ||!trGetN.hint_fit ||!trGetN.hint_subtract_base)
		return;
	
	trGetN.hint_int.Show = (trGetN.goal.nVal == PA_GOAL_INTEGRATE_PEAK? true:false);
	trGetN.hint_base.Show = (trGetN.goal.nVal == PA_GOAL_CREATE_BASELINE? true:false);
	trGetN.hint_subtract_base.Show = (trGetN.goal.nVal == PA_GOAL_SUBTRACT_BASELINE? true:false);//sandy 2008-10-16 add subtract baseline goal
	trGetN.hint_find.Show = (trGetN.goal.nVal == PA_GOAL_FIND_PEAK? true:false);
	trGetN.hint_fit.Show = (trGetN.goal.nVal == PA_GOAL_FIT_PEAK? true:false);
	
	
}

static void _update_help_id(TreeNode &trGetN)
{
	int nHelpId = IDD_PA_START;
	switch ( trGetN.goal.nVal )
	{
	case PA_GOAL_INTEGRATE_PEAK:
		nHelpId = IDD_PA_INTEGREATE;
		break;
		
	case PA_GOAL_CREATE_BASELINE:
		nHelpId = IDD_PA_CREATE_BASELINE;
		break;
		
	case PA_GOAL_SUBTRACT_BASELINE:
		nHelpId = IDD_PA_SUBTRACT_BASELINE;//wait fisher add new help id
		break;
		
	case PA_GOAL_FIND_PEAK:
		nHelpId = IDD_PA_FIND_PEAK;
		break;
		
	case PA_GOAL_FIT_PEAK:
		nHelpId = IDD_PA_FIT_PEAK;
		break;
		
	default:
		break;
	}
	trGetN.SetAttribute(STR_HELPID_ATTRIB, nHelpId);
}

///sandy 2008-10-16  add
void 	_update_goal_radio_strings(TreeNode trGetN)
{
	trGetN.goal.SetAttribute(STR_COMBO_ATTRIB, _STR_COMBO_LIST_GOAL); /// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
	
		if(is_pro_version())
		{
			/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
			//trGetN.goal.SetAttribute(STR_COMBO_ATTRIB, _STR_COMBO_LIST_GOAL_IN_PRO);
			///End ALSO_SHOW_PRO_IN_PRO_VERSION
		}
		else
		{
			/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
			//trGetN.goal.SetAttribute(STR_COMBO_ATTRIB, _STR_COMBO_LIST_GOAL_IN_REG);
			///End ALSO_SHOW_PRO_IN_PRO_VERSION
			///------ Folger 08/21/09 QA80-14165 PA_GOAL_DISABLE_FIT_PEAK_FOR_REGULAR
			trGetN.goal.SetAttribute(STR_DISABLED_INDEX_START_ATTRIB, PA_GOAL_FIT_PEAK);
			if ( PA_GOAL_FIT_PEAK == trGetN.goal.nVal )
			{
				PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
				paCore->ChangeGoal(trGetN.goal.nVal = PA_GOAL_INTEGRATE_PEAK);
			}
			///------ End PA_GOAL_DISABLE_FIT_PEAK_FOR_REGULAR
		}
}

static BOOL	 _get_xyr_minmax_x_value(XYRange& xyr, double *prMin, double *prMax)
{
	double dMin, dMax;
	
	vector vx, vy;	
	BOOL	bb = xyr.GetData(vy, vx);
	if(!bb)
	{
		dMin = NANUM;
		dMax = NANUM;
		
		return false;
	}
	else
	{
		vx.GetMinMax(dMin, dMax);
	}
	
	if ( prMin )
		*prMin = dMin;
	if ( prMax )
		*prMax = dMax;

	return bb;
}


void pa_goal(const string& hint_int, const string& hint_base, const string& hint_subtract_base, const string& hint_find, const string& hint_fit, const int& goal, const int& nXFCorePointer, const XYRange& iy, const TreeNode& hint_input)
{
	///---Sim 01-07-2008 QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	//PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(getnhandler);
	PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(NODE_NAME_XF_WIZ_CORE_POINTER);
	///---END QA80-12833 FIX_APPLY_XF_WIZ_XF_TWICE
	if(!paCore)
		XF_THROW(XF_ERR_INVALID_PA_INSTANCE);
	
	paCore->SetInstanceID(iy.GetUID(true));
	
	int  nIsPro = is_pro_version();
	
	if(!is_pro_version() && goal == PA_GOAL_FIT_PEAK)
	{
		/// Iris 2/02/2010 QA81-14165 ALSO_SHOW_PRO_IN_PRO_VERSION
		//string strList 		= _STR_COMBO_LIST_GOAL_IN_REG;
		string strList 		= _STR_COMBO_LIST_GOAL;
		///End ALSO_SHOW_PRO_IN_PRO_VERSION
		string strFitPeak	= strList.GetToken(PA_GOAL_FIT_PEAK, '|');
		XF_THROW_EX(XFERR_PRO_OPTION_WARNNING_MSG, strFitPeak);
	}
	
	/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES
	//paCore->SetSourceRange(iy); /// Iris 11/01/2008 v8.0964 NEW_PA_SUPPORT_CREATE_REPORT_GRAPH_ON_SOURCE
	///end IMPROVE_GET_SOURCE_GRAPH_CODES
	
	/// Iris 11/04/2008 v8.0965b PA_FIT_ADD_INPUT_REPORT_TABLE
	if( nIsPro && goal == PA_GOAL_FIT_PEAK ) // only pa_fit xfunction need this report for now
	{
		Tree 		trOut;
		TreeNode 	trTable;
		XFExeContext* pxfexectxt = Project.GetCurrentXFExeCtxt();
		if( pxfexectxt && pxfexectxt->AddInputToTree(trOut, "iy", _L("Input Data"), trTable) )
		{
			paCore->SetInputDataTable(trTable);
		}
	}
	///end PA_FIT_ADD_INPUT_REPORT_TABLE
	
	
}

//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 pa_goal_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return pa_goal_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	
	PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
	ASSERT(paCore);
	
	if ( 0 == lstrcmp(lpcszNodeName, "goal") ||  nEventID ==GETNE_ON_INIT  || nEventID == GETNE_ON_THEME)
	{
		///sandy 2008-10-16 add reset goal radio strings when change theme or reset
		if(nEventID == GETNE_ON_THEME)
		{
			_update_goal_radio_strings(trGetN);
		}
		
		//preview drawing
		if(nEventID == GETNE_ON_INIT|| nEventID == GETNE_ON_THEME)
		{
			XYRange xyOrigin;
			if(!paCore->GetOriginalRange(xyOrigin)||!xyOrigin.IsValid())
			{
				strErrMsg = XFERR_NO_DATA_SELECT;
				bOKEnable = false;
				return false;
			}			
			GraphLayer gl;
			paCore->GetPreviewLayer(gl);
			if(!gl)
				return false;
			
			//xyOrigin.MakePlot(gl);
			DataPlot dpPreview = xyOrigin.MakePlot(gl);
			
			//------ Folger 10/16/08 SAVE_PLOT_UIDS_IN_PA_CORE_TO_WORKAROUND_MISSING_PREVIEW_PLOT_IN_PA_FIT
			vector<uint>	vnPlots;
			xyOrigin.GetPlots(vnPlots);
			paCore->AccessOriginalRangePlots(vnPlots, false);
			//------ End SAVE_PLOT_UIDS_IN_PA_CORE_TO_WORKAROUND_MISSING_PREVIEW_PLOT_IN_PA_FIT
			
			/*
			//gl.Rescale();   ///Sandy 2008-8-9 should not rescale when the drawing current plot
			///Sandy 2008-10-12 if there isn't souce graph, should auto rescale preview graph
			GraphLayer glSource;
			/// Iris 11/06/2008 v8.0966b IMPROVE_GET_SOURCE_GRAPH_CODES, function name changed
			//glSource = paCore->GetOriginalGraph();
			paCore->GetSourceGraph(glSource);
			///end IMPROVE_GET_SOURCE_GRAPH_CODES
			if(!glSource.IsValid())
			{
				gl.Rescale();
			}	
			*/
			
			///Sandy 2009-1-22 update input range description of Spectrum Data
			//1, hint of spectrum range 
			string strInputDes = _L("Spectrum") + " = " + xyOrigin.GetDescription(GETLC_NO_DESIGNATIONS|GETLC_NO_ROWS);
			trGetN.hint_input.spectrum.strVal = strInputDes;//SetAttribute(STR_LABEL_ATTRIB, strInputDes);
			
			//2, hint of rows
			string strNRange;
			Worksheet wksSource;
			int r1, r2, c1, c2;
			xyOrigin.GetRange(0, r1, c1, r2, c1, wksSource);
			string strEnd;
			if(r2 == -1)
				strEnd = "end";
			else
				strEnd =  (string)(r2+1);//row number should base on 1
			strNRange.Format("%s = [%s, %s]", _L("Rows"), (string)(r1+1), strEnd );
			//trGetN.hint_nrange.SetAttribute(STR_LABEL_ATTRIB, strNRange);
			trGetN.hint_input.nrange.strVal = strNRange;
			
			//3, hint of x range
			double dx1, dx2;
			if(_get_xyr_minmax_x_value(xyOrigin, &dx1, &dx2))
			{
				string strXRange;//xyOrigin.GetDescription(GETLC_DATAPLOTS)
				strXRange.Format("%s = (%s, %s)",  _L("X Range"), ftoa(dx1, "*4"),  ftoa(dx2, "*4"));
				//trGetN.hint_xrange.SetAttribute(STR_LABEL_ATTRIB, strXRange);
				trGetN.hint_input.xrange.strVal = strXRange;
			}
			
			//4, hint of npts
			string strNPTS;
			vector vtx, vty;
			xyOrigin.GetData(vty, vtx);
			strNPTS = _L("Number of Points") + " = " + (string)(vty.GetSize());
			//trGetN.hint_npts.SetAttribute(STR_LABEL_ATTRIB, strNPTS);
			trGetN.hint_input.npts.strVal = strNPTS;
			///end
		}
		
		paCore->SetGoal(trGetN.goal.nVal);
		if( 0 == lstrcmp(lpcszNodeName, "goal"))
			paCore->ChangeGoal(trGetN.goal.nVal);
		
		_update_hints(trGetN);
		_update_help_id(trGetN);
		return true;
	}	
	
	//if(nEventID == GETNE_ON_RESTORE)
	//{
		//return true;
	//}
	//
	//if( nEventID ==  GETNE_ON_PREVIOUS)
	//{
		//return true;
	//}	
	if(nEventID == GETNE_ON_UNDO)
	{
		return true;
	}
	
	
	return false;
	
	

}

int pa_goal_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	if(tr.IsValid())
	{	
		string strVarName = lpcszVarName;
		if (strVarName == "hint_input")
		{
			string strTemp;
			GETN_USE(tr)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	
			GETN_STR(spectrum, "", strTemp)	GETN_INFO	
			GETN_STR(xrange, "", strTemp)	GETN_INFO
			GETN_STR(nrange, "", strTemp)	GETN_INFO	
			GETN_STR(npts, "", strTemp)		GETN_INFO
			
		}
		return 0;
	}
}
//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 pa_goal_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	//
	
	//
	//if(nGetNDialog == -2)
	//{
		//XYRange xyOrigin;
		//if(!paCore->GetOriginalRange(xyOrigin)||!xyOrigin.IsValid())
		//{
			//TreeNode trInputData= trGetN.iy;
			//if(!okxf_resolve_tree_construct_range(&trInputData, &xyOrigin)||!xyOrigin.IsValid())
			//{
				//warning_msg_box(XFERR_NO_DATA_SELECT, true);
				//nRet = XFEVT_ABORT;
			//}
		//}
	//}
	
	if( nGetNDialog > 0 )
	{
		///sandy 2008-10-16 
		_update_goal_radio_strings(trGetN);
		//if(is_pro_version())
		//{
			//trGetN.goal.SetAttribute(STR_COMBO_ATTRIB, _L(_STR_COMBO_LIST_GOAL_IN_PRO));
		//}
		//else
			//trGetN.goal.SetAttribute(STR_COMBO_ATTRIB, _L(_STR_COMBO_LIST_GOAL_IN_REG));
		
	}
	
	if(nGetNDialog == 0)
	{
		PAWizCore* paCore = (PAWizCore*)get_xf_core_handler(trGetN);
		ASSERT(paCore);			
		paCore->SetGoal(trGetN.goal.nVal);
	}
	
}
//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 pa_goal_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
