/*------------------------------------------------------------------------------*
 * File Name: GraphPageControl.h												*
 * Creation: CPY 3/8/2004														*
 * Purpose: Graph Control in a dialog, general support							*
 * Copyright (c) OriginLab Corp.2004											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * Frank 7/2/04 v8.0900  		ADD_GETPAGE_FUNCTION							*
 * Frank 8/25/04 v8.0122	QA70-6086	SET_SCALE_NEED_CHECK_INCREMENTBY		*
 * DG 4/22/05 v8.0225 QA70-7581 XYZ_DATARANGE_ADDPLOT							*
 * DG 6/6/05 v8.0246 KEEP_EXIST_WKS												*
 *	CPY 10/3/04 GRAPH_CNTRL_BASE_CLASS_FOR_EMF									*
 * CPY 5/31/07 QA70-9851 TWO_BLANK_BOOKS_AFTER_NLFIT							*
 * Folger 06/05/07 SET_CREATE_SET_MISSING_IN_MANAGER							*
 * Iris 07/05/2007 v8.0655 FIX_SHOW_HIDDEN_GRAPH_IN_EXPGRAPH_XF					*
 *------------------------------------------------------------------------------*/
#ifndef _GRAPH_PAGE_CONTROL_H
#define _GRAPH_PAGE_CONTROL_H


#define PLOT_MODI_OFFSET 	4194404			///DG 6/6/05 set color map for scatter
//----- CPY 10/3/04 GRAPH_CNTRL_BASE_CLASS_FOR_EMF

class DialogViewControl
{
public:
	DialogViewControl(DWORD dwCntrl)
	{
	}
	DialogViewControl()
	{
	}
	~DialogViewControl()
	{
	}
	//virtual PictureControl& GetPict() {return NULL;}

	virtual Datasheet& GetWorksheet() {return NULL;}
	virtual GraphPage GetPage() {GraphPage junk;return junk;} 
};


///jasmine 08/06/10 ORG-389 ADD_MATRIX_IMAGE_PREVIEW
class MatrixViewControl : public DialogViewControl
{
public:
	MatrixViewControl(DWORD dwCntrl): DialogViewControl(dwCntrl)
	{
	}
	MatrixViewControl(): DialogViewControl(0)
	{
	}
	~MatrixViewControl()
	{
		if(m_matrixPage)
			m_matrixPage.Destroy();
	}
	
	void Create(MatrixControl &ctrl)
	{
		m_matrixCntrl = ctrl;
		
		if(m_matrixCntrl)
		{
			m_matrixCntrl.Create(0, "Origin");
			m_matrixPage = m_matrixCntrl.GetPage();
			m_matrixLayer = m_matrixPage.Layers();
			m_matrixLayer.SetViewImage();			
		}
	}
	
	//virtual 
	Datasheet& GetWorksheet()
	{
		if(m_matrixLayer)
			return m_matrixLayer;
		
		return NULL;
	}
	
private:
	MatrixControl		m_matrixCntrl;
	MatrixPage			m_matrixPage;
	MatrixLayer			m_matrixLayer;
};
///End ADD_MATRIX_IMAGE_PREVIEW

class EMFViewControl : public DialogViewControl
{
public:
	EMFViewControl(DWORD dwCntrl): DialogViewControl(dwCntrl)
	{
	}
	EMFViewControl(): DialogViewControl(0)
	{
	}
	~EMFViewControl()
	{
		if(m_graphPage)
			m_graphPage.Destroy();
	}
	void Create(PictureControl &ctrl)
	{
		m_pictCntrl = ctrl;
		/// Iris 07/05/2007 v8.0655 FIX_SHOW_HIDDEN_GRAPH_IN_EXPGRAPH_XF
		//m_graphPage.Create(NULL, CREATE_HIDDEN); // this is used to transfer the metafile only
		m_graphPage.Create(NULL, CREATE_SET_MISSING_IN_MANAGER); // this is used to transfer the metafile only		
		///end FIX_SHOW_HIDDEN_GRAPH_IN_EXPGRAPH_XF
	}
	//virtual
	PictureControl* GetPictPtr() {return &m_pictCntrl;}
	
private:
	PictureControl	m_pictCntrl;
	GraphPage		m_graphPage;
	
};
	
