/*------------------------------------------------------------------------------*
 * File Name: Page_Utils.h														*
 * Creation: July 25, 2003														*
 * Purpose: Declare page utility functions										*
 * Copyright (c) OriginLab Corp. 2003											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/

#ifndef _PAGE_UTILS_H
#define _PAGE_UTILS_H

enum {
	FILTER_TYPE_UNKNOWN = -1,
	FILTER_TYPE_ASCII = 0,
	FILTER_TYPE_BINARY,
	FILTER_TYPE_USERDEFINED,
	FILTER_TYPE_IGNORE = 100, // use with fuIsApplicable
};
#define IS_FILTER_TYPE(i)		(FILTER_TYPE_ASCII <= (i) && (i) <= FILTER_TYPE_USERDEFINED)

/** >Info Storage
	Get a section from an OriginObject's Info.
	Parameters:
		obj = the OriginObject to get the section from
		trSection = the tree node to put the section into
		lpcszStorageSection = pointer to the storage and section name
	Return:
		If success then true else false
	Example:
		Page pg("Data1");
		if( info_get_section(pg, trSection, "User.Variables") )
		{
		}
*/
bool info_get_section(OriginObject& obj, TreeNode& trSection, LPCSTR lpcszStorageSection);

/** >Info Storage
	Set a section into an OriginObject's Info.
	Parameters:
		obj = the OriginObject to set the section into
		trSection = the tree node containing the section
		lpcszStorageSection = pointer to the storage and section name
	Return:
		If success then true else false
	Example:
		void Run_info_set_section()
		{
			Tree    trSection;
			trSection.user.var.nVal = 1;
			
			Page pg("Data1");
			bool bRet = info_set_section(pg, trSection, "user.var");
		}
*/
bool info_set_section(OriginObject& obj, TreeNode& trSection, LPCSTR lpcszStorageSection);

/** >Info Storage
	Get the value of a variable in a Page's Info section
	Parameters:
		pg = the page to get the value from
		lpcszVarName = pointer to the name of the variable
		strVal = the string to receive the value
		lpcszInfo = pointer to the name of the section.  If NULL then the Variables section is used.
	Return:
		If success then true else false
	Example:
		void Run_page_get_info_var_value()
		{
			string 	strVal;	
			Page pg("Data1");
			bool bRet = page_get_info_var_value(pg,"var",strVal,"user.var");		
		}
*/
bool page_get_info_var_value(Page& pg, LPCSTR lpcszVarName, string& strVal, LPCSTR lpcszStorageSection=NULL);

/** >Info Storage
	Set the value of a variable in a Page's Info section
	Parameters:
		pg = the page containing the variable to set
		lpcszVarName = pointer to the name of the variable
		lpcszVarVal = pointer to the string value
		lpcszInfo = pointer to the name of the section.  If NULL then the Variables section is used.
	Return:
		If success then true else false
	Example:
		void Run_page_set_info_var_value()
		{
			Page pg("Data1");	
			bool bRet = page_set_info_var_value(pg,"var","abc","user.var");	
		}
*/
bool page_set_info_var_value(Page& pg, LPCSTR lpcszVarName, LPCSTR lpcszVarVal, LPCSTR lpcszStorageSection=NULL);

/** >Info Storage
	Get the value of a variable in a Page's Info section
	Parameters:
		pg = the page to get the value from
		lpcszVarName = pointer to the name of the variable
		dVal = the double to receive the value
		lpcszInfo = pointer to the name of the section.  If NULL then the Variables section is used.
	Return:
		If success then true else false
	Example:
		void Run_page_get_info_var_value()
		{
			double 	dVal;	
			Page pg("Data1");
			bool bRet = page_get_info_var_value(pg,"var",dVal,"user.var");		
		}

*/
bool page_get_info_var_value(Page& pg, LPCSTR lpcszVarName, double& dVal, LPCSTR lpcszStorageSection=NULL);

