#ifndef _IMG_L_PROFILE_DATA_H
#define _IMG_L_PROFILE_DATA_H

enum{
	DISPLAY_MODE_OVERLAP = 0,
	DISPLAY_MODE_STACK,
};

enum{
	CHANNEL_MODE_INTENSITY = 0,
	CHANNEL_MODE_RED,
	CHANNEL_MODE_GREEN,
	CHANNEL_MODE_BLUE,
	CHANNEL_MODE_ALL,
};

#define WORKSHEETPAGE_NAME_PROFILE "imgLPData"
#define GRAPH_NAME_PROFILE "imgLProfileGraph"
#define TEMPLATE_NAME_PROFILE_GRAPH "imgLProfile"
#define WKS_X_COL_PREFIX			"A"
#define WKS_INTENSITY_COL_PREFIX	"I"
#define WKS_RED_COL_PREFIX		"Red"
#define WKS_BLUE_COL_PREFIX		"Blue"
#define WKS_GREEN_COL_PREFIX	"Green"

#define STR_ROI_LEFT_NAME		"ROILeft"
#define STR_ROI_RIGHT_NAME		"ROIRight"

#define WORKSHEET_NAME_ROI_INTEGRATE "imgLPIntegrate"
#define WORKSHEET_NAME_ROI_DATA       "imgLPROIData"



///Sandy 2006-12-22 extract the kernel function and move to matdata_utils
/*
///Sandy 2006-12-19 move back from matdata_uitls.h/c since it needs include grobj_utils.h
///---Sim 12-11-2006 GET_IMAGE_LINE_PROFILE
bool get_matrix_line_profile(GraphObject& go, MatrixObject& mo, vector& vxPoints, vector& vyPoints, vector& vIntensity)
{
	if ( !go.IsValid() || !mo.IsValid() )
		return false;
	

	int nWidth = get_thick_line_width(go);
	int nDir = get_thick_line_dir(go);
	
	matrix& mat = mo.GetDataObject();
	int nCols = mat.GetNumCols();
	int nRows = mat.GetNumRows();
	

	convert xy to mat index
	vector vx(2), vy(2);
	if(nDir == LN_HORIZONTAL)
	{
		vx[0] = 0;
		vx[1] = nCols;
		vy[0] = go.Y + ( (double)nWidth/2 );
		vy[1] = go.Y + ( (double)nWidth/2 );
		
	}
	else if(nDir == LN_VERTICAL)
	{
		vy[0] = 0;
		vy[1] = nRows;
		vx[0] = go.X + ( (double)nWidth/2 );
		vx[1] = go.X + ( (double)nWidth/2 );		
	}
	else
	{
		return false;//temp
	}
	
	double dPts;

	switch(nPType)
	{
	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);
	vector vError(nPts);	
	
	
	if(0 == get_matrix_upright_line_profile(mo, dLeft, dTop, dRight, dBottom, vxPoints, vyPoints, vIntensity))
		return true;
	else
		return false;
	

}
///---END GET_IMAGE_LINE_PROFILE

///end 
*/
///end of extracting

class imgLProfileData
{
public:
	imgLProfileData();
	~imgLProfileData();
	//{
		// may need to destroy wks graph if user cancel
	//}
	// called on Init and when nChannelMode is changed, need to resize columns and clean up and remake plots
	// nRefLInes = 1 will indicate one ref line and they are always stored to the left most in the wks
	void ResetAll(int nRefLines, int nNumLines, int nDataSize = 0, int nChannelMode = CHANNEL_MODE_INTENSITY, bool bFirstTime = false);	
	
	//for the given nLineIndex to put results profile data to worksheet
	//lpcszType = "X", "Intensity", "Red" etc, only the 1st char is used
	// nIndex = -1 for 1st ref line
	// nIndex = 0,1,2 for measure lines
	bool NewData(const vector& vData, int nLineIndex, LPCSTR lpcszType);
	void FillXCol(int nIndex, int nSize, double dStart = 0, double dInc = 1, bool bCheckExisting = true); ///---Sim 12-07-2006 FILL_X_COL
	
