#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	type_math,
	type_abs,
};
//put additional include files here
#include <event_utils.h>
#include <o8dlg.h>

/// modification log
/// ML 4/18/2007 QA70-9643 ALLOW_NO_X_IN_OUTPUT_SUCH_THAT_XYRANGE_IF_OUTPUT_ONLY_CREATES_ONE_Y_COLUMN
/// CPY 6/25/2007 ALLOW_NO_INTEGRAL_CURVE_OUTPUT
/// Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
/// Folger 09/25/08 QA80-12276 SET_SAMPLING_INTERVAL_FOR_YXRANGE_OUTPUT
/// Kyle 11/11/2008 QA80-12356 SET_NOT_TO_ALTER_THE_INPUT_X_VALUES_WHEN_THERE_ARE_MISSING_VALUES
/// Folger 12/10/08 QA80-12250 ADD_BASELINE_OPTION_FOR_INTEG1
/// Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES

//put your own support static functions here
#define	MIN_INPUT_DATA_NUMBER 2
///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
#define	DATE_RULES		DRR_NO_WEIGHTS | DRR_NO_FACTORS | DRR_GET_DEPENDENT
///------ End ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES

///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
//static bool _construct_integral_curve(XYRange& oy, const int& plot, const int& color)
static bool _construct_integral_curve(XYRange& oy, const int& plot, int nColor = 1)
///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
{
	///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	//int nVal = okutil_ocolor_LT_color_convert(color, false); // false = LT color to OCOLOR
	///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	if (true == plot)
	{
		///Arvin 08/23/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
		/*
		GraphPage gp;
		gp.Create("Origin");
		if(!gp.IsValid()) 
			return false;
		GraphLayer glnew = gp.Layers();
		if(!glnew.IsValid()) 
			return false;
		int nIndex = glnew.AddPlot(oy, IDM_PLOT_LINE);
		DataPlot dp = glnew.DataPlots(nIndex);
		if(!dp.IsValid()) 
			return false;

		dp.SetColor(nColor);
		glnew.Rescale();
		legend_update(glnew);
		*/
		xf_check_plot_output_rng_in_graph(oy);
		///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	}

	return true;
}
/*
static void _update_plot_show(TreeNode& trGetN, int nOutRangeType, int& nErr)
{
	switch(nOutRangeType)
	{
	case PDS_INVALID:
	case PDS_UNASSIGNED:
		trGetN.plot.Show = false;
		trGetN.color.Show = false;
		//if (nErr == CER_NO_ERROR)
			//nErr = CER_NOT_ONE_XYRANGE;
		break;
	case PDS_OPTIONAL:
		trGetN.plot.Show = false;
		trGetN.color.Show = false;
		break;
	case PDS_NEW:
	case PDS_USER:
	case PDS_ACTIVE:
	case PDS_INPUT:	
		trGetN.plot.Show = true;
		trGetN.color.Show = true;
		break;
	default:
		trGetN.plot.Show = false;
		trGetN.color.Show = false;
		//if (nErr == CER_NO_ERROR)
			//nErr = CER_NOT_ONE_XYRANGE;
		break;
	}
	
	if(trGetN.plot.nVal == false || trGetN.plot.Show == false)
		trGetN.color.Show = false;
	else
		trGetN.color.Show = true;
	
}
*/
///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
/*
static void _update_plot_show(TreeNode& trGetN)
{
	trGetN.color.Show = (trGetN.plot.nVal == 1) ? true:false;
}
*/
///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF

///Cheney 2007-6-7 ADD_AN_ERR_CHECK_FUNC
static int _check_err_condition(TreeNode& trGetN)
{
	int nErr = CER_NO_ERROR;
	///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
	//if(get_input_xyrange_num(trGetN.iy) != 1)
		//nErr = CER_NOT_ONE_XYRANGE;
		//
	//if(nErr == CER_NO_ERROR && 0>= get_input_xyrange_data_size(trGetN.iy))
		//nErr = CER_NO_DATA;
	//
	/////Arvin 07/30/07 WRONG_ERR_MASSAGE
	///// Cloud 10/11/07 WRONG_MIN_DATA_NUMBER_CONDITION
	////if(nErr == CER_NO_ERROR && MIN_INPUT_DATA_NUMBER >= get_input_xyrange_data_size(trGetN.iy))
	//if(nErr == CER_NO_ERROR && MIN_INPUT_DATA_NUMBER > get_input_xyrange_data_size(trGetN.iy))
		//nErr = CER_DATA_TOO_FEW;
	///// End WRONG_MIN_DATA_NUMBER_CONDITION
	/////END WRONG_ERR_MASSAGE
	XYRange		xy;
	if ( xy_range_from_GetN_data_node(trGetN.iy, xy) && xy )
	{
		int		nNumDatas = xy.GetNumData(DATE_RULES);
		for ( int ii=0; ii<nNumDatas; ++ii )
		{
			DataRange	dr;
			xy.GetSubRange(dr, DATE_RULES, ii);
			XYRange		xySub(dr);
			int		nDataSize = get_input_xyrange_data_size(xySub);
			if ( nDataSize <= 0 )
				nErr = CER_NO_DATA;
			else if ( nDataSize <= MIN_INPUT_DATA_NUMBER )
				nErr = CER_DATA_TOO_FEW;
			
			if ( 0 != nErr )
				break;
		}
	}
	else
	{
		nErr = CER_NO_DATA;
	}
	///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES
	
	return nErr;
}
///end ADD_AN_ERR_CHECK_FUNC

//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
static	void	_set_output_range_comments(XYRange &oy, const XYRange& iy, int nType)
{
	vector<string>		vsAreaTypes;
	vsAreaTypes.Add(_LC("Mathematical Integral Area", "integ1"));
	vsAreaTypes.Add(_LC("Absolute Integral Area", "integ1"));
	
	if(oy != NULL && oy.IsValid())
		oy.SetOutputComment(vsAreaTypes[nType] + " of " + get_input_data_range_string(iy));
}
//------ End BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS

//------ Folger 12/10/08 QA80-12250 ADD_BASELINE_OPTION_FOR_INTEG1
static	void	_calculate_baseline_y_data(vector& vby, const vector& vx, const vector& vy, int nStart, int nEnd)
{
	ASSERT(nStart >= 0 && vx.GetSize() > nEnd);
		
	if ( vx[nStart] == vx[nEnd] )
	{
		vy.GetSubVector(vby, nStart, nEnd);
	}
	else
	{
		double a = (vy[nEnd] - vy[nStart]) / (vx[nEnd] - vx[nStart]);
		double b = vy[nStart] - a * vx[nStart];
		vby.SetSize(nEnd - nStart + 1);
		for ( int ii=nStart; ii<=nEnd; ++ii )
		{
			vby[ii] = a * vx[ii] + b;
		}
	}
}
//------ End ADD_BASELINE_OPTION_FOR_INTEG1


void integ1(const XYRange& iy, const int& baseline, const int& type, XYRange& oy, const int& plot, double& x1, double& x2, int& i1, int& i2, double& area, double& y0, double& x0, double& dx)
{
	
	vector vx, vy, vIntegrated;
	
	///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
	int		nNumDatas = iy.GetNumData(DATE_RULES);
	for ( int ii=0; ii<nNumDatas; ++ii )
	{
		DataRange	drInput;
		iy.GetSubRange(drInput, DATE_RULES, ii);
		XYRange		iySub(drInput);
		
		XYRange		oySub;
		if ( oy )
		{
			DataRange	drOutput;
			oy.GetSubRange(drOutput, DATE_RULES, ii);
			oySub = drOutput;
		}
	///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES
		///Kyle 11/11/2008 QA80-12356 SET_NOT_TO_ALTER_THE_INPUT_X_VALUES_WHEN_THERE_ARE_MISSING_VALUES
		//if(!iy.IsValid() || iy.GetNumData(DRR_GET_DEPENDENT) != 1 || !iy.GetData(vy, vx))
		vector<int> vnMissingValsIndices;
		if(!iySub.IsValid() || iySub.GetNumData(DRR_GET_DEPENDENT) != 1 || !iySub.GetData(vy, vx, NULL, 0, DRR_BAD_WEIGHT_TREATMENT, &vnMissingValsIndices))
		///End SET_NOT_TO_ALTER_THE_INPUT_X_VALUES_WHEN_THERE_ARE_MISSING_VALUES
				XF_THROW(CER_NOT_ONE_XYRANGE);	
		
		if(0>= vy.GetSize())
			XF_THROW(CER_NO_DATA);
				
		///Arvin 07/24/06 ADD_DIFFERENT_INTEGRATION_TYPE
		/// Cloud 06/08/2007 X_COORDINATE_NO_NEED_MONOTONIC
		/*
		if(MONO_INCREASE != ocmath_is_monotonic(vx, vx.GetSize(), false) && MONO_DECREASE != ocmath_is_monotonic(vx, vx.GetSize(), false))
		{
			warning_msg_box(CWARN_NONMONOTONIC_X, true);
			vector<uint> vN;
			vx.Sort(SORT_ASCENDING, FALSE, vN);
			vy.Reorder(vN);
		}
		*/
		/// End X_COORDINATE_NO_NEED_MONOTONIC
		/*
		if(type == ABSOLUTE_AREA)
		{
			for(int ii= 0; ii < vy.GetSize(); ii++)
				vy[ii] = abs(vy[ii]);
		}
		*/
		///END ADD_DIFFERENT_INTEGRATION_TYPE
		
		int nFrom = 0, nTo = vy.GetUpperIndex();	//	integration index
		vIntegrated.SetSize(nTo+1);	// size = last_index + 1
		IntegrationResult result;
		
		//------ Folger 12/10/08 QA80-12250 ADD_BASELINE_OPTION_FOR_INTEG1
		//if (OE_NOERROR != ocmath_integrate(vx, vy, nFrom, nTo, &result, vIntegrated, type))
		double*		rBaseline = NULL;
		vector		vby;
		if ( baseline )
		{
			_calculate_baseline_y_data(vby, vx, vy, nFrom, nTo);
			rBaseline = vby;
		}
		
		/// YuI 01/26/09 INTEGRATION_BUG
		//	if (OE_NOERROR != ocmath_integrate(vx, vy, nFrom, nTo, &result, vIntegrated, type, rBaseline))
		if (OE_NOERROR != ocmath_integrate(vx, vy, nFrom, nTo, &result, vIntegrated, type, rBaseline))
		/// end INTEGRATION_BUG
		//------ End ADD_BASELINE_OPTION_FOR_INTEG1
		{	
			//	integrate failed
			XF_THROW(XFERR_INTEGRATE_FAILED);
			return;
		}
		
		/// Max 6/1/07 CHECK_IF_OUTPUT_AND_INPUT_SHARE_X
		/*
		if(oy != NULL && oy.IsValid() )
		{
			if(!oy.SetData(&vIntegrated, &vx))
				XF_THROW(XFERR_FAIL_IN_SET_XYRANGE_DATA);
		*/
		
		if ( oySub )
		{
			//------ Folger 09/25/08 QA80-12276 SET_SAMPLING_INTERVAL_FOR_YXRANGE_OUTPUT
			//bool bXShare = oy.IsIntersect(iy,"X");
			//bool bYShare = oy.IsIntersect(iy,"Y");
			//vector *pX = &vx;
			//if(bXShare && !bYShare)
			//pX = NULL;
		
			//if(!oy.SetData(&vIntegrated, pX))
			///Kyle 11/11/2008 QA80-12356 SET_NOT_TO_ALTER_THE_INPUT_X_VALUES_WHEN_THERE_ARE_MISSING_VALUES
			//if( !set_xyrange_data_ex(oy, &vIntegrated, &vx, 0, iy) )
			if( !set_xyrange_data_ex(oySub, &vIntegrated, &vx, 0, iySub, &vnMissingValsIndices) )
			///End SET_NOT_TO_ALTER_THE_INPUT_X_VALUES_WHEN_THERE_ARE_MISSING_VALUES
			//------ End SET_SAMPLING_INTERVAL_FOR_YXRANGE_OUTPUT
				XF_THROW(XFERR_FAIL_IN_SET_XYRANGE_DATA);
		/// END CHECK_IF_OUTPUT_AND_INPUT_SHARE_X
			/// END QA70-9715 NEW_NAME_CREATION
			///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
			//if(!_construct_integral_curve(oy, plot, color))
			if(!_construct_integral_curve(oySub, plot))
			///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
				XF_THROW(XFERR_FAILED_ADD_PLOT);
		}
		//---- CPY 6/25/2007 ALLOW_NO_INTEGRAL_CURVE_OUTPUT
		//else
		//	XF_THROW(XFERR_FAIL_IN_SET_XYRANGE_DATA);
		//----
		
		///Zachary 2006-12-11 OUTPUT_ALL_RESULTS_TO_OUTPUT_VARIABLES
		if (x1!=NULL) x1 = result.x1;
		if (x2!=NULL) x2 = result.x2;
		//Sandy 2008-12-29 QA80-12865 ADJUST_INDEXES_RESULT
		int r1, c1, r2, c2;
		Datasheet ds;
		bool	bIsFromNormalBook = is_range_from_normal_book(iySub);
		if(iySub.GetRange(0,  r1,  c1,  r2,  c2, ds) || !bIsFromNormalBook)
		{
			result.i1 = r1+1;
			result.i2 = (r2 == -1) ? nTo-nFrom+1 : r2+1;//offset is 1
			ASSERT(i2>=i1);
			
		}
		if (i1!=NULL) i1 = result.i1;
		if (i2!=NULL) i2 = result.i2;
		//end ADJUST_INDEXES_RESULT
		
		if (area!=NULL) area = result.Area;
		if (x0!=NULL) x0 = result.xPeak;
		if (y0!=NULL) y0 = result.yPeak;
		if (dx!=NULL) dx = result.dxPeak;
		
		//------ Folger 07/23/08 BETTER_OPREATION_OUTPUT_COLUMN_COMMENTS
		if ( oySub )
			_set_output_range_comments(oySub, iySub, type);
		//------
	///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
	}
	///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES	
}

//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 integ1_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return integ1_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	bool bIsChangingPlot = lstrcmpi(lpcszNodeName, "plot") == 0? true:false;
	
	int init = GETNE_ON_INIT;
	int the = GETNE_ON_THEME;
	///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	//if(nEventID == GETNE_ON_INIT || nEventID == GETNE_ON_THEME || bIsChangingPlot)
	//	_update_plot_show(trGetN);
	///end KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	
	//if(nEventID == GETNEVENT_ON_THEME)
		//trGetN.color.Show = trGetN.plot.Show = false;
	//
	int nErr = CER_NO_ERROR;
	
	///Cheney 2007-6-7 ADD_AN_ERR_CHECK_FUNC
	//if(get_input_xyrange_num(trGetN.iy) != 1)
		//nErr = CER_NOT_ONE_XYRANGE;
	//
	//if(nErr == CER_NO_ERROR && 0>= get_input_xyrange_data_size(trGetN.iy))
		//nErr = CER_NO_DATA;
	nErr = _check_err_condition(trGetN);
	///end 	ADD_AN_ERR_CHECK_FUNC
	
	/*
	///Zachary 	12/13/06 MAKE_OUTPUT_XYRANGE_OPTIONAL
	int nYoType = get_xyrange_type(trGetN.oy); 
	_update_plot_show(trGetN, nYoType, nErr);
	/// End MAKE_OUTPUT_XYRANGE_OPTIONAL
	
	int nyoUse = -1, nx1Use = -1, nx2Use = -1, ni1Use = -1, ni2Use = -1, nareaUse = -1, ny0Use =-1, nx0Use = -1, ndxUse = -1;
	trGetN.oy.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nyoUse);
	trGetN.x1.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nx1Use);
	trGetN.x2.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nx2Use);
	trGetN.i1.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, ni1Use);
	trGetN.i2.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, ni2Use);
	trGetN.area.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nareaUse);
	trGetN.y0.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, ny0Use);
	trGetN.x0.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, nx0Use);
	trGetN.dx.GetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, ndxUse);
	
	if (nErr == CER_NO_ERROR && nyoUse + nx1Use + nx2Use + ni1Use + ni2Use + nareaUse + ny0Use + nx0Use + ndxUse == 0)
		nErr = CER_SUPPRESS_ALL_OUTPUT;	
	*/
	
	if(nErr != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErr;
		///Arvin 07/30/07 WRONG_ERR_MASSAGE
		if(nErr == CER_DATA_TOO_FEW)
		{
			strErrMsg += ":";
			strErrMsg += MIN_INPUT_DATA_NUMBER;
		}
		///end WRONG_ERR_MASSAGE
	}
	
	return true;

}

int integ1_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 integ1_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	//------ fisher 11/16/07 ADD_MAP_ID_TO_CHM
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_integ1);
	
	/*
	///Zachary 03/04/07 OUTPUT_A_SINGLE_Y_VECTOR_FOR_INTEGRATE
	if ((dwCntrl & LTXF_FROM_GUI_MENU)||(dwCntrl&LTXF_FROM_GUI_PROMPT)||(dwCntrl&LTXF_CHANGE_PARAM))
	{ //variable integy only availabe from LT script and do not be shown in the dialog.
			trGetN.integy.Show = false;
	}
	*/
	/// end OUTPUT_A_SINGLE_Y_VECTOR_FOR_INTEGRATE
	///Arvin 08/16/07 QA70-10073 KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	//if ((dwCntrl&LTXF_CHANGE_PARAM))
	if ((dwCntrl&LTXF_CHANGE_PARAM) || (dwCntrl&LTXF_FROM_AUTO_UPDATE))
	///end 	KEEP_OUTPUT_CURVE_CUSTOMIZATION_AFTER_RECALCULATE_FOR_XF
	{	
		//trGetN.plot.nVal = 0;	
		//trGetN.color.Enable = trGetN.plot.Enable = false;	/// USE_P_OPTION_STRING
	}
	
	///Cheney 2007-6-7 ADD_AN_ERR_CHECK_FUNC
	///Cheney 2007-6-14 PROCEED_WITH_DLG_SHOULD_IF_ERR
	//if(0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && _check_err_condition(trGetN) != CER_NO_ERROR)
	if(0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU)
		&& _check_err_condition(trGetN) != CER_NO_ERROR)
	///end PROCEED_WITH_DLG_SHOULD_IF_ERR
		nRet = XFEVT_PROCEED_WITH_DLG;	
	///end ADD_AN_ERR_CHECK_FUNC
	
	///------ Folger 08/02/10 ORG-672 INTEG1_SUPPORT_MULTIPLE_XYRANGES
	if( is_xf_before_execute_body(nGetNDialog, dwCntrl) )
	{
		prepare_multixy_output_tree(trGetN.iy, trGetN.oy);
	}
	///------ End INTEG1_SUPPORT_MULTIPLE_XYRANGES
	
}
//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 integ1_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