/** >Info Storage
	Set the value of a variable in a Page's Info section
	Parameters:
		pg = the page containing the variable to set
		lpcszVarName = pointer to the name of the variable
		lpcszVarVal = pointer to the string value
		lpcszInfo = pointer to the name of the section.  If NULL then the Variables section is used.
	Return:
		If success then true else false
	Example:
		void Run_page_set_info_var_value()
		{
			Page pg("Data1");	
			bool bRet = page_set_info_var_value(pg,"var",12.25,"user.var");	
		}
*/
bool page_set_info_var_value(Page& pg, LPCSTR lpcszVarName, double dVal, LPCSTR lpcszStorageSection=NULL);

/** >Info Storage
	Get a binary storage from a page into a string.
	Parameters:
		pg = the page containing the binary storage
		lpcszName = pointer to the name of the binary storage
		strVal = the string to receive the value
	Return:
		If success then true else false
	Example:
		void  Run_page_get_storage_str()
		{
			Page pg("Data1");
			string strName = "var";
			string strVal;
			bool bRet = page_get_storage_str(pg,strName,strVal);
			out_str(strVal);
		}
*/
bool page_get_storage_str(Page& pg, LPCSTR lpcszName, string &strValue);

/** >Info Storage
	Set a string into a page as a binary storage
	Parameters:
		pg = the page to contain the binary storage
		lpcszName = pointer to the name of the binary storage
		lpcszVarVal = pointer to the string value
	Return:
		If success then true else false
	Example:
		void  Run_page_set_storage_str()
		{
			Page pg("Data1");
			string strName = "var";
			string strVal = "Testing";
		    bool bRet = page_set_storage_str(pg,strName,strVal);
		}
*/
bool page_set_storage_str(Page& pg, LPCSTR lpcszName, LPCSTR lpcstrValue);


/** >Graph Window
	Get Graphpage's DataPlots contents into a tree
	Parameters:
		pg = the Graph page to get the contents from
		tr = Tree to retrive the contents
	Return:
		If success then return the plot type for the next added plot, or return 0 if error
	Example:
		void Run_gpage_get_plots()
		{	
			Tree tr;
			GraphPage gp("graph1");
			int nRet = gpage_get_plots(gp,tr);
			out_tree(tr);
		}
*/
int	gpage_get_plots(const GraphPage &pg, TreeNode &tr);
// tree attributes that will be added for additional layer info
#define		STR_LAYER_TYPE_BITS				"LayerTypeBits"
#define		STR_ACTIVE_LAYER			"ActiveLayer"	// attribute in resulting tr if applicable

/** >Graph Window
	Get the active layer number from the given page, if page is not the active window, then return -1
	Parameters:
		pg = the page to get the layer number
	Return:
		0-offset layer number if given page is the active window, otherwise return -1
	Example:
		void Run_page_active_layer_index()
		{
			GraphPage gp("Graph1");
			int nIndex = page_active_layer_index(gp);
		}
*/
int page_active_layer_index(Page& pg);

// we need to indicate function to be diff from dataset, but there is no such EXIST type in 
// Origin, so we will steal another EXIST const that is not being used
#define EXIST_FUNC_PLOT		EXIST_PLOT

/** >Graph Window
*/
int	get_plot_type_info(int nPlotID, int nPageType, DWORD dwTargetLayer, DWORD& dwAuxTypeInfo, DWORD& dwAuxPlotInfo, string& strColPattern);