	//void SetROI(double x1, double x2);
	void UpdateROI(double x1, double x2);
	
	bool NewDisplayMode(int nDispMode)
	{
		return false;
	}
	
	void  GetROILinesX(double& dXofLeft, double& dXofRight);

		
private:
	void cleanUpGraphROI();///---Sim 12-13-2006 CLEAN_GRAPH_ROI
	bool updateIntegrateResult();
	bool checkGetROILine(GraphLayer& gl, GraphObject& go, LPCSTR lpcszName, int nLTindex);
	void constructPlots();
	uint getTotalNumCols()
	{
		uint nn = 0;
		for(int ii = -m_nRefLines; ii < m_nNumLines; ii++)
		{
			nn++;//	m_wks.AddCol(WKS_X_COL_PREFIX + (ii+1));
			vector<string> vs;
			getProfileColNames(ii, vs);
			nn += vs.GetSize();
		}
		return nn;
	}
	void emptyPlots(GraphLayer& gl)
	{
		DataPlot dp;
		while(dp = gl.DataPlots(0))
		{
			dp.Destroy();
		}
	}
	
	bool plotData(GraphLayer& gl, int nCol, int nColor)
	{
		///Sandy 2006-12-11
		//fill shadow
		Curve cROI(m_wksROI, nCol);
		if(!cROI)
			return error_report("imgProfileData found invalid col to make plot");
		int nPlotROI = gl.AddPlot(cROI);
		DataPlot dpROI = gl.DataPlots(nPlotROI);
		plot_change_to_area_graph(dpROI);
		//gl.Rescale();
		///end
		Curve cc(m_wks, nCol);
		if(!cc)
			return error_report("imgProfileData found invalid col to make plot");
		
		int nPlot = gl.AddPlot(cc);
		DataPlot dp = gl.DataPlots(nPlot);
		dp.SetColor(nColor);
		return true;
	}
	int getColor(LPCSTR lpcszType)
	{
		string str = lpcszType;
		if(str.IsEmpty())
			return SYSCOLOR_BLACK;
		switch(str[0])
		{
		case 'R':
			return SYSCOLOR_RED;
		case 'G':
			return SYSCOLOR_GREEN;
		case 'B':
			return SYSCOLOR_BLUE;
		}
		return SYSCOLOR_BLACK;
	}
	int getColIndex(int nLine, LPCSTR lpcszType)
	{
		string str = lpcszType;
		if(str.IsEmpty())
			return -1;
		str.MakeUpper();
		string strPrefix;
		switch(str[0])
		{
		case 'X':
		case 'A': //because of WKS_X_COL_PREFIX
			strPrefix = WKS_X_COL_PREFIX;
			break;
		case 'I':
			strPrefix = WKS_INTENSITY_COL_PREFIX;
			break;
		case 'R':
			strPrefix = WKS_RED_COL_PREFIX;
			break;
		case 'G':
			strPrefix = WKS_GREEN_COL_PREFIX;
			break;
		case 'B':
			strPrefix = WKS_BLUE_COL_PREFIX;
			break;
		default:
			return -2;
		}
		string strName = getColName(strPrefix, nLine);
		Column cc = m_wks.Columns(strName);
		if(cc)
			return cc.GetIndex();
		
		return -3;
	}
	void setupCols(int nLine1 = 0)
	{		
		for(int ii = nLine1; ii < m_nNumLines; ii++)
		{
			string strName = getColName(WKS_X_COL_PREFIX, ii);
			int nCol = m_wks.AddCol(strName);
			m_wks.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_X);
			
			///sandy 2006-12-11 add for ROI wks
			nCol = m_wksROI.AddCol(strName);
			m_wksROI.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_X);	
			///end

			vector<string> vs;
			getProfileColNames(ii, vs);
			for(int jj = 0; jj < vs.GetSize(); jj++)
			{
				nCol = m_wks.AddCol(vs[jj]);
				m_wks.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);
				
