/*------------------------------------------------------------------------------*
 * File Name: RangeControl.h													*
 * Creation: CPY 5/8/2003														*
 * Purpose: Origin C support the general slider range control in dialogs		*
 * Copyright (c) OriginLab Corp.2003											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/
 
#include <analysis_utils.h>

class RangeControl
{
public:
	void InitControls(Dialog& dlg, int nIDRangeFrom, int nIDRangeTo, int nIDSlider, int nIDCheckFullRange, int nIDXFrom = 0, int nIDXTo = 0, int nIDData = 0)
	{
		m_sliderRange = dlg.GetItem(nIDSlider);
		m_staticRangeFrom = dlg.GetItem(nIDRangeFrom);
		m_staticRangeTo = dlg.GetItem(nIDRangeTo);
		m_checkFullRange = dlg.GetItem(nIDCheckFullRange);
		if(nIDXFrom)
			m_editXFrom = dlg.GetItem(nIDXFrom);
		if(nIDXTo)
			m_editXTo = dlg.GetItem(nIDXTo);
		
		if(nIDData)
			m_staticDataset = dlg.GetItem(nIDData);
		
		m_bShowXvalues = (nIDXFrom > 0 && nIDXTo > 0)? true:false;
		
		m_staticRangeFrom.Text = c_index_to_labtalk_index(m_i1);
		m_staticRangeTo.Text = c_index_to_labtalk_index(m_i2);

		Update();
		if(nIDData)
			m_staticDataset.Text = m_trInput.Range1.Ydata.strVal;
	}
	void Show(bool bShow)
	{
		m_sliderRange.Visible = bShow;
		m_staticRangeFrom.Visible = bShow;
		m_staticRangeTo.Visible = bShow;
		m_checkFullRange.Visible = bShow;
		if(m_bShowXvalues)
		{
			m_editXFrom.Visible = bShow;
			m_editXTo.Visible = bShow;
		}
	}
	//bNeedInit = true to indicate that we need to init trInput with ActiveLayer, and also cuvInput was the active curve already
	//bNeedInit = false will indicate that we already know which Curve and where that we need to do the InitRange, in that case
	//we will need to set that cuvInput as active and activate its layer as well
	//return HWND of the window where we needed to activate our cuvInput, or return NULL if that was not needed
	HWND InitRange(const curvebase& cuvInput, TreeNode& trInput, bool bNeedInit = true)
	{
		m_trInput = trInput;
		HWND	hWndRet = NULL;
		m_bFullRange = set_curve_input(cuvInput, m_trInput, m_i0, m_imax, hWndRet, bNeedInit);
		bool bFullRange = cuvInput.GetSourceRange(m_i0, m_imax)? false:true;
		if(m_trInput.Range1.R1.IsValid())
			m_i1 = m_trInput.Range1.R1.nVal;
		if(m_trInput.Range1.R2.IsValid())
			m_i2 = m_trInput.Range1.R2.nVal;			
		return hWndRet;
	}
	
	// update the GUI controls from outside range setting, or use -1 to simply update to become consistent
	// i1 i2 must be in LabTalk indexing
	void	Update(int i1 = -1, int i2 = -1)
	{
		m_checkFullRange.Check = m_bFullRange;
		
		m_sliderRange.Enable = !m_bFullRange;
		
		if(m_bShowXvalues)
		{
			m_editXFrom.Enable = !m_bFullRange;
			m_editXTo.Enable = !m_bFullRange;
		}
		
		if( m_bFullRange )
		{
			m_staticRangeFrom.Text = GetMinIndex();
			m_staticRangeTo.Text = GetMaxIndex();
		}
		else
		{
			if(i1 > 0)
				m_staticRangeFrom.Text = i1;
			if(i2 > 0)
				m_staticRangeTo.Text = i2;
			
		}
		OnSetFocus(m_bRangeSliderControlsFrom);
		OnRangeChange();
	}
	// LabTalk index for following GetIndex functions
	int	GetFromIndex() {return atoi(m_staticRangeFrom.Text);}
	int GetToIndex() {return atoi(m_staticRangeTo.Text);}
	int GetMinIndex() {return c_index_to_labtalk_index(m_i0);}
	int GetMaxIndex() {return c_index_to_labtalk_index(m_imax);}
	
	bool IsFullRange() {return m_bFullRange;}
	
	void OnSlide()
	{
		//string str = "**************** OnSlide, ";
		//str += m_sliderRange.Position;
		//str.WriteLine(WRITE_COMPILER_OUTPUT);
		
		if( m_bRangeSliderControlsFrom )
			m_staticRangeFrom.Text = m_sliderRange.Position;	
		else
			m_staticRangeTo.Text = m_sliderRange.Position;
		
		OnRangeChange();
	}
	void OnSetFocus(bool bFrom)
	{
		m_bRangeSliderControlsFrom = bFrom;
		
		if(m_bRangeSliderControlsFrom)
		{
			m_sliderRange.RangeMin = GetMinIndex();
			m_sliderRange.RangeMax = GetToIndex() - 1;
			m_sliderRange.Position = GetFromIndex();				
		}
		else
		{
			m_sliderRange.RangeMin = GetFromIndex() + 1;
			m_sliderRange.RangeMax = GetMaxIndex();
			m_sliderRange.Position = GetToIndex();
		}
		if(m_bFullRange)
		{
			m_staticRangeTo.Enable = false;
			m_staticRangeFrom.Enable = false;
		}
		else
		{
			m_staticRangeTo.Enable = !m_bRangeSliderControlsFrom;
			m_staticRangeFrom.Enable = m_bRangeSliderControlsFrom;
		}
	}

	void OnKillFocus(bool bFrom)
	{
		OnRangeChange();
	}
	
	void OnSetFullRange()
	{
		m_bFullRange = m_checkFullRange.Check;
		Update();
	}
	TreeNode GetCurveRange()
	{
		m_trInput.Range1.UseRange.nVal = m_bFullRange? 0:1;
		m_trInput.Range1.R1.nVal = m_i1;
		m_trInput.Range1.R2.nVal = m_i2;
		m_trInput.Range1.X1.dVal = m_x1;
		m_trInput.Range1.X2.dVal = m_x2;
		return m_trInput;
	}
		

private:
	void	OnRangeChange()
	{
		TreeNode tr = m_trInput;

		m_i1 = labtalk_index_to_c_index(GetFromIndex());
		m_i2 = labtalk_index_to_c_index(GetToIndex());
		
		GraphLayer gl = get_graph_layer(m_trInput);
		if( gl )
		{
			if(m_bFullRange)
				gl.SetDataMarkers(-1, -1);
			else
				gl.SetDataMarkers(m_i1, m_i2);
		}
		string strYdata = m_trInput.Range1.Ydata.strVal;
		if(!strYdata.IsEmpty() && m_bShowXvalues)
		{
			string strXdata = m_trInput.Range1.Xdata.strVal;
			Curve cc(strXdata, strYdata);
			m_x1 = Curve_x(&cc, m_i1);// need to be C index
			m_x2 = Curve_x(&cc, m_i2);
			m_editXFrom.Text = m_x1;
			m_editXTo.Text = m_x2;
		}
	}

private:	
	Slider	m_sliderRange;
	Edit	m_editXFrom;
	Edit	m_editXTo;
	Control m_staticRangeFrom;
	Control m_staticRangeTo;
	Button	m_checkFullRange;
	Control m_staticDataset;
	bool	m_bShowXvalues;
	int		m_i0;
	int		m_imax;
	bool	m_bFullRange;
	int		m_i1;
	int		m_i2;
	double	m_x1;
	double	m_x2;
	bool	m_bRangeSliderControlsFrom; // fals means that rtange slider changes begin of range.
	TreeNode	m_trInput;
};

