#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	mode_val,
	mode_beg,
	mode_end,
	mode_low,
	mode_high,
};

//--------------- Modification Log -------------------
//CPY 8/19/08 QA70-11961 DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X



class XYDataForTranslate
{
public:
	XYDataForTranslate(XYRange& iy)
	{
		m_x0 = m_xinc = 1;
		m_bMinMaxCalc = false;
		m_nYmin= m_nYmax = -1;
		
		iy.GetXColumn(m_x);
		iy.GetYColumn(m_y);
		int c1, c2;
		iy.GetRange(0, m_r1, c1, m_r2, c2, m_wks); 
		m_daty.Attach(m_y);
		if(IsEvenSampleInterval())
		{
			m_y.IsEvenSampling(&m_x0, &m_xinc);
			//---- CPY 8/19/08 QA70-11961 DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X
			iy.GetPlot(m_dp,0 );
			if(m_dp && !(m_dp.GetSpecialFlags() & 0x01)) // 0x01 = x0 disconnected from col, 0x02 = xInc disconnected
				m_dp.Detach();
			//----
		}
		else
			m_datx.Attach(m_x);
	}
	bool IsEvenSampleInterval()
	{
		if(m_x)
			return false;
		
		return true;
	}
	double GetX(int nIndex)
	{
		if(IsEvenSampleInterval())
			return getEvenSampleX( nIndex );
		
		return m_datx[nIndex];
	}
	double GetXBegin()
	{
		return GetX(m_r1);
	}
	double GetXEnd()
	{
		int i2 = m_r2;
		if(i2 < 0) // whole range
			i2 = m_y.i2;
		
		return GetX( i2 );
	}
	double GetXAtYMin()
	{
		checkCalcYMinMax();
		return GetX(m_nYmin);
	}
	double GetXAtYMax()
	{
		checkCalcYMinMax();
		return GetX(m_nYmax);
	}
	void ShiftX(double dx) // no undo for now
	{
		if(IsEvenSampleInterval())
		{
			//---- CPY 8/19/08 QA70-11961 DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X
			//m_x0 += dx;
			//m_y.SetEvenSampling(m_x0, m_xinc);
			if(m_dp)
				m_dp.x0 += dx;
			else
			{
				m_x0 += dx;
				m_y.SetEvenSampling(m_x0, m_xinc);
			}
			//---- end DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X
		}
		else
			m_datx += dx;	
	}
private:
	double getEvenSampleX(int nn)
	{
		//---- CPY 8/19/08 QA70-11961 DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X
		if(m_dp)
			return m_dp.x0 + nn * m_dp.xInc;
		//----
		return m_x0 + nn * m_xinc;
	}
	void	checkCalcYMinMax()
	{
		if(m_bMinMaxCalc)
			return;
		//int nMissing = m_daty.GetMinMax(m_dYmin, m_dYmax, &m_nYmin, &m_nYmax);
		int nDatas = 0;
		vector vDataY;
		nDatas = m_daty.GetSubVector( vDataY, m_r1, m_r2 ); // subRange may be selected
		vDataY.GetMinMax( m_dYmin, m_dYmax, &m_nYmin, &m_nYmax );
		m_nYmin += m_r1; //offset is m_r1
		m_nYmax += m_r1;
		m_bMinMaxCalc = true;
	}
private:
	Worksheet 	m_wks;
	Column 		m_x, m_y;
	Dataset 	m_datx, m_daty;
	int			m_r1, m_r2;
	double 		m_x0, m_xinc;
	bool		m_bMinMaxCalc;
	int			m_nYmin, m_nYmax;
	double		m_dYmin, m_dYmax;
	DataPlot	m_dp;//CPY 8/19/08 QA70-11961 DATAPLOT_ALLOWS_X0_SHIFT_FOR_EVEN_SPACED_X
};



void cxt(XYRange& iy, const double& val, const int& mode, double& odx)
{
	
	XYDataForTranslate myData(iy);
	double dx = 0;
	
	switch(mode)
	{
	case mode_val:
		dx = val;
		break;
	case mode_beg:
		dx = val - myData.GetXBegin();
		break;
	case mode_end:
		dx = val - myData.GetXEnd();
		break;
	case mode_low:
		dx = val - myData.GetXAtYMin();
		break;
	case mode_high:
		dx = val - myData.GetXAtYMax();
		break;
	default:
		printf("Invalid mode (%d) is specified\n", mode);
		return; // do nothing
	}
	myData.ShiftX(dx);
	if(odx != NULL)
		odx = dx;
	
	
}

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

}

int cxt_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	
	return -1;
	
}
//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 cxt_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

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