				///sandy 2006-12-11 add  for ROI wks
				nCol = m_wksROI.AddCol(vs[jj]);
				m_wksROI.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);
				///end
			}
			

		}
	
		///---Sim 12-13-2006 FIX_INTEGRATE_RESULT_WKS remove
		/*
		int nCol = m_wksInteg.AddCol(WKS_X_COL_PREFIX);
		m_wksInteg.Columns(nCol).SetLongName("ROI Integrated Area");
		m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_X);		
		
		nCol = m_wksInteg.AddCol();
		m_wksInteg.Columns(nCol).SetLongName("ROI Integrated Area");
		m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);
		
		nCol = m_wksInteg.AddCol();
		m_wksInteg.Columns(nCol).SetLongName("Ratio to Reference");
		m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);			
		*/
		///---END FIX_INTEGRATE_RESULT_WKS
	}
	string getColName(LPCSTR lpcszNameBase, int nLine)
	{
		string str;
		if(nLine < 0) // ref line
		{
			nLine = -nLine;
			str = "Ref" + nLine;
		}
		else
			str = (string)(nLine+1);
		
		string strName = lpcszNameBase;
		return strName + str;
	}
	void setupDataWks()
	{
		m_wks.SetSize(-1, 0);
		
		///Sandy 2006-12-11 add
		m_wksROI.SetSize(-1,0);
		m_wksInteg.SetSize(-1,0);
		///end
		
		setupCols(-m_nRefLines);
		
		///---Sim 12-13-2006 FIX_INTEGRATE_RESULT_WKS
		// setup integrate wks
		int nCol = m_wksInteg.AddCol(WKS_X_COL_PREFIX);
		m_wksInteg.Columns(nCol).SetLongName("ROI Integrated Area");
		m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_X);		
		
		vector<string> vs;
		getProfileColNames(0, vs);
		for(int jj = 0; jj < vs.GetSize(); jj++)
		{
			vs[jj].Delete(vs[jj].GetLength()-1);
			
			nCol = m_wksInteg.AddCol();
			m_wksInteg.Columns(nCol).SetLongName("ROI Integrated Area "+vs[jj]);
			m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);
			
			nCol = m_wksInteg.AddCol();
			m_wksInteg.Columns(nCol).SetLongName("Ratio to Reference "+vs[jj]);
			m_wksInteg.Columns(nCol).SetType(OKDATAOBJ_DESIGNATION_Y);			
		}
		///---END FIX_INTEGRATE_RESULT_WKS
	}
	///---Sim 12-13-2006 FIX_UPDATE_INTEGRATE_WKS
	void resizeDataWks()
	{
		int nNumCols = getTotalNumCols();
		m_wks.SetSize(-1, nNumCols);
		m_wksROI.SetSize(-1, nNumCols);
		
		m_wksInteg.SetSize(m_nNumLines + m_nRefLines, -1);
	}
	///---END FIX_UPDATE_INTEGRATE_WKS
	int getProfileColNames(int nLine, vector<string>& vsNames)
	{
		vsNames.SetSize(0);
		switch(m_nChannelMode)
		{
		case CHANNEL_MODE_INTENSITY:
			vsNames.Add(WKS_INTENSITY_COL_PREFIX);
			break;
		case CHANNEL_MODE_RED:
			vsNames.Add(WKS_RED_COL_PREFIX);
			break;
		case CHANNEL_MODE_GREEN:
			vsNames.Add(WKS_GREEN_COL_PREFIX);
			break;
		case CHANNEL_MODE_BLUE:
			vsNames.Add(WKS_BLUE_COL_PREFIX);
			break;
		case CHANNEL_MODE_ALL:
			vsNames.Add(WKS_RED_COL_PREFIX);
			vsNames.Add(WKS_BLUE_COL_PREFIX);
 			vsNames.Add(WKS_GREEN_COL_PREFIX);
			//vsNames.Add(WKS_INTENSITY_COL_PREFIX);
			break;
		}
		for(int ii = 0; ii < vsNames.GetSize(); ii++)
		{
			string stName = getColName(vsNames[ii], nLine);
			vsNames[ii] = stName;
		}
		
		return vsNames.GetSize();
	}
	