/** >Graph Window
		It adds one or more plots to a graph layer using data from a worksheet.
	Parameters:
		lay=graph layer to add the plot(s) to.
		nPlotType=plot type id
		lpcszWksName=the name of the worksheet to take the data from
		vsCols=vector of strings with the column names to use gtom the worksheet lpcszWksName when creating the plot.
		vpdesig=a vector of integers holding the column designations for each column
				from the vector vsCols. The size of the vector vpdesig must match
				the size of the vector vsCols. The column designations must have the
				values from the following enumeration:
				typedef enum tagPlotDesignationEx {
					COLDESIG_NONE = 0,
					COLDESIG_X = 1,
					COLDESIG_Y,
					COLDESIG_Z,
					COLDESIG_ERROR_OR_LABEL_BEGIN,
					COLDESIG_LABEL = COLDESIG_ERROR_OR_LABEL_BEGIN,
					COLDESIG_XERROR,
					COLDESIG_YERROR,
					COLDESIG_YPLUSERROR,
					COLDESIG_ERROR_OR_LABEL_END,
					COLDESIG_YMINUSERROR = COLDESIG_ERROR_OR_LABEL_END,
					COLDESIG_SIZE,    // for symbol size in bubble plots
					COLDESIG_COLOR,    // for symbol color in scatter color plots
					COLDESIG_VECTOR_ANGLE,  // for vector XYAM plots
					COLDESIG_VECTOR_MAGNITUDE,  // for vector XYAM plots
					COLDESIG_VECTOR_XEND,  // for vector XYXY plots
					COLDESIG_VECTOR_YEND  // for vector XYXY plots
				} PlotDesignationEx;

	Returns:
			1) >0, the total number of plots added; 
			2) =0 means "Failed to add dataplots.";
			3) =-1 means "Cannot create plot tree.";

	Example:
		//		The example creates a graph with a vector XYXY plot.
		//	Parameters:
		//		strWksName=the name of the worksheet to take the data from.
		//		strX1ColName=the name of the column for X1
		//		strY1ColName=the name of the column for Y1
		//		strX2ColName=the name of the column for X2
		//		strY2ColName=the name of the column for Y2
		void	make_XYXY(string strWksName, string strX1ColName, string strY1ColName, string strX2ColName, string strY2ColName)
		{
		
			GraphPage		pg;
			// Create a new graph from the template appropriate for vector XYXY graphs:
			if ( !pg.Create("VectXYXY"))
			{
				out_str("Cannot create page");
				return;
			}
			
			// Get the first layer from the graph:
			GraphLayer		lay = pg.Layers(0);
			if ( !lay )
			{
				out_str("Cannot get graph layer");
				return;
			}
			
			// Build the arrays of the column names and designations.
			vector<string>	vsCols;
			vector<uint>	vpdesig;
			
			vpdesig.SetSize(4);
			vsCols.SetSize(4);
			
			vsCols[0] = strX1ColName;
			vpdesig[0] = COLDESIG_X;
			
			vsCols[1] = strY1ColName;
			vpdesig[1] = COLDESIG_Y;
			
			vsCols[2] = strX2ColName;
			vpdesig[2] = COLDESIG_VECTOR_XEND;
			
			vsCols[3] = strY2ColName;
			vpdesig[3] = COLDESIG_VECTOR_YEND;
			
			int				nNum = add_plots_to_layer(lay, IDM_PLOT_FLOWVECTOR, strWksName, vsCols, vpdesig);
			
			if (0 < nNum)
				lay.Rescale();		// rescale the layer to show all the data points
			
			return;
		}

*/
int		add_plots_to_layer(GraphLayer &lay, int nPlotType, LPCSTR lpcszWksName, vector<string> &vsCols, vector<uint> &vpdesig);


/** >Graph Window
		get info tree from a graph layer by looping through all the data plots in the given layer and find their corresponding workbook info tree
	Parameters:
		gl = [in] GraphicLayer to obtain info tree from
		trNode = [out] TreeNode to receive the Info tree
	Return:
		true for success

	Example:
		Tree tr;
		GraphicLayer gl = Project.ActiveLayer();
		if(page_graph_get_info_tree(gl, tr))
			out_tree(tr);
*/
bool page_graph_get_info_tree(GraphLayer gl, TreeNode& trNode);


#endif // _PAGE_UTILS_H