/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/
#define NUM_DATA_PTS 500
class CRealtimeGraphDlg : public Dialog
{
public:
	CRealtimeGraphDlg() : Dialog("RealTimeGraph", "Graphs")
	{
		
	}
public:
	string s_strWksName;
	
public:	
	virtual int  DoModal(HWND hParent = NULL)
	{
		InitMsgMap();
		int nRet = Dialog::DoModal(hParent);	//Launch the dialog
		return nRet;
	}
	
protected:	
EVENTS_BEGIN
	ON_INIT( OnInitDialog ) 
	ON_SIZE( OnDlgResize )
	ON_BN_CLICKED(IDC_REALTIME_SCOPE, OnStartScope)
	ON_BN_CLICKED(IDC_REALTIME_STRIPT_CHART, OnStartChart)
	ON_DESTROY( OnDestroy )
EVENTS_END

protected:	
	BOOL OnDestroy()
	{
		// Destroy the worksheet window named s_strWksName
		Worksheet wks(s_strWksName);
		if(wks)
			wks.Destroy();
		
		return TRUE;
	}

	
	// *** Initialize Dialog on creation ***
    BOOL OnInitDialog()
	{
		// Attach to first GraphControl
		GraphControl og1 = GetItem( IDC_REALTIME_GRAPH );
		
		// Create Origin graph and add to first GraphControl
		og1.Create( NOCLICK_AXES | NOCLICK_TICKLABEL | NOCLICK_LAYERICON | NOCLICK_DATA_PLOT );
		
		// we will also create our worksheet with XY columns
		Worksheet wks;
		wks.Create(NULL,CREATE_HIDDEN);
		while(wks.DeleteCol(0))	 // Remove all columns in worksheet
			;
		// we don't trust the default template, so del all and recreate
		wks.AddCol();
		wks.AddCol();
		wks.Columns(0).SetType(OKDATAOBJ_DESIGNATION_X);
		wks.Columns(1).SetType(OKDATAOBJ_DESIGNATION_Y);
		wks.SetRange(0, NUM_DATA_PTS-1); // total 500 points
		Dataset aa(wks, 0);
		ASSERT(aa.GetSize() == NUM_DATA_PTS);
		double x1=-10;
		double x2 = 10;
		double inc = (x2-x1)/(NUM_DATA_PTS-1);
		aa.Data(x1,x2,inc);
		Dataset bb(wks, 1);
		bb = 0.5;
		s_strWksName = wks.GetPage().GetName();
		
		// we will also plot this into our graph
		Curve cc(wks, 0, 1);
		GraphPage gp = og1.GetPage(); // Get page
		GraphLayer gl = gp.Layers();  // Get active layer
		gl.AddPlot( cc );
		
		//Set the range of scale
		gl.Y.From = -1;	
		gl.Y.To = 2;
		gl.X.From = x1;
		gl.X.To = x2;
		
		return true;
	}

	// *** Button handler, when user click button ***
    BOOL OnStartScope(Control cButton)
	{
		GraphControl og1 = GetItem( IDC_REALTIME_GRAPH );
		GraphPage gp = og1.GetPage(); // Get page
		gp.LT_execute("set %(1,@D) -an 1"); // make sure data plot is in animate mode
	
		GraphLayer gl = gp.Layers();  // Get active layer
		DataPlot dp = gl.DataPlots(0);
		Dataset bb(dp.GetDatasetName());
		if(!bb)
		{
			ASSERT(FALSE);
			return TRUE;
		}
		dp.SetRange();// set to full range, incase range was not set to full before
		gp.LT_execute("plot -P");
	
		for(int jj = 0; jj < 10; jj++)
		{
			make_peak(jj/9.0, bb);
			
			bb.Update(FALSE, REDRAW_REALTIME_SCOPE);
		}
		return TRUE;
	}


    BOOL OnStartChart(Control cButton)
	{
		GraphControl og1 = GetItem( IDC_REALTIME_GRAPH );
		GraphPage gp = og1.GetPage(); // Get page
		
		gp.LT_execute("set %(1,@D) -an 0"); // make sure data plot is NOT in animate mode
		gp.LT_execute("layer -b RT 1"); // we need to turn on layer realtime drawing support
		
		GraphLayer gl = gp.Layers();  // Get active layer
		DataPlot dp = gl.DataPlots(0);
		Dataset bb(dp.GetDatasetName());
		if(!bb)
		{
			ASSERT(FALSE);
			return TRUE;
		}
		// we need to use the full range of data, but we start out with range reset to 0
		bb.SetSize(NUM_DATA_PTS);// in case it was not setup correctly
		make_peak(0.5, bb); // 
		int nMax = bb.GetSize();
		int	nStepSize = nMax/50;
		bb.SetUpperIndex(-1);
		bb.Update(FALSE, REDRAW_REFRESH);
	
		//gp.LT_execute("plot -P"); // redraw the page
		
		LT_execute("sec -p 0.2");
		
	
		for(int jj = nStepSize; jj < nMax; jj+= nStepSize)
		{
			if(jj > nMax -1)
				jj = nMax -1;
			bb.SetUpperIndex(jj);		
			bb.Update(FALSE, REDRAW_REALTIME_WKS);
			// waste some time here to clearly show the curve moving
			LT_execute("sec -w 0.1");
		}
		return TRUE;
	}

	// make a gaussian shape with peak center around x0 (0-1)*DatasetSize
    void make_peak(double x0, Dataset& bb)
	{
		int nSize = bb.GetSize();
		double xCtr = x0 * nSize;
		double xWidth = 0.05 * nSize;
		double yHeight = 1.2;
		double yNoiseLevel = 0.05;
		
		// we will make a gaussian curve with some noise
		for(int nx = 0; nx < nSize; nx++)
			bb[nx] = yNoiseLevel * rnd() + yHeight * exp(-(nx - xCtr)^2.0 / (PI*xWidth));
	}
		

	// *** Re-size controls on re-sized Dialog ***
	// nType = SIZE_MAXIMIZED, SIZE_RESTORED etc, can be ignored
	// cx and cy are width and height of dialog   
    BOOL OnDlgResize( int nType, int cx, int cy )
	{	
		RECT r1;
		Window wndDlg = GetWindow();
		GraphControl og1 = GetItem( IDC_REALTIME_GRAPH );
		og1.GetWindowRect(&r1);
		wndDlg.ScreenToClient(&r1);
		int nGap = r1.left;
		r1.bottom = cy - nGap;
		r1.right = cx - nGap;
		
		og1.MoveWindow(&r1);
		
		return TRUE;
	}

};