private:
	int			m_nChannelMode;
	int			m_nNumLines;
	int			m_nRefLines;
	Worksheet	m_wks;
	///sandy 2006-12-11 add for ROI
	Worksheet 	m_wksROI;
	Worksheet   m_wksInteg;
	//end
	GraphPage	m_gp;
	//----- layer margins
	double		m_dTop;
	double		m_dBottom;
	//-----
};

imgLProfileData::imgLProfileData()
{
	m_nChannelMode = -1;
	m_nNumLines = 0;
	WorksheetPage wpTemp(WORKSHEETPAGE_NAME_PROFILE);
	if(!wpTemp)
	{
		wpTemp.Create("Origin", CREATE_HIDDEN|CREATE_SET_MISSING_IN_MANAGER );
		wpTemp.Rename(WORKSHEETPAGE_NAME_PROFILE);
		wpTemp.SetLongName("Image Profile Data", false);
	}
	m_wks = wpTemp.Layers(0);
	m_wks.SetSize(-1, 0);
	m_wks.SetName("Profile Data");
	
	
	///Sandy 2006-12-11 add for ROI of integrate
	WorksheetPage wpTempROI(WORKSHEET_NAME_ROI_DATA);
	if(!wpTempROI)
	{
		wpTempROI.Create("Origin", CREATE_HIDDEN|CREATE_SET_MISSING_IN_MANAGER );
		wpTempROI.Rename(WORKSHEET_NAME_ROI_DATA);
		wpTempROI.SetLongName("ROI Data", false);
	}
	m_wksROI = wpTempROI.Layers(0);
	m_wksROI.SetSize(-1, 0);
	m_wksROI.SetName("ROI Data");
	
	WorksheetPage wpTempInteg(WORKSHEET_NAME_ROI_INTEGRATE);
	if(!wpTempInteg)
	{
		wpTempInteg.Create("Origin");
		wpTempInteg.Rename(WORKSHEET_NAME_ROI_INTEGRATE);
		wpTempInteg.SetLongName("ROI Integrated Data", false);
	}
	m_wksInteg = wpTempInteg.Layers(0);
	m_wksInteg.SetSize(-1, 0);
	m_wksInteg.SetName("ROI Integrated Data");
	///end

	GraphPage gpTemp(GRAPH_NAME_PROFILE);
	if(!gpTemp)
	{
		gpTemp.Create(TEMPLATE_NAME_PROFILE_GRAPH, CREATE_HIDDEN);
		gpTemp.Rename(GRAPH_NAME_PROFILE);
		gpTemp.SetLongName("Image Profiles", false);
	}
	m_gp = gpTemp;
	
	m_dTop = 2;
	m_dBottom = 6;
}

///---Sim 12-12-2006 DESTROY_GRAPH_PAGE_AND_WORK_SHEET
imgLProfileData::~imgLProfileData()
{
	if( m_wks )
		m_wks.Destroy();
	
	if( m_wksROI )
		m_wksROI.Destroy();
	
	if( m_wksInteg )
		m_wksInteg.Destroy();

	if( m_gp )
		m_gp.Destroy();
}
///---END DESTROY_GRAPH_PAGE_AND_WORK_SHEET


void imgLProfileData::ResetAll(int nRefLines, int nNumLines, int nDataSize, int nChannelMode, bool bFirstTime)
{
	bool bNewChannnelMode = nChannelMode==m_nChannelMode? false:true;
	int nOldNumLines = m_nNumLines;
	int nOldRefLines = m_nRefLines;
	
	int	nNumLineDelta = nNumLines - m_nNumLines;
	m_nChannelMode = nChannelMode;
	m_nNumLines = nNumLines;
	m_nRefLines = nRefLines;
	
	if(bNewChannnelMode)
		setupDataWks();
	else if(nOldRefLines != m_nRefLines || nNumLineDelta != 0)
	{
		///---Sim 12-12-2006 FIX_BUG_OF_CLEAN_ALL
		//if(nOldRefLines == m_nRefLines && nNumLineDelta < 0) // only need to del
			//m_wks.SetSize(-1, getTotalNumCols());
		//else if(nOldRefLines == m_nRefLines)// need to add new cols
		//{
			//setupCols(nOldNumLines);
		//}
		//else
			//setupCols(-m_nRefLines);// resetup all
			
		if ( nOldRefLines != m_nRefLines )
		{
			setupDataWks();
		}
		else
		{
			if(nNumLineDelta < 0) // only need to del
				///---Sim 12-13-2006 FIX_UPDATE_INTEGRATE_WKS
				//m_wks.SetSize(-1, getTotalNumCols());
				resizeDataWks();
				///---END FIX_UPDATE_INTEGRATE_WKS
			else // need to add new cols
				setupCols(nOldNumLines);
		}
		///---END FIX_BUG_OF_CLEAN_ALL
	}
	if(nDataSize > 0) // fill X cols
	{
		for(int ii = -m_nRefLines; ii < m_nNumLines; ii++)
		{
			///---Sim 12-07-2006 FILL_X_COL
			//int nXCol = getColIndex(ii, "X");
			//Dataset dsx(m_wks, nXCol);
			//dsx.Data(0, nDataSize-1);
			FillXCol(ii, nDataSize);
			///---END FILL_X_COL
		}
	}
	if(bFirstTime)
		m_gp.SetShow();
	
	constructPlots();
}
bool imgLProfileData::NewData(const vector& vData, int nLineIndex, LPCSTR lpcszType)
{
	int nCol = getColIndex(nLineIndex, lpcszType);
	if(nCol >= 0)
	{
		FillXCol(nLineIndex, vData.GetSize()); ///---Sim 12-07-2006 FILL_X_COL
		
		Dataset ds(m_wks, nCol);
		ds = vData;
		// update graph scale
		GraphLayer gl = m_gp.Layers(nLineIndex);
		gl.Rescale();
		return true;
	}
	return false;
}

///---Sim 12-07-2006 FILL_X_COL
void imgLProfileData::FillXCol(int nIndex, int nSize, double dStart, double dInc, bool bCheckExisting) // = 0, 1, true
{
	int nXCol = getColIndex(nIndex, "X");
	Dataset dsx(m_wks, nXCol);
	if(!bCheckExisting || dsx.GetSize() != nSize)
		dsx.Data(dStart, dStart+ dInc*(nSize-1), dInc);
}
///---END FILL_X_COL

void imgLProfileData::constructPlots()
{
	if(m_nNumLines + m_nRefLines <1)
	{
		m_gp.SetShow(PAGE_HIDDEN);	
		return;
	}
	m_gp.SetShow();	
	arrange_x_link_layers(m_gp, m_nNumLines + m_nRefLines, m_dTop, m_dBottom, 0, false);
	int nLine = -m_nRefLines;
	foreach(GraphLayer gl in m_gp.Layers)
	{
		emptyPlots(gl);
		vector<string> vs;
		getProfileColNames(nLine, vs);
		for(int ii = 0; ii < vs.GetSize(); ii++)
		{
			int nCol = getColIndex(nLine, vs[ii]);
			plotData(gl, nCol, getColor(vs[ii]));
		}
		nLine++;
	}
	// set full X range to propergate to all other layers
	GraphLayer gl0 = m_gp.Layers(0);
	int nX = getColIndex(-m_nRefLines, "X");
	Dataset dsx(m_wks, nX);
	double x1, x2;
	dsx.GetMinMax(x1, x2);
	gl0.X.From = x1;
	gl0.Y.To = x2;
}

	// when profile ROIRect is updated, call this with the left-right position if profile line is vertical, 
	// top/bottom if horizontal
///Sandy 2006-12-11
//void imgLProfileData::SetROI(double x1, double x2)
void imgLProfileData::UpdateROI(double x1, double x2)
{
	bool bRemove = (x1==NANUM || x2==NANUM)? true:false;
	if(bRemove)
	{
		cleanUpGraphROI();
		m_gp.Refresh();
		return;
	}
	
	GraphLayer gl = m_gp.Layers(0);
	GraphObject goLeft, goRight;
	checkGetROILine(gl, goLeft, STR_ROI_LEFT_NAME, 0);
	checkGetROILine(gl, goRight, STR_ROI_RIGHT_NAME, 1);
	
	goLeft.X = x1;
	goRight.X = x2;		

	///---Sim 12-13-2006 FIX_ROI_DATA_WKS
	///Sandy 2006-12-11 add
	for( int nLine = -m_nRefLines; nLine < m_nNumLines; nLine++ )
	{
		// Set line x data
		int nColX = getColIndex(nLine, WKS_X_COL_PREFIX);
		Dataset dsX(m_wks, nColX);
		
		//copy data from source wks
		vector vSubX;
		dsX.GetSubVector(vSubX, x1, x2);
		
		//add two points to the beginning and the end
		vSubX.InsertAt(0,x1-1);
		vSubX.Add(x2+1);
		
		//fill data to ROI worksheet
		m_wksROI.Columns(nColX).SetType(OKDATAOBJ_DESIGNATION_X);
		Dataset dsx(m_wksROI, nColX);
		dsx = vSubX;
			
		// Set line y datas
		vector<string> vs;
		getProfileColNames(nLine, vs);
		for ( int nChn = 0; nChn < vs.GetSize(); nChn++ )
		{
			int nColY = getColIndex(nLine, vs[nChn]);
			Dataset dsY(m_wks, nColY);
			
			//copy data from source wks
			vector vSubY;
			dsY.GetSubVector(vSubY, x1, x2);
			
			//add two points to the beginning and the end
			vSubY.InsertAt(0,0);
			vSubY.Add(0);
			
			//fill data to ROI worksheet
			m_wksROI.Columns(nColY).SetType(OKDATAOBJ_DESIGNATION_Y);
			Dataset dsy(m_wksROI, nColY);
			dsy = vSubY;
		}
	}
	///---END FIX_ROI_DATA_WKS
	
	updateIntegrateResult();

	//end
}
//bool add_line(Layer& lay, GraphObject& go, double x0, double y0, int nAttach, int nDirection, bool bSpan, bool bPercent, double x1, double y1, int nColor, LPCSTR lpcszName)
// return true only if go is valid when function return
bool imgLProfileData::checkGetROILine(GraphLayer& gl, GraphObject& go, LPCSTR lpcszName, int nLTindex)
{
	go = gl.GraphObjects(lpcszName);
	if(go)
	{
		return true;
	}
	
	double xx = 0;
	int nAttach = 2;// page
	int nDir = 2; // vertical
	int nSpan = 0;
	int nColor = SYSCOLOR_RED;
	if(add_line(gl, go, xx, xx, nAttach, nDir, nSpan, false, 100, 100, nColor, lpcszName))
	{
		set_LT_script(go, "event_update_ROI_rect_from_GraphPage(" + nLTindex + ");" ,GRCT_MOVE);
		return 	move_vline(go, m_dTop, 100-m_dBottom, 50);
	}
	return false;
}


///end

///Sandy 2006-12-11 add for integration
bool imgLProfileData::updateIntegrateResult()
{

	double refArea;
	///---Sim 12-13-2006 FIX_NAME_IN_INTEGRATE_DATA_WKS
	/*
	for(int ii = 0; ii < (m_nNumLines+m_nRefLines) ; ii++)
	{
		int nColX = ii*2;
		int nColY = ii*2+1;
		Dataset dsX(m_wksROI, nColX);
		Dataset dsY(m_wksROI, nColY);
		vector vx = dsX;
		vector vy = dsY;
		//vector vIntegrated;
		ocmath_IntegResult result;
		int nFrom = 0, nTo = vy.GetUpperIndex();
		int nRet = ocmath_integrate(vx, vy, nFrom, nTo, &result);
		if (OE_NOERROR != nRet)
		{
			return false;
		}	
		
		if(ii == 0)
		{
			refArea = result.Area;
			m_wksInteg.SetCell(0, 0, "Ref");
		}
		else
		{
			m_wksInteg.SetCell(ii, 0, "Line"+(string)ii);
		}
		
		m_wksInteg.SetCell(ii, 1, result.Area);
		m_wksInteg.SetCell(ii, 2, result.Area/refArea);
	}
	*/
	int nRowIndex;
	// set line name
	nRowIndex = 0;
	for( int nLine = -m_nRefLines; nLine < m_nNumLines; nLine++ )
	{
		string strNameLine = getColName(WKS_X_COL_PREFIX, nLine);
		strNameLine.Delete(0);// delete character 'A';
		if ( -1 == strNameLine.Find("Ref") )
		{ // it is measure line
			strNameLine.Insert(0, "Line");
		}
		m_wksInteg.SetCell(nRowIndex, 0, strNameLine);
		nRowIndex++;
	}
	
	// set line integrate data
	vector<string> vs;
	getProfileColNames(nLine, vs);
	for ( int nChn = 0; nChn < vs.GetSize(); nChn++ )
	{
		nRowIndex = 0;
		for( int nLine = -m_nRefLines; nLine < m_nNumLines; nLine++ )
		{
			int nColX = getColIndex(nLine, WKS_X_COL_PREFIX);
			int nColY = getColIndex(nLine, vs[nChn]);
			Dataset dsX(m_wksROI, nColX);
			Dataset dsY(m_wksROI, nColY);
			vector vx = dsX;
			vector vy = dsY;
			///Arvin 03/19/07 IMPROVE_CALCULATION_CENTROID_METHOD
			//ocmath_IntegResult result;
			IntegrationResult result;
			///end IMPROVE_CALCULATION_CENTROID_METHOD
			int nFrom = 0, nTo = vy.GetUpperIndex();
			int nRet = ocmath_integrate(vx, vy, nFrom, nTo, &result);
			if (OE_NOERROR != nRet)
			{
				return false;
			}	
			
			if(0 == nRowIndex)
			{
				refArea = result.Area;
			}
			
			m_wksInteg.SetCell(nRowIndex, 1 + nChn*2, result.Area);
			m_wksInteg.SetCell(nRowIndex, 1 + nChn*2 + 1, result.Area/refArea);
			
			nRowIndex++;
		}
	}
	///---END FIX_NAME_IN_INTEGRATE_DATA_WKS

    return true;
}

void  imgLProfileData::GetROILinesX(double& dXofLeft, double& dXofRight)
{
	GraphLayer gl = m_gp.Layers(0);
	GraphObject goLeft, goRight;
	checkGetROILine(gl, goLeft, STR_ROI_LEFT_NAME, 0);
	checkGetROILine(gl, goRight, STR_ROI_RIGHT_NAME, 1);	
	
	dXofLeft = goLeft.X;
	dXofRight = goRight.X;
}

///---Sim 12-13-2006 CLEAN_GRAPH_ROI
void  imgLProfileData::cleanUpGraphROI()
{
	GraphLayer gl = m_gp.Layers(0);
	GraphObject go;
	go = gl.GraphObjects(STR_ROI_LEFT_NAME);
	if (go)
		go.Destroy();
	go = gl.GraphObjects(STR_ROI_RIGHT_NAME);
	if (go)
		go.Destroy();
	
	m_wksROI.ClearData();
	m_wksInteg.ClearData();
}
///---END CLEAN_GRAPH_ROI

#endif // _IMG_L_PROFILE_DATA_H

