#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
//-------------- modification log ---------------------
// Folger 09/17/09 SAMPLING_INTERVAL_IS_LOST_AFTER_SUBTRACT_LINE
//-----------------------------------------------------
#include <GraphGetPts.h>
#include <event_utils.h>
//put your own support static functions here



void subtract_line(const XYRange& iy, const double& x1, const double& y1, const double& x2, const double& y2, XYRange& oy)
{
	
	if( is_missing_value(x1) ||
		is_missing_value(y1) ||
		is_missing_value(x2) ||
		is_missing_value(y2) )
		XF_THROW(XFERR_INVALID_ARG)
		
	vector vxIn,vyIn;	
	DWORD dwRulesEx = DRR_GET_MISSING | DRR_BAD_WEIGHT_TREATMENT;	
	if(!iy.IsValid() || !iy.GetData(vyIn, vxIn, NULL, 0, dwRulesEx))	
		XF_THROW(XFERR_GET_DATA_FAILED)
	
	double dx = x2-x1;
	if(0==dx)
		XF_THROW(XFERR_INVALID_ARG)
		
	double slope = (y2-y1)/dx;
	vyIn -= y1 + (vxIn - x1) * slope; 
		
	DWORD		dwMatching;
	BOOL		bXShared = oy.IsIntersect(iy, "X", NULL, &dwMatching);
	BOOL		bYShared = oy.IsIntersect(iy, "Y");
	vector* pX = &vxIn;
	if(bXShared) pX = NULL;
	///------ Folger 09/17/09 SAMPLING_INTERVAL_IS_LOST_AFTER_SUBTRACT_LINE
	//if(!oy.SetData(&vyIn, pX))
	if( !set_xyrange_data_ex(oy, &vyIn, pX, 0, iy) ) 
	///------ End SAMPLING_INTERVAL_IS_LOST_AFTER_SUBTRACT_LINE
		XF_THROW(XFERR_INVLIAD_XY);
	
	if(!bYShared)
		oy.MakePlot(iy);
	
	
}

//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 subtract_line_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return subtract_line_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	return false;

}

int subtract_line_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 subtract_line_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	if(nGetNDialog > 0 && (dwCntrl & LTXF_FROM_GUI_MENU))
	{
		XYRange iy;
		DataPlot dp;
		int nErr = get_graph_input_xyrange(trGetN.iy, dp, iy);
		if(nErr || !dp)
		{
			nRet = XFEVT_ABORT;
			return;
		}
		GraphLayer gl;
		dp.GetParent(gl);
		if(!gl)
		{
			nRet = XFEVT_ABORT;
			return;
		}
		GetGraphPointsEx sp(-1, _L("Select two points to form straight line to be subtracted"));
		sp.SetFollowData(false, 0);
		sp.GetPoints(2, gl);
		vector vx, vy;
		int nn = sp.GetData(vx, vy);
		if(nn < 2)
		{
			gl.Invalidate();
			nRet = XFEVT_ABORT;
			return;
		}
		trGetN.x1.dVal = vx[0];
		trGetN.y1.dVal = vy[0];
		trGetN.x2.dVal = vx[1];
		trGetN.y2.dVal = vy[1];
		nRet = XFEVT_PROCEED_NO_DLG;
	}
	
}
//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 subtract_line_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