//-----
class GraphPageControl : public DialogViewControl 
{
public:
	//--- CPY 5/20/06 CHANGE_GETN_PREVIEW_TO_DATASHEET_FROM_WKSHEET
	GraphPageControl(DWORD dwCntrl) : DialogViewControl(dwCntrl)
	{
		m_dwOptions = dwCntrl;
	}
	GraphPageControl() : DialogViewControl(0)
	{
		m_dwOptions = 0;
	}
	//---
	~GraphPageControl()
	{
		if(m_bDeleteWorksheet)
		{
			if(m_wks)	///DG 6/6/05 KEEP_EXIST_WKS : add m_bDeleteWorksheet
				m_wks.Destroy();
			if(m_mpPreview)
				m_mpPreview.Destroy();
		}
	}
	
	///Frank 11/04/04 	v8.0159 QA70-6583	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
	//void Create(GraphControl &ctrl, DWORD dwNoClicks, LPCSTR lpcszTemplate = NULL, LPCSTR lpcszDesignations = NULL)
	/// Iris 5/12/2008 QA80-11497-P4 DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
	//void Create(GraphControl &ctrl, DWORD dwNoClicks, LPCSTR lpcszTemplate = NULL, LPCSTR lpcszDesignations = NULL, LPCSTR lpcstrCreateGraphName = NULL, LPCSTR lpcstrWksName = NULL)
	virtual void Create(GraphControl &ctrl, DWORD dwNoClicks, LPCSTR lpcszTemplate = NULL, LPCSTR lpcszDesignations = NULL, LPCSTR lpcstrCreateGraphName = NULL, LPCSTR lpcstrWksName = NULL, LPCSTR lpcstrSharedWksName = NULL)
	///end DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
	///End	CREATE_WITH_TEMP_NAME_AND_SAVE_GRAPH_SETTING_OF_SIMULATE
	{
		string strTemplate = lpcszTemplate;
		if(strTemplate.IsEmpty())
			strTemplate = "Origin";
		
		m_dwNoClicks = dwNoClicks; /// Iris 05/09/08 QA80-11497 ADD_NO_PREVIEW_FOR_LARGR_DATA_SET, remember this value and used in UpdateGraphTemplate
		m_gCntrl = ctrl;
		m_gCntrl.Create(dwNoClicks, strTemplate);
		m_graphPage = m_gCntrl.GetPage();
		m_graphLayer = m_graphPage.Layers(0);
		
		m_bDeleteWorksheet = true; ///DG KEEP_EXIST_WKS
		if(m_dwOptions & XFGSETUP_IMAGEGRAPH_CNTRL)
		{
			/// TD 02-29-2008 QA80-11069 BLOCK_DIRTY_DOC_MORE_WORK
			//m_mpPreview.Create("Origin", CREATE_HIDDEN);
			m_mpPreview.Create("Origin", CREATE_HIDDEN|CREATE_SET_MISSING_IN_MANAGER);
			/// end BLOCK_DIRTY_DOC_MORE_WORK
			m_mlPreview = m_mpPreview.Layers(0);
		}
		else
		{
			/// Iris 5/12/2008 QA80-11497-P4 DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
			string		strSharedWks(lpcstrSharedWksName);
			if( !strSharedWks.IsEmpty() )
			{
				m_bDeleteWorksheet = false;
				WorksheetPage wp(strSharedWks);
				if( wp )
				{
					m_wks=wp.Layers(0);
				}
				else
				{
					error_report("Input invalid shared worksheet name in GraphPageControl::Create");
				}
			}
			else				
			///end DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
			{				
				WorksheetPage wp;
				//------- CPY 5/31/07 QA70-9851 TWO_BLANK_BOOKS_AFTER_NLFIT
				//wp.Create("origin", CREATE_HIDDEN);
				///Folger 06/05/07 SET_CREATE_SET_MISSING_IN_MANAGER
				//wp.Create("origin", CREATE_HIDDEN | CREATE_LOAD_1ST_LAYER_ONLY);
				wp.Create("origin", CREATE_HIDDEN | CREATE_LOAD_1ST_LAYER_ONLY | CREATE_SET_MISSING_IN_MANAGER);
				///End SET_CREATE_SET_MISSING_IN_MANAGER_AND_HIDE_TEMP_PAGE
				//-------
				m_wks=wp.Layers(0);
				if(m_wks)
				{
					string strDesignations = lpcszDesignations;
					if(!strDesignations.IsEmpty())
					{
						m_wks.SetSize(100, strDesignations.GetLength());
						m_wks.SetColDesignations(strDesignations);
					}
					if(lpcstrWksName != NULL)
					{
						wp.Rename(lpcstrWksName);
						wp.SetLongName(lpcstrWksName);
					}
					if(lpcstrCreateGraphName != NULL)
					{
						m_graphPage.Rename(lpcstrCreateGraphName);
						m_graphPage.SetLongName(lpcstrCreateGraphName);
					}
				}
			}
		}
	}
	
