#ifndef _IMG2XYZ_DATA_H
#define _IMG2XYZ_DATA_H



#define GO_ROI_NAME     "img2XYZ_ROI_Object"

#define IMG2XYZ_PREVIEW_DATA "img2xyz_data"
#define IMG2XYZ_PREVIEW_GRAPH "img2xyz"

enum{
	ANCHOR_SHAPE_ELLI,
	ANCHOR_SHAPE_RECT,
};





int events_from_img2xyz_go()
{
	return _events_from_img2xyz_go();
}

class OCImg2XYZData : public OCImgROIPreview
{
public:
	
	OCImg2XYZData(MatrixObject& mobj,  LPCSTR lpcstrPreviewPage)
			:OCImgROIPreview(mobj,  lpcstrPreviewPage, EXIST_MATRIX){}

	~OCImg2XYZData():~OCImgROIPreview()
	{
		remove_GraphObjects_with_prefix(m_mlParent, GO_ROI_NAME );
	}

	bool UpdateAnchorShape(int nShape);// int nRadius = 0);
	bool CropROI(XYZRange& xyz);
	bool InitAnchor(TreeNode& tr);
	bool UpdatePreviewData();
	
	bool SetupGraphPreview();
	
	bool GetROIData(MatrixObject& mo);
	bool SaveAnchor(TreeNode& tr);
	
	GraphLayer& CheckGetPreviewGraph()
	{
	
		if(!m_gpPreview.IsValid())
		{
			GraphPage gpPreview();
			gpPreview.Create("Origin");
			gpPreview.Rename(IMG2XYZ_PREVIEW_GRAPH);

			m_gpPreview = gpPreview;
			SetupGraphPreview();
		}
		
		return m_gpPreview.Layers(0);
	}	

	
private:
	bool getRegionXYZ(vector<int>& vx, vector<int>& vy, vector& vz);
	

private:
	Tree m_trAnchor;
	//int m_nAnchorShape;
	//int m_nAnchorRadius;
	
};

bool OCImg2XYZData::SaveAnchor(TreeNode& tr)
{

	return save_anchors_to_tree(m_mlParent, tr, GO_ROI_NAME);
}

bool OCImg2XYZData::SetupGraphPreview()
{
	MatrixLayer  ml = m_dsTempData;
	MatrixObject& mo = ml.MatrixObjects(0);
	
	page_load(m_gpPreview, "IMG2XYZ_WIREFRM");
	GraphLayer gl = m_gpPreview.Layers(0);
 	if(-1 == gl.AddPlot(mo, IDM_PLOT_3D_MESH))
 	{
 		return false;
 	}
 	
 	
 	gl.Rescale();
	return true;
}
bool OCImg2XYZData::UpdatePreviewData()
{
	//vector<int> vX, vY, vZ;
	//
	//if(!getRegionXYZ(vX, vY, vZ))
		//return false;
	//
	//double x0, y0, x1, y1;
	//vX.GetMinMax(x0, x1);
	//vY.GetMinMax(y0, y1);
	
	MatrixLayer  ml = m_dsTempData;
	MatrixObject& mo = ml.MatrixObjects(0);
	
	//Matrix& mat = mo.GetDataObject();
	//Matrix& matI = m_moIntensity.GetDataObject();
	//
	//matI.GetSubMatrix(mat, x0, x1, y0, y1);
	GetROIData(mo);
	
	
	GraphLayer gl = CheckGetPreviewGraph();
	gl.Rescale();
	
	//TreeNode trAnchor;
	save_anchors_to_tree(m_mlParent,m_trAnchor, GO_ROI_NAME);
	//m_trAnchor.AddNode(trAnchor); 
	return true;
}

bool OCImg2XYZData::GetROIData(MatrixObject& mo)
{
	vector<int> vX, vY;
	vector vZ;
	
	if(!getRegionXYZ(vX, vY, vZ))
		return false;
	
	double x0, y0, x1, y1;
	vX.GetMinMax(x0, x1);
	vY.GetMinMax(y0, y1);	
	
	
	Matrix& mat = mo.GetDataObject();
	Matrix& matI = m_moIntensity.GetDataObject();
	
	matI.GetSubMatrix(mat, x0, x1, y0, y1);	
	
	mo.SetXY(x0, y0, x1, y1);
	return true;
}

bool OCImg2XYZData::UpdateAnchorShape(int nShape)//int nShape, int nRadius)
{
	//GraphObject go = m_mlParent.GraphObjects(GO_ROI_NAME);
	//if(!go.IsValid())
		//return false;
		//
	//int X, Y;
	//X = go.X;
	//Y = go.Y;
	
	int nObjectType = s_vnObjectType[nShape];
	update_tree_anchors_object_type(nObjectType, m_trAnchor);
	
	remove_GraphObjects_with_prefix(m_mlParent, GO_ROI_NAME);
	
	//if(!DrawAnchor(m_trAnchor))
		//return false;
	//return save_anchors_to_tree(m_mlParent,m_trAnchor, GO_ROI_NAME);
	return InitAnchor(m_trAnchor);
	
}

bool OCImg2XYZData::InitAnchor(TreeNode& trAnchor)//)
{
	GraphObject go;
	
	if(!trAnchor.IsValid())
		return false;

	remove_GraphObjects_with_prefix(m_mlParent, GO_ROI_NAME);
	if(!read_and_create_anchors_from_tree(m_mlParent, trAnchor, GO_ROI_NAME, go))
	{
		
		int nShape, nRadius, nX, nY;
		nX = m_nCols/2;
		nY = m_nRows/2;
		nRadius = min(m_nCols, m_nRows)/4 ;
			
		//GraphObject go;
		//if(nShape == ANCHOR_SHAPE_RECT)
		//{	
		if( !add_rect(m_mlParent, go, nX-nRadius, nY-nRadius, nX+nRadius, nY+nRadius, INDEX_COLOR_TRANSPARENT,  ATTACH_TO_SCALE, LN_FREE, false,  false) )
			return false;
		//}
		//else
		//{
			//if( !add_ellipse(m_mlParent, go, nX-nRadius, nY-nRadius, nX+nRadius, nY+nRadius, INDEX_COLOR_TRANSPARENT,  ATTACH_TO_SCALE,  false) )
				//return false;			
		//}
			
		go.SetName(GO_ROI_NAME);
		save_anchors_to_tree(m_mlParent,trAnchor, GO_ROI_NAME)
		
	}
	
	set_go_border_color(go, SYSCOLOR_GREEN);
	set_LT_script(go, "events_from_img2xyz_go;" , GRCT_SIZEMOVE);	
	

	
	//m_nAnchorShape = nShape;
	//m_nAnchorRadius = nRadius;
	return true;
}

bool OCImg2XYZData::CropROI(XYZRange& xyz)
{

	if(!xyz.IsValid())
		return false;
	
	vector<int> vX, vY;
	vector vZ;
	
	if(!getRegionXYZ(vX, vY, vZ))
		return false;
	
	xyz.SetData(&vZ, &vY, &vX);
	return true;
}

bool OCImg2XYZData::getRegionXYZ(vector<int>& vx, vector<int>& vy, vector& vz)
{

	GraphObject go = m_mlParent.GraphObjects(GO_ROI_NAME);
	if(!go.IsValid())
		return false;
	
	PolylineGraphObject pgo;
	pgo = go;
	if(!pgo.IsValid())
		return false;
	
	vector vrx, vry; 
	if(0>=pgo.GetPoints(vrx, vry))
		return false;
	
	return m_moIntensity.GetRegionPoints(vrx, vry, vz, vy, vx); 
}


#endif