#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>

/*------------------------------------------------------------------------------*
 * Modification Log:															*
 *	Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC				*
 *------------------------------------------------------------------------------*/

//put additional include files here
enum {
	ERR_INVALID_MATRIX_LAYER = XF_LOCAL_ERR_BEGIN,
};
//put your own support static functions here
static bool get_profile(MatrixObject& mo, vector& vx, vector& vy, vector& vxPoints, vector& vyPoints, vector& vIntensity, vector& vError, int iDir)
{
	matrixbase& matbase = mo.GetDataObject();
	matrix mat = matbase;
	
	int nCols = mat.GetNumCols();
	int nRows = mat.GetNumRows();

	//convert xy to mat index
	vx += 0.5;
	vy += 0.5;
	
	double dPts;

	switch(iDir)
	{
	case PROJECTION_HOR:
		vector vxDiff;
		vx.Difference(vxDiff);
		vxDiff.Sum(dPts);
		break;
	case PROJECTION_VER:
		vector vyDiff;
		vy.Difference(vyDiff);
		vyDiff.Sum(dPts);
		break;
	case PROJECTION_NONE:
		vector vxDiff;
		vx.Difference(vxDiff);
		vector vyDiff;
		vy.Difference(vyDiff);
		for (int ii = 0; ii < vxDiff.GetSize(); ii++)
		{
			double nx = floor(vxDiff[ii] + 0.5);
			double ny = floor(vyDiff[ii] + 0.5);
			dPts += sqrt(nx*nx + ny*ny);
		}
		break;
	}
	int nPts = floor(dPts + 0.5);
	nPts++;
		
	vxPoints.SetSize(nPts);
	vyPoints.SetSize(nPts);
	vIntensity.SetSize(nPts);
	vError.SetSize(nPts);

	int nRet = ocmath_image_lines_profile(nRows, nCols, mat,
		vx.GetSize(), vx, vy,
		nPts, vxPoints, vyPoints, vIntensity, vError,
		1, INTERP2_NEAREST, iDir);
		
	if (nRet != OE_NOERROR)
	{
		XF_THROW_EX("Xfunction failed, Code = %d", nRet);
	}
	
	static GraphPage gp;
	if (!gp.IsValid())
	{
		/// Kenny 08/25/2009 QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
		//gp.Create("Line");
		gp.Create("Line", CREATE_DEFAULT_OPTIONS | CREATE_ENUM_EXIST_PAGE);
		/// End QA81-14203 RESET_PAGE_NAME_IF_CREATED_FROM_OC
	}
	static Worksheet wks;
	if (!wks.IsValid())
	{
		wks.Create("Origin", CREATE_HIDDEN);
		wks.SetSize(-1, 5);
	}
	Dataset dsX(wks, 0), dsY(wks, 1), dsErr(wks, 2);
	dsX.Data(1, nPts);
	dsY = vIntensity;
	dsErr = vError;
	///*
	Dataset dsX1(wks, 3), dsY1(wks, 4);
	dsX1 = vxPoints;
	dsY1 = vyPoints;
	wks.Columns(3).SetType(OKDATAOBJ_DESIGNATION_X);
	//*/
	GraphLayer gl = gp.Layers(0);
	Curve cv(wks, 0, 1);
	gl.AddPlot(cv, IDM_PLOT_LINE);
	gl.Rescale();

	return true;
}


int imagelinesprofile(const int& dir, EventInfo& ei)
{
	int iRet = 0;
	
	GraphObject go;
	ei.GetParent(go);
	vector vx, vy;
	
	for (int ii = 0; ii < go.GetNumOfNodes(); ii++)
	{
		fpoint ptNode;
		go.GetNode(ii, ptNode);
		vx.Add(ptNode.x);
		vy.Add(ptNode.y);
	}
	
	MatrixLayer ml;
	go.GetParent(ml);
	if (!ml)
	{
		XF_THROW(ERR_INVALID_MATRIX_LAYER);
	}
	ml.SetViewImage(true);
	MatrixObject mo = ml.MatrixObjects(0);
	
	vector vxPoints;
	vector vyPoints;
	vector vIntensity;
	vector vError;
	
	switch( ei.GetEvent() )
	{
	case OE_INIT_ANCHORS:
	case OE_MOVE:
	case OE_RESIZE:
	case OE_GRAPHOBJ_SKEW:
	case OE_GRAPHOBJ_ROTATE:
		get_profile(mo, vx, vy, vxPoints, vyPoints, vIntensity, vError, dir);
		iRet = OCD_MODIFY;
		break;
	}
	
	double dxMin, dyMin, dxMax, dyMax;
	mo.GetXY(dxMin, dyMin, dxMax, dyMax);
	
	//convert mat index space to xyz space for vxPoints, vyPoints.
	
	return iRet;
}

//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 imagelinesprofile_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