	/// Iris 05/09/08 QA80-11497 ADD_NO_PREVIEW_FOR_LARGR_DATA_SET
	bool UpdateGraphTemplate(LPCSTR lpcszTemplate)
	{
		if(m_graphPage)
		{
			page_load(m_graphPage, lpcszTemplate, m_dwNoClicks);
			m_graphLayer = m_graphPage.Layers(0); // after load none preovew template and load back to Contour tempate, m_graphLayer is invalid
			return true;
		}
		return false;
	}
	///end ADD_NO_PREVIEW_FOR_LARGR_DATA_SET
	
	int AddPlot(int nXCol = 0, int nYCol = 1, int nPlotType = IDM_PLOT_LINE, bool bRescale = true)
	{
		Curve cuv(m_wks, nXCol, nYCol);
		int nPlot =  m_graphLayer.AddPlot(cuv, nPlotType);
		if(nPlot >= 0)
		{
			if(bRescale)
				m_graphLayer.Rescale();
			return nPlot;
		}
		return -1;
	}
	///DG XYZ_DATARANGE_ADDPLOT
	int AddPlot(DataRange& dr, int nPlotID = IDM_PLOT_SCATTER, uint dwCntrl = GAP_USE_TEMPLATE)
	{
		return m_graphLayer.AddPlot(dr, nPlotID, dwCntrl);
	}
	int	AddPlot(MatrixObject& matObj, int nPlotID = IDM_PLOT_MATRIX_IMAGE)
	{
		return m_graphLayer.AddPlot(matObj, nPlotID);
	}
	bool SetScatterColorMap(int nPlotIndex, int nYData, int nColorMap)
	{
		DataPlot dp = m_graphLayer.DataPlots(nPlotIndex); 
		Tree tr; 
		tr = dp.GetFormat(FPB_ALL, FOB_ALL, true, true);
		//colormap not yet available at this point
		tr.Root.Symbol.EdgeColor.nVal = PLOT_MODI_OFFSET + (nColorMap - nYData);
		dp.ApplyFormat(tr, true, true);
		return true;
	}
	bool RemoveAllPlots()
	{
		int nPlots = m_graphLayer.DataPlots.Count();
		bool bRet=true;
		for(int ii = 0; ii < nPlots; ii++)
			bRet &= m_graphLayer.RemovePlot(0);
		return bRet;
	}
	void SetPlotActive(int nPlotIndex)
	{
		DataPlot dp = m_graphLayer.DataPlots(nPlotIndex);
		if(dp)
			dp.SetActive();
	}
	void SetData(vector &vec, int nCol)
	{
		int nCols = m_wks.Columns.Count();
		for(int ii=nCol-nCols; ii >= 0; ii--)
			m_wks.AddCol();
		
		Dataset ds(m_wks, nCol);
		ds = vec;
	}
	bool GetData(vector &vec, int nCol)
	{
		Dataset ds(m_wks, nCol);
		if(!ds)
			return false;
		
		vec.SetSize(ds.GetSize());
		vec = ds;
		return true;
	}
	//-----  CPY 5/23/05
	//	GraphObject &GetGraphObject(LPCSTR lpcszName)
	//{
	//	return m_graphLayer.GraphObjects(lpcszName);
	GraphObject &GetRectObject(LPCSTR lpcszName, bool bCreateIfNotFound = false)
	{
		GraphObject gr = m_graphLayer.GraphObjects(lpcszName);
		if(gr)
			return gr;
		if(bCreateIfNotFound)
		{
			gr = create_rect_object(m_graphLayer);
			gr.SetName(lpcszName);
		}
		return gr;
	}
	//-------
	Worksheet& GetWks()	//now add 3d surface plot must use DataRange
	{
		return m_wks;
	}
	bool IsValid()
	{
		return m_graphLayer.IsValid();
	}
	void Refresh()
	{
		m_graphPage.Refresh();
	}
	bool UpdateLabel(LPCSTR lpcszObject, const string& strLabel, int x = 10, int y = 5)
	{
		return page_insert_label(m_graphLayer, strLabel, lpcszObject, x, y);
	}
	virtual Datasheet& GetWorksheet()
	{
		if(m_mlPreview)
			return m_mlPreview;
		
		return m_wks;
	}
	void SetWorksheet(Worksheet& wks)
	{
		if(wks)
		{
			/// Iris 5/12/2008 QA80-11497-P4 DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
			//if(m_wks)
			//	m_wks.Destroy();
			
			///end DESTROY_WKS_MISS_IN_PROJECT_WILL_RESIZE_OTHER_WKS
			
			m_bDeleteWorksheet = false; ///DG KEEP_EXIST_WKS
			
			m_wks=wks;
		}
	}
	///end XYZ_DATARANGE_ADDPLOT
	bool RemovePlot(int nPlot)
	{
		return m_graphLayer.RemovePlot(nPlot);
	}
	bool GetData(Dataset& dat, int nCol)
	{
		return dat.Attach(m_wks, nCol);
	}
	bool SetScale(double dMin, double dMax, bool bXscal = true)
	{
		if(bXscal)
		{
			m_graphLayer.X.From = dMin;
			m_graphLayer.X.To = dMax;
		}
		else
		{
			m_graphLayer.Y.From = dMin;
			m_graphLayer.Y.To = dMax;
		}
		return true;
	}
	bool PlotRescale()
	{
		m_graphPage.Refresh();
		return m_graphLayer.Rescale();
	}
	/*
	///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
	///--These two function were designed to set formulat to column, but not use now, so comment
	bool SetFormular( string &strFormula, int nXcol = 0, int nYcol = 1 )
	{
		string strXColName; 
		strXColName = m_wks.Columns( nXcol ).GetName();
		strXColName.Format("Col(%s)", strXColName );
		
		if(0 == strFormula.Replace("x", strXColName))
		strFormula.Replace("X", strXColName);
		
		string strFormulaApply = strFormula.GetToken(1,'=');
		if( strFormulaApply.IsEmpty() )
		{
			return m_wks.Columns( nYcol ).SetFormula(strFormula);
		};	
		return m_wks.Columns( nYcol ).SetFormula(strFormulaApply);
		
	}
	
	bool UpdateFormula( int nYcol = 1 )
	{
		if( m_wks.Columns(nYcol).ExecuteFormula())
		{
			m_wks.UpdateOrigin();
			return true;
		};
		return false;
	}
	///	End			SIMILATE_UPDATE_SCALE_METHOD

	*/
	int AddColumns( int nNewColumns = 1, bool bRemoveOld = false, int nSetXcolType = OKDATAOBJ_DESIGNATION_X  )
	{
		int nColunmIndex;
		if( !m_wks.IsValid() )
		{
			return false;
		};
		if( bRemoveOld )
		{
			while( m_wks.DeleteCol(0) );
		};
		for( int i = 0; i < nNewColumns ; i++ )
		{
			nColunmIndex = m_wks.AddCol();
		};
		m_wks.Columns(0).SetType( nSetXcolType );
		return nColunmIndex;
	}
	///--Frank 8/27/04 	v8.0122				SIMILATE_UPDATE_SCALE_METHOD
	bool SetXAxisScale(double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1)
	{
		if(!m_graphLayer.IsValid())
		{
			return false;
		}
		Axis xa = m_graphLayer.XAxis;

		Tree tr;
		tr = xa.Scale;

		if(!setScale(tr, dFrom, dTo, nType , nRescaleType))
			return false;
		xa.Scale = tr;
		tr = xa.Scale;
		double dTest = tr.From.dVal;
		double dTest1 = tr.To.dVal;
		return true;			
	}	

	//bool SetYAxisScale(double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1)
	bool SetYAxisScale(double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1, GraphLayer* pLay = NULL)
	{
		///DG 5/18/05 : allow specify another graphlayer to set
		if(NULL == pLay)
		{
			pLay = &m_graphLayer;
		}
		///end
		if(!pLay->IsValid())
		{
			return false;
		}
		Axis xa = pLay->YAxis;
		Tree tr;
		tr = xa.Scale;

		if(!setScale(tr, dFrom, dTo, nType , nRescaleType))
			return false;
		xa.Scale = tr;
		return true;			
	}
	bool setScale(TreeNode &trScaleNode,double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1)
	{
		if(nRescaleType == 0)
		{
			int nIncrementType = trScaleNode.IncrementBy.nVal;
			int	nMajorTicksCount=0;
			TreeNode trMajorTicksCount = trScaleNode.MajorTicksCount;
			if(trMajorTicksCount)
				nMajorTicksCount = trMajorTicksCount.nVal;
			
			if(nIncrementType == 0 )
				nMajorTicksCount = 6;
			
			trScaleNode.MajorTicksCount.nVal = nMajorTicksCount;
			double	dIncre = abs(dTo- dFrom)/( nMajorTicksCount - 1 );
			
			trScaleNode.From.dVal = dFrom ;//- dIncre;
			trScaleNode.To.dVal = dTo ;//+ dIncre;
			trScaleNode.Type.nVal = nType;
			trScaleNode.Rescale.nVal = nRescaleType;
			return true;
		}
		else
			if(nRescaleType == 1)
			{
				///If rescale type is auto, then just set rescale value, not need set other value.
				trScaleNode.Rescale.nVal = nRescaleType;
				return true;
			}		
		return false;
	}
	bool GetYScaleValue(double &dFrom, double &dTo)
	{
		if(!m_graphLayer.IsValid())
		{
			return false;
		}
		Axis xa = m_graphLayer.YAxis;
		Tree tr;
		try
		{
			tr = xa.Scale;
		}
		catch(int nErr)
		{
			return false;
		}
		
		dFrom = tr.From.dVal;
		dTo	= tr.To.dVal;
		
		return true;			
		
	}
	///--End				SIMILATE_UPDATE_SCALE_METHOD
	bool GetAxisScale(TreeNode &trScale, bool bXScale = true)
	{
		if(!m_graphLayer.IsValid())
		{
			return false;
		}
		Axis xa ;	
		if(bXScale)
			xa = m_graphLayer.XAxis;
		else
			xa = m_graphLayer.YAxis;

		trScale = xa.Scale;
		if(!trScale)
			return false;
		return true;			
	}	

	/*
	////---Frank 8/25/04 v8.0122	QA70-6086	SET_SCALE_NEED_CHECK_INCREMENTBY
	bool SetXAxisScale(double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1)
	{
		if(!m_graphLayer.IsValid())
		{
			return false;
		}
		Axis xa = m_graphLayer.XAxis;
		Tree tr;
		tr = xa.Scale;
		double	dIncre = tr.Value.dVal;
		tr.From.dVal = dFrom - dIncre;
		tr.To.dVal = dTo + dIncre;
		tr.Rescale.nVal = nRescaleType;
		tr.Type.nVal = nType;
		xa.Scale = tr;
		return true;
	}	
	bool SetYAxisScale(double dFrom, double dTo, int nType = LINEAR_SPACE, int nRescaleType = 1)
	{
		if(!m_graphLayer.IsValid())
		{
			return false;
		}
		Axis xa = m_graphLayer.YAxis;
		Tree tr;
		tr = xa.Scale;
		double	dIncre = tr.Value.dVal;
		tr.From.dVal = dFrom - dIncre;
		tr.To.dVal = dTo + dIncre;
		tr.Rescale.nVal = nRescaleType;
		tr.Type.nVal = nType;
		xa.Scale = tr;
		return true;
	}	
	*/
	////---End	SET_SCALE_NEED_CHECK_INCREMENTBY
	//Frank 7/2/04 v8.0900  		ADD_GETPAGE_FUNCTION
	GraphPage GetPage()
	{
		return m_gCntrl.GetPage();
	}
	//End
private:
	GraphControl	m_gCntrl;
	//WorksheetPage	m_wksPage;
	Worksheet		m_wks;
	GraphPage		m_graphPage;
	GraphLayer 		m_graphLayer;
	
	bool			m_bDeleteWorksheet;		///DG 6/6/05
	//--- CPY 5/20/06 CHANGE_GETN_PREVIEW_TO_DATASHEET_FROM_WKSHEET
	// the following might need to be moved so can share in XYZ2MatPreviewGraphControl
	MatrixPage				m_mpPreview;
	MatrixLayer				m_mlPreview;
	DWORD					m_dwOptions;
	//---
	DWORD					m_dwNoClicks;/// Iris 05/09/08 QA80-11497 ADD_NO_PREVIEW_FOR_LARGR_DATA_SET

};



#endif //_GRAPH_PAGE_CONTROL_H


