/*------------------------------------------------------------------------------*
 * File Name: Project.h															*
 * Creation: CPY 2/1/2002														*
 * Purpose: Origin C Project Class Header										*
 * Copyright (c) OriginLab Corp.2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007	*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/

 
#ifndef _PROJECT_H
#define _PROJECT_H

#include <data.h>
#include <Graph.h>
#include <Page.h>
#include <Folder.h>

#if _OC_VER > 0x0703
#include <Settings.h>
// #include <OperationManager.h>
// #include <Operation.h>
#endif

/** >Internal Origin Objects
		The Project class provides methods and properties to access many of the objects
		contained in an Origin project file. The Project class includes collections
		of all different page types and collections of loose data sets (data sets not
		in a worksheet column) and of all data sets in the Origin Project file. Several
		methods to get objects active in the Origin project file (such as ActiveCurve,
		ActiveLayer, and ActiveFolder) and a RootFolder property are also available.
		An Origin C Project object is a wrapper object that is a reference to an internal
		Origin project object. Origin C wrapper objects do not actually exist in Origin and
		merely refer to the internal Origin object. Only one project file at a time can be
		open in Origin consequently all Origin C Project objects refer to the same currently
		open project file.
	Example:
		// try to count the total number layers in all graphs in project
		int nCount = 0;
		foreach(GraphPage gp in Project.GraphPages)
		{
			foreach(GraphLayer gl in gp.Layers)
			{
				nCount++;
			}
		}
		out_int("total number of layers=",nCount);
		out_str("");// another blank line 
*/
class Project
{

public:
	/**
		Default constructor. Note that in Origin there can only be one Project open
		at a time, so it is not necessary to attach a Project object (see the example).
		The Origin C Project object is attached and valid by default.
	Parameters:
		None.
	Example:
		// For this example to run, create several windows in Origin
		// (graphs, worksheets, etc).
		void	run_Project()
		{
			PageBase	pg;
			
			// Create a Project object
			Project		proj;
			
			// Loop over all the pages in the project and display their names:
			foreach (pg in proj.Pages)
			{
				out_str(pg.GetName());
			}
		}
		
		// Since a Project object does not need to be initialized, the same function
		// can be written like this, where "Project" is used as a global object:
		void	run_Project()
		{
			PageBase	pg;
			
			// Loop over all the pages in the project and display their names:
			foreach (pg in Project.Pages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Project();
	
	/**
		Collection of all the pages in the project.
	Example:
		// For this example to run, create several windows in Origin
		// (graphs, worksheets, etc).
		void	run_Project_Pages()
		{
			PageBase	pg;
			
			// Loop over all the pages in the project and display their names:
			foreach (pg in Project.Pages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<PageBase> 		Pages;
	
	/**
		Collection of all the worksheet pages in the project.
	Example:
		// For this example to run, create several worksheets in Origin.
		void	run_Project_WorksheetPages()
		{
			WorksheetPage	pg;
			
			// Loop over all the worksheet pages in the project and display their names:
			foreach (pg in Project.WorksheetPages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<WorksheetPage> 	WorksheetPages;
	
	/**
		Collection of all the Note pages in the project.
	Example:
		// For this example to run, create several Notes windows in Origin.
		void	run_Project_Notes()
		{
			Note	pg;
			
			// Loop over all the Note pages in the project and display their names:
			foreach (pg in Project.Notes)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<Note>			Notes;
	
	/**
		Collection of all the matrix pages in the project.
	Example:
		// For this example to run, create several matrices in Origin.
		void	run_Project_MatrixPages()
		{
			MatrixPage	pg;
			
			// Loop over all the matrix pages in the project and display their names:
			foreach (pg in Project.MatrixPages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<MatrixPage>		MatrixPages;
	
	/**
		Collection of all the graph pages in the project.
	Example:
		// For this example to run, create several graphs in Origin.
		void	run_Project_GraphPages()
		{
			GraphPage	pg;
			
			// Loop over all the graph pages in the project and display their names:
			foreach (pg in Project.GraphPages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<GraphPage> 		GraphPages;
	
	/**
		Collection of all the layout pages in the project.
	Example:
		// For this example to run, create several layout pages in Origin.
		void	run_Project_LayoutPages()
		{
			LayoutPage	pg;
			
			// Loop over all the layout pages in the project and display their names:
			foreach (pg in Project.LayoutPages)
			{
				out_str(pg.GetName());
			}
		}
	*/
	Collection<LayoutPage> 		LayoutPages;
	
	/**
		Collection of Names of all the Datasets not attached to a worksheet or a matrix in the current project.
	Example:
		void run_Project_DatasetNames()
		{
			int ii = 1;
			foreach(string strName in Project.LooseDatasetNames)
			{
				printf("Dataset(%d) Name: %s\n",ii++, strName);
			}
		}
	*/
	Collection<string> 		LooseDatasetNames;
	/**
		Collection of Names of all the Datasets in the current project.
	Example:
		void run_Project_DatasetNames()
		{
			int ii = 1;
			foreach(string strName in Project.DatasetNames)
			{
				printf("Dataset(%d) Name: %s\n",ii++, strName);
			}
		}
	*/
	Collection<string> 		DatasetNames;
	
	
	/**
		Gets a PageBase object by index.
	Parameters:
		index = (optional) the 0-offset index of the PageBase object in project, or
				-1 for the active page.
	Returns:
		the index'th PageBase or the active PageBase.
	Example:
		// For this example to run, create at least one window (graph, worksheet, etc.).
		void	run_Project_Pages()
		{
			// Get the first page:
			PageBase	pg = Project.Pages(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	PageBase					Pages(int index = -1);
	
	/**
		Gets a WorksheetPage object by index.
	Parameters:
		index = the 0-offset index of the WorksheetPage object in project.
	Returns:
		the index'th WorksheetPage in project.
	Example:
		// For this example to run, create at least one worksheet.
		void	run_Project_WorksheetPages()
		{
			// Get the first WorksheetPage:
			WorksheetPage	pg = Project.WorksheetPages(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	WorksheetPage				WorksheetPages(int index);
	
	/**
		Gets a Notes window by index.
	Parameters:
		index = the 0-offset index of the Note object in project.
	Returns:
		the index'th Note object in project.
	Example:
		// For this example to run, create at least one Notes window.
		void	run_Project_Notes()
		{
			// Get the first Note in project:
			Note	pg = Project.Notes(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	Note						Notes(int index);
	
	/**
		Gets a Matrix window by index.
	Parameters:
		index = the 0-offset index of the MatrixPage object in project.
	Returns:
		the index'th MatrixPage in project.
	Example:
		// For this example to run, create at least one matrix window.
		void	run_Project_MatrixPages()
		{
			// Get the first MatrixPage in project:
			MatrixPage	pg = Project.MatrixPages(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	MatrixPage					MatrixPages(int index);
	
	/**
		Gets a graph window by index.
	Parameters:
		index = the 0-offset index of the GraphPage object in project.
	Returns:
		the index'th GraphPage in project.
	Example:
		// For this example to run, create at least one graph window.
		void	run_Project_GraphPages()
		{
			// Get the first GraphPage in project:
			GraphPage	pg = Project.GraphPages(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	GraphPage					GraphPages(int index);
	
	/**
		Gets a layout window by index.
	Parameters:
		index = the 0-offset index of the LayoutPage object in project.
	Returns:
		the index'th LayoutPage in project.
	Example:
		// For this example to run, create at least one layout window.
		void	run_Project_LayoutPages()
		{
			// Get the first LayoutPage in project:
			LayoutPage	pg = Project.LayoutPages(0);
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	LayoutPage					LayoutPages(int index);
	/**
		Gets the name of Dataset  which is index'th element in the list.
	Parameters:
		index = A number smaller than the number of datasets in the project. The datasets are enumerated 
				by the order in which they appear in the link list and have no special significance.
	Returns:
		return the name of the dataset. 
	Remark: 
		If index is larger than the number of datasets in the project, DatasetNames(int) generates to an execution error.
	Example:
		void run_Project_DatasetNames(int index)
		{
			string strName = Project.DatasetNames(index);
			printf("Dataset(%d) Name: %s\n",index, strName);

		}
	*/
	string 						DatasetNames(int index);
	/**
		Gets the name of Dataset not attached to a worksheet or a matrix, which is index'th element in the list.
	Parameters:
		index = A number smaller than the number of datasets not attached to a worksheet or a matrix in the project. 
				The datasets are enumerated by the order in which they appear in the link list and have no special 
				significance.
	Returns:
		return the name of the dataset. 
	Remark: 
		If index is larger than the number of datasets in the project, DatasetNames(int) generates to an execution error.
	Example:
		void run_Project_LooseDatasetNames(int index)
		{
			string strName = Project.LooseDatasetNames(index);
			printf("Dataset(%d) Name: %s\n",index, strName);

		}
	*/
	string 						LooseDatasetNames(int index);

	/**
		Gets a PageBase object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the PageBase object with the name name. 
	Example:
		// For this example to run, create a worksheet with the name "Data1".
		void	run_Project_Pages()
		{
			// Get the page by name:
			PageBase	pg = Project.Pages("Data1");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	
	
	PageBase					Pages(LPCSTR name);
	
	/**
		Gets a WorksheetPage object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the WorksheetPage object with the name name. 
	Example:
		// For this example to run, create a worksheet with the name "Data1".
		void	run_Project_WorksheetPages()
		{
			// Get the page by name:
			WorksheetPage	pg = Project.WorksheetPages("Data1");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	WorksheetPage				WorksheetPages(LPCSTR name);
	
	/**
		Gets a Note object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the Note object with the name name. 
	Example:
		// For this example to run, create a Note window with the name "Notes".
		void	run_Project_Notes()
		{
			// Get the page by name:
			Note	pg = Project.Notes("Notes");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	Note						Notes(LPCSTR name);
	
	/**
		Gets a MatrixPage object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the MatrixPage object with the name name. 
	Example:
		// For this example to run, create a matrix with the name "Matrix1".
		void	run_Project_MatrixPages()
		{
			// Get the page by name:
			MatrixPage	pg = Project.MatrixPages("Matrix1");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	MatrixPage					MatrixPages(LPCSTR name);
	
	/**
		Gets a GraphPage object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the GraphPage object with the name name. 
	Example:
		// For this example to run, create a graph with the name "Graph1".
		void	run_Project_GraphPages()
		{
			// Get the page by name:
			GraphPage	pg = Project.GraphPages("Graph1");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	GraphPage					GraphPages(LPCSTR name);
	
	/**
		Gets a LayoutPage object by name.
	Parameters:
		name = pointer to the name of the page.
	Returns:
		the LayoutPage object with the name name. 
	Example:
		// For this example to run, create a layout with the name "Layout1".
		void	run_Project_LayoutPages()
		{
			// Get the page by name:
			LayoutPage	pg = Project.LayoutPages("Layout1");
			
			// Display the page name:
			out_str(pg.GetName());
		}
	*/
	LayoutPage					LayoutPages(LPCSTR name);
		
	
	/**
		The Active Curve in the active layer of the active page(window)
	Remark:
		Dataset, Curve and Matrix are different kinds of objects when compared with other 
		Origin objects. Layers and Pages etc are pure wrapper classes for internal Origin
		objects so that you can make assignment between them and they will still be
		referencing the same internal Origin object. For example, both gg1 and gg2 below
		are the same thing
	
			GraphLayer gg1 = Layer("Graph1");
			GraphLayer gg2;
			gg2 = gg1;// having two reference object to the same internal layer in Origin
		
		On the other hand, Datasets and Curves and Matrix are wrapper for data objects inside
		Origin and the assigment between them are interpreted as arithmetic assignments, so
	
			Curve cc("data1_a", "data1_c");
			Curve dd("data1_a", "data1_d");
			dd = cc;// put all values from Y column of cc into Y column of dd
	
		Due to this reason, you cannot do things like
		
			Curve cc = Project.ActiveCurve();
			
		but rather, you should use Project.ActiveCurve directly or use the "using" notation.
	Parameters:
		None.
	Returns:
		the active Curve object
	Example:
		// For this example to run, create a graph  with at least one dataplot.
		void	run_Project_ActiveCurve()
		{
			using cc = Project.ActiveCurve();
			if(cc.IsValid())
			{
				Dataset xd;
				printf("Active dataset is %s",cc.GetName());
				if(cc.AttachX(xd, FALSE))
					printf(", its corresponding X dataset is %s",xd.GetName());
				
				printf(".\n");
			}
			else
				out_str("There is no active dataset");
		}
	*/
	Curve						ActiveCurve();

#ifdef 	 _CURVE_BASE
	/**
	*/
	curvebase&					ActiveCurveBase();
#endif// _CURVE_BASE
	
	/**
		It returns the active Layer object. The active Layer object corresponds to the
		active layer in the active window (graph, worksheet, matrix, or layout).
	Parameters:
		None.
	Returns:
		The active Layer object.
	Example:
		// For this example to run, create a graph window with one or more dataplots.
		void	run_Project_ActiveLayer()
		{
			GraphLayer	gl = Project.ActiveLayer();
			if(gl)
			{
				printf("The current layer has %d plots\n", gl.DataPlots.Count());
			}
			else
				out_str("There is no active window or it is not a graph window");
		}
	*/
	Layer						ActiveLayer();

	/**
		the root folder of the project.
	Example:
		void	run_Project_RootFolder()
		{
			// Get the root folder:
			Folder		fld = Project.RootFolder;
			
			// Get the name:
			string		strRoot = fld.GetName();
			
			// Display the name:
			out_str(strRoot);
		}
	*/
	Folder						RootFolder;
	
	/**
		Gets the active folder in the project.
	Parameters:
		None.
	Returns:
		the active Folder object.
	Example:
		// For this example to run, create a few folder in the project
		// using Project Explorer. Make one of the new folders active.
		void	run_Project_ActiveFolder()
		{
			// Get the active folder:
			Folder		fld = Project.ActiveFolder();
			
			// Get the name:
			string		strName = fld.GetName();
			
			// Display the name:
			out_str(strName);
		}
	*/
	Folder						ActiveFolder();
	
	/**
		Find the folder that contains the page with the given name, and return the folder.
	Paramaters:
		lpcszWindowName = the name of the page.
	Returns:
		the Folder containing the page with the name lpcszWindowName.
	Example:
		// For this example to run, create a folder in the project and make
		// sure that the folder contains a graph with the name "Graph1".
		void	run_Project_GetFolderWithPage()
		{
			Folder			fld = Project.GetFolderWithPage("Graph1");
			
			if (fld.IsValid())	// if the page was found
			{
				// Display the name of the folder containing the page (window) "Graph1".
				out_str(fld.GetName());
			}
			else		// the page was not found
				out_str("The page was not found!");
		}
	*/
	Folder GetFolderWithPage(LPCSTR lpcszWindowName);
	
	/**
		Find the folder that contains a given page.
	Paramaters:
		page = the page.
	Returns:
		the Folder containing the page.
	Example:
		// For this example to run, create a folder in the project and make
		// sure that the folder contains a graph with the name "Graph1".
		void	run_Project_GetFolderWithPage()
		{
			Page			pg("Graph1");
			
			Folder			fld = Project.GetFolderWithPage(pg);
			
			if (fld.IsValid())	// if the page was found
			{
				// Display the name of the folder containing the page (window) "Graph1".
				out_str(fld.GetName());
			}
			else		// the page was not found
				out_str("The page was not found!");
		}
	*/
	Folder GetFolderWithPage(PageBase &page);
	
	/**
		Set the project's active folder.  Specified path can be relative or absolute and is not case sensitive.
	Parameters:
		lpszPath = the path to the folder to be activated. The path can be absolute, in which
					case it has to start with the '/' character denoting the root folder, and
					each subfolder is separated by a '/' character (example: "/mysub/musubsub")
					or it can be relative to the current active folder, in which case the path
					must not start with '/' (example: "mysub/mysubsub" where "mysub" is the subdolder
					within the current active folder).
	Returns:
		TRUE for success, otherwise FALSE.
	Example:
		// For this example to run, create a subfolder named "MySub" in the project's root folder.
		// Make sure that the root folder is active.
		// After the function executes, "MySub" will be the active folder.
		void	run_Project_ActivateFolder()
		{
			string		strPath = "/MySub";
		
			if (Project.ActivateFolder(strPath))
				out_str("Folder activation succeeded.");
			else
				out_str("Folder activation failed!");
		}
	Return:
		TRUE for success.	
	*/
	BOOL ActivateFolder(LPCSTR lpszPath);
	
	/**
		Gets the name of the project.
	Parameters:
		None.
	Returns:
		the name of the project.
	Example:
		void	run_Project_GetName()
		{
			printf("The name of the project is %s\n", Project.GetName());
		}
	*/
	string						GetName();
	
	/**
		Gets the path of the file corresponding to the project. If the project has never been saved
		before, the path will be empty.
	Parameters:
		None.
	Returns:
		the path to the project file.
	Example:
		// For this example to run, make sure that you have saved the current project
		// at least once, or that the current project has been loaded from a file.
		void	run_Project_GetPath()
		{
			printf("The path of the project is %s\n", Project.GetPath());
		}
	*/
	string						GetPath();
	
	/**
		Open a new project. Current project will be closed and replace with the new one if successful
	Parameters:
		lpcszFilename = Origin project name. OPJ extension must be included with full path, if lpcszFilename=NULL, an empty project will be open, so using NULL
						has the same effect as creating a new project
		bOpenReadOnly = TRUE to open project as ReadOnly. If lpcszFilename is a ReadOnly file, then project will be open as ReadOnly automatically.
	Return:
		TRUE for success, this method will check file existence before attempting to open, so will immediately return FALSE if file does not exist
	Example:
		// For this example to run, make sure that the variable strPathName inside
		// the function is initialized to the pathname of an existing project file. 
		void	run_Project_Open()
		{
			string		strPathName = "c:\\myproject.opj";
			if (Project.Open(strPathName))
				out_str("Project opening succeeded.");
			else
				out_str("Project opening failed!");
		}
	*/
	BOOL Open(LPCSTR lpcszFilename = NULL, BOOL bOpenReadOnly = FALSE);
	
	/**
		Save the active project.
	Parameters:
		lpcszFilename = The path and name of the file to save to.  If NULL then save to the current path using the project's current name.
	Returns:
		TRUE for success, otherwise FALSE.
	Example:
		void	run_Project_Save()
		{
			string		strPathNameToSave = "c:\\myproj.opj";
			
			if (Project.Save(strPathNameToSave))
				out_str("Project saving succeeded.");
			else
				out_str("Project saving failed!");
		}
	*/
	BOOL Save(LPCSTR lpcszFilename = NULL);

	/**
		Test if the active project has been modified since the last saving or loading.
	Parameters:
		None.
	Return:
		TRUE if the active project has been modified else FALSE.
	Example:
		// For this example to run, create a project, save it, and then modify it
		// (for example by modifying the value in a worksheet cell).
		void	run_Project_IsModified()
		{
			if (Project.IsModified())
				out_str("Project has been modified");
			else
				out_str("Project has NOT been modified");
			
			// Now save the project:
			Project.Save();
			
			// Now it must be NOT modifed because we saved it above.
			if (Project.IsModified())
				out_str("Project has been modified");
			else
				out_str("Project has NOT been modified");
		}
	*/
	BOOL IsModified();
	
	/**
		Mark the active project as not modified. This is usually done before exiting
		or before loading another project in order to avoid the prompt asking the user
		to save it.
	Parameters:
		None.
	Returns:
		void
	Example:
		// For this example to run, create a project, save it, and then modify it
		// (for example by modifying the value in a worksheet cell).
		void	run_Project_ClearModified()
		{
			if (Project.IsModified())
				out_str("Project has been modified");
			else
				out_str("Project has NOT been modified");
			
			// Now clear the modified flag:
			Project.ClearModified();
			
			// Now it must be NOT modifed because we cleared it above.
			if (Project.IsModified())
				out_str("Project has been modified");
			else
				out_str("Project has NOT been modified");
		}
	*/
	void ClearModified();

	/**
		Get Drag-and-Drop information for the last dropped file..
	Parameters:
		strWinName = The string that will receive the name of the window that the files were dropped on.  If not dropped on a window then the string will be blank.
		iWinLayer = The index of the window's layer that the files were dropped on.
		iFileIndex = The index of the dropped file currently being handled.
		iFileCount = The number of files that were dropped.
		strFileName = The string that will receive the file name of the dropped file.
	Example:
		void OCTestDragDrop()
		{
			string strWinName, strFileName;
			int iWinLayer, iFileIndex, iFileCount;
			
			BOOL b = Project.GetDragDropInfo(strWinName, iWinLayer, iFileIndex, iFileCount, strFileName);
			if( b )
			{
				printf("Project.DragDropInfo\n");
				printf("    WinName = %s\n", strWinName);
				printf("    Layer   = %d\n", iWinLayer);
				printf("    Index   = %d\n", iFileIndex);
				printf("    Count   = %d\n", iFileCount);
				printf("    FileName= %s\n", strFileName);
			}
		}
	*/
	BOOL GetDragDropInfo(string &strWinName, int &iWinLayer, int &iFileIndex, int &iFileCount, string &strFileName);
	/**
		Check a control window to see if it is currently shown.
	Remarks:
		Origin's control windows are those that you can access from the View menu, like Project Explorer, Script Window etc.
	Parameters:	
		nWinID = Control window's ID, can be one of the followings 
			CWT_PROJECT_EXPLORER, 
			CWT_SCRIPT_WINDOW, 
			CWT_CODE_BUILDER,
			CWT_RESULTS_LOG,
	Examples:
			BOOL bOK = Project.IsVisible(); // return TRUE if Project Explorer is Open.
	*/
	BOOL IsVisible(int nWinID=CWT_PROJECT_EXPLORER);

	/**
		Show/Hide the sepcified control window.
	Parameters:
		nWinID = Control window's ID, can be one of the followings 
			CWT_PROJECT_EXPLORER, 
			CWT_SCRIPT_WINDOW, 
			CWT_CODE_BUILDER,
			CWT_RESULTS_LOG,
		bShow = TRUE, show the window, otherwise, hide the window.	
	Examples:
		// test if Script Window open, hide it if yes
		if(Project.IsVisible(CWT_SCRIPT_WINDOW))
			Project.ShowWindow(CWT_SCRIPT_WINDOW, FALSE);
	*/
	void ShowWindow(int nWinID=CWT_PROJECT_EXPLORER, BOOL bShow=TRUE);  
	/**
	Creates a DataObject& from DataObject name

	Parameters:
		name = name of the DataObject
		
	Returns:
		A refernce to  DataObject (A MatrixObject or Column), if invalid name -- the object is invalid
	Examples:
	void test_Project_GetDataObject()
	{
	   foreach (string strDatasetName in Project.DatasetNames)
	   {
		  DataObject& obj = Project.GetDataObject(strDatasetName);
		  if(obj.IsValid())
		  {
			   printf("Dataset  is  in some wks/matrix\n", strDatasetName);
		  }
		  else
		  {
			   printf("Dataset %s is not in any wks/matrix\n", strDatasetName);
		  }
	   }
	}  
	*/
	DataObject& GetDataObject(LPCSTR name);

	/**
	Get Dataset information
	
	Parameters:
		lpcszDatasetName = name of the Dataset object
		bNeedFolderInfo = get folder info, otherwise not

	Return:
		return value defined in oc_const.h, can be one of the followings
			PGDN_PLOTTABLE = 0x0001,
			PGDN_IN_WKS = 0x0002,
			PGDN_IN_MATRIX = 0x0004,
			PGDN_IS_DATASET = 0x0008, 
			PGDN_LOOSE = 0x0010,
			PGDN_FOLDER = 0x0020,
			PGDN_FOLDER_SUB = 0x0040

	Example:
	void test_Project_GetDatasetInfo()
	{
		DWORD dwInfo;
		foreach (string strDatasetName in Project.DatasetNames)
		{
			dwInfo = Project.GetDatasetInfo(strDatasetName);
			printf("Info(Dataset %s) = %d\n", strDatasetName, dwInfo);  
		}
	}  

	Remarks:
	SeeAlso:
	*/
	DWORD GetDatasetInfo(LPCTSTR lpcszDatasetName, BOOL bNeedFolderInfo = FALSE);

	
#if _OC_VER > 0x0703
	
	/**#
		Finds function in the project by function name, compile and link the file if not ready to be called
	Parameters:
		lpcszFunctionName = name of function to find
		lpcszFileName = Optional, name of file
		bCompileDependents = used only if lpcszFileName is supplied; search dependent files and compile and link them as well 

	Remarks:
		If lpcszFileName is NULL FindFunction looks for function in entire workspace

	Returns:
		Found function
	
	Examples:
		// this code demonstrates how FindFunction may be used
		// to make function call by means of function pointer
		void	AddColumns(Worksheet& wks, int nn)
		{
			if( wks )
			{
				for( int ii = 0; ii < nn; ii++ )
				{
					wks.AddCol();
				}
			}
		}

		typedef void (*FUNCTYPE)(Worksheet& wks, int nn); 
		void myFunction()
		{
			Function fn = Project.FindFunction("AddColumns");
			FUNCTYPE pfn = fn;
			
			// it also can be done in one line:
			//	 FUNCTYPE pfn = Project.FindFunction("AddColumns");
			
			if( pfn )
			{
				Worksheet wks;
				wks.Create();
				pfn(wks, 5);
			}
		}
	*/
	Function FindFunction(LPCSTR lpcszFunctionName, LPCSTR lpcszFileName = NULL, BOOL bCompileDependents = FALSE);
	
	/**#
	*/
	OriginSettings Settings;
	
	/**#
	Loads and compile OriginC file
	Parameters:
		lpcszFileName = name of file to load and compile
		
	Remarks:	
		Possible values for result:
			0, Compiled successfully
			1, File not found
			2, Compilation failed
			3, File is found but can not be loaded
			4, Unable to load and compile internal.c
			5, File is already loaded and compiled
			7, Unknown error
	Returns:
		TRUE if compilation either successful or not needed
		FALSE otherwise
	Example:
		Project.Compile("c:\test.c");
	*/
	BOOL	Compile(LPCSTR lpcszFileName, int* lpResult = NULL);
	
	/**#
	Loop over all wks and matrix and call its Reset method.
	Parameters:
		bReduceWksSize =  if True, will reset worksheets to 30 rows
		bReduceMatrices = if True, will reduce all matrices to 2x2
	Returns:
		TRUE if reset successful
		FALSE otherwise
	Example:
		Project.Reset();
	*/
	BOOL	Reset( BOOL bReduceWksSize = TRUE, BOOL bReduceMatrices = TRUE );
	

	/**#
	Do the same as LabTalk: run -p au; wait for autoupdate to finish
	Parameters:
	Returns:
		TRUE if successful, FALSE otherwise
	Example:
		Project.Run();
	*/
	bool		Run();

	/**
	Retrieves Origin object given the object unique ID
	Paramteres:
		uid - ID of object
	Return:
		OriginObject if object with unique ID equal to uid passed to function exists
	Example:
		void run_GetObject()
		{
			WorksheetPage wks("Data1");
			UINT uID = wks.GetUID(TRUE);
			
			Page  pg;
			pg = (Page)Project.GetObject(uID);	
			out_str(pg.GetName());
		}
	*/
	OriginObject		GetObject(UINT uid);

	/**
		Begin undo block. After this call any undoable action belongs to the same block.
		Do not call it directly, use UndoBlock class instead.
	Parameters:
		None.
	Returns:
		None.
	*/
	void		UndoBlockBegin();

	/**
		End undo block.
		Do not call it directly, use UndoBlock class instead.
	Parameters:
		None.
	Returns:
		None.
	*/
	void		UndoBlockEnd();

	/**
		Gets current undo block identifier (ID).
	Parameters:
		None.
	Returns:
		Current undo block ID.
	*/
	int			UndoBlockId();

	/**
		Undo the last block.
	Parameters:
		None.
	Returns:
		None.
	*/
	int			Undo();
	
	/**
		Create new theme.
	Parameters:
		None.
	Returns:
		Tree.
	*/
	Tree		CreateNewTheme();

	/**
		Updates data plot limits.
	Parameters:
		tn - tree node as input/output
	Returns:
		TRUE if success, FALSE if failure
	*/
	BOOL		UpdateDataPlotLimits(TreeNode& tn);

	/**
		Updates layer rescale.
	Parameters:
		tnDP - tree node as input which has dataplots
		tnLayer - tree node as input/ouput has layer settings and rescale property
	Returns:
		TRUE if success, FALSE if failure
	*/
	BOOL		UpdateLayerRescale(TreeNode& tnDP, TreeNode& tnLayer);
	
	/**
		It provides all the columns (by names or prefixes) that are common between the worksheets whose names are supplied. 
		If only one worksheet is supplied, all its columns are returned.
	Parameters:
		worksheets = [in] the names of all the worksheets to consider. They are in the form WksPageName or WksPageName!WksLayerName
		columnNames = [out] the names of all the common columns. There are certain restriction on which columns should be considered "common enough" to be included.
		columnLabels = [out] the labels from the 1st worksheet for the corresponding columns
		bKeepOrder = TRUE if common columns must follow same order as in the first worksheet, FALSE if the order of columns are not important
	Returns:
		TRUE if successful, FALSE otherwise
	Example:
		void run_GetCommonColumns()
		{
			vector<string>  wksNames = {"Data1","Data2"};
			vector<string>  colNames;
			vector<string>  colLabels;
			
			BOOL bRet = Project.GetCommonColumns(wksNames, colNames, colLabels, FALSE);
		}
	*/
	BOOL  GetCommonColumns(const vector<string> &worksheets, vector<string> &columnNames, vector<string> &columnLabels, BOOL bKeepOrder = FALSE);

	/**#
			Given a plot type, like IDM_PLOT_LINE, return an array of integers containing all possible column plot designations.
		Parameters:
			nPlotType = [in] the plot type, general plot ID, can be more then the internal basic plot type id
			dwAuxTypeInfo = [in] cntrl info about the internal details of the plot type
			lpcszColPattern = [in] internal pattern to represent the col designations
			vplotdesig= [out] the array integers from the following enumeration:
				enum {
					COLDESIG_X = 1,
					COLDESIG_Y,
					COLDESIG_Z,
					COLDESIG_LABEL,
					COLDESIG_XERROR,
					COLDESIG_YERROR,
					COLDESIG_YPLUSERROR,
					COLDESIG_YMINUSERROR,
					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
				};
		Return:
			TURE if success, FALSE if nPlotType is invalid or inconsistent with other arguments
		Example:
			void run_GetPlotDesignations()
			{
				DWORD dwAuxTypeInfo;
				DWORD dwAuxPlotInfo;
				string strColPattern;
				
				int nPlotID = IDM_PLOT_LINE;
				int nRet = Project.GetPlotTypeInfo(nPlotID,dwAuxTypeInfo,dwAuxPlotInfo,strColPattern);
				
				vector<uint> vplotdesig;
				BOOL bRet = Project.GetPlotDesignations(nPlotID, dwAuxTypeInfo, strColPattern, vplotdesig);
				
				nRet = Project.CheckPlotDesignations(nPlotID,dwAuxTypeInfo,strColPattern,vplotdesig);
			}
	*/
	BOOL    GetPlotDesignations(int nPlotType, DWORD dwAuxTypeInfo, LPCTSTR lpcszColPattern, vector<uint> &vplotdesig);
	
	/**#
			Given a plot id, like ID_PLOT_DOUBLEY, return the internal plot type like IDM_PLOT_LINE.
 		Parameters:
			nPlotID	= [in] typically resource ID in menu
			dwAuxTypeInfo = [out] this is internal flags that is needed for other functions like  GetPlotDesignations
			dwAuxPlotInfo = [out] this is internal flags that is usful when making the plot
			strColPattern = [out] string in the form of "XY" to indicate the typical plot designation combinations
		SeeAlso:
			GetPlotDesignations
	*/		
	int		GetPlotTypeInfo(int nPlotID, DWORD& dwAuxTypeInfo, DWORD& dwAuxPlotInfo, string& strColPattern);

	/**#
	         Given a plot type (one of IDM_PLOT_* values), the auxiliary plot type info, a string with col desigs, an array of integers representing plot designations of columns (for those plot types for which the order of columns is important, see #4658, the array of integers will be in the order of columns in worksheet), the arrays of wks. page and layer names, and an array of column names, generate the above tree.
	       Parameters:
	          tr = [out] the tree to be generated.
	          nPlotType = [in] the plot type
	          dwAuxTypeInfo= [in] auxiliary plot type info
	          lpcszColPattern = [in] string in the form of "XY" to indicate the typical plot designation combinations
	          nExVal = [in] extra control info that is used in making a new plot, like to connect data points using spline
	          vpdesig= [in] the array of plot designations (see #4658)
	          vsWksPages = [in] the array of wks. page names.
	          vsLayers = [in] the array of wks. layer names.
	          vsCols = [in] the array of column names corresponding to vpdesig.
			  bNoLimits = [in] prevents calculation of data plot limits
		Returns:
		   one of the values from the following enumeration:
		   enum {
			  MDPT_SUCCESS = 0, 
			  MDPT_INCOMPLETE,  // column designations are not finished for the specified plot type. typically when X or Y is missing 
			  MDPT_WRONG_ORDER // Example: for bubble plots the column that determines the size of symbols must be after the y-column. 
		   };
	   */
	int   MakeDataplotsTree(TreeNode &tr, int nPlotType, DWORD dwAuxTypeInfo, DWORD dwLTPlotInfo, LPCTSTR lpcszColPattern, uint nExVal, const vector<uint> &vpdesig, const vector<string> &vsWksPages, const vector<string> &vsLayers, const vector<string> &vsCols, BOOL bNoLimits);
#endif // _OC_VER > 0x0703


#ifdef _OPERATION_H
	/**
	*/
	OperationBase* 	NewOperation(LPCSTR lpcszClassName, LPCSTR lpcszPath, BOOL bAddToOperationList = TRUE);
	
	/**
	*/
	BOOL 		DeleteOperation(OperationBase* op, BOOL bRemoveFromOperationList = FALSE);

	/**
	*/
	OperationBase &  GetOperationObject(UINT uid);
	/**
	*/
	OperationManager	Operations;
#endif //	#ifdef _OPERATION_H

	/**
	  Turn on/off profiling
	  Parameters:
	      bStart = set internal flag to enable/disable profiling for functions.
	      bResetAll = TRUE, to walk all functions to reset profiling info
	  Return:
	    flag value before call.  
	*/
	BOOL Profile(BOOL bStart, BOOL bResetAll = TRUE);
	
	
	/**
	   		Get internal profiling info
	  	Parameters:
	    	vsFuncNames = internal mangled function names
	    	vnNumCalls = number of times corresponding function was called
	    	vdTimes = total amount of time in seconds the corresponding function was called
	  	Return:
	    	FALSE if no profiling info available
	*/
	BOOL GetProfileData(vector<string>& vsFuncNames, vector<uint>& vnNumCalls, vector<double>& vdTimes);
};

#if _OC_VER > 0x0703
/** >Internal Origin Objects
		The UndoBlock class provides safe access to project functions UndoBlockBegin() and
		UndoBlockEnd().
	Example:
		// get format from Graph1 page
		GraphPage pageSrc("Graph1");
		Tree tree;
		tree = pageSrc.GetFormat();
		if( tree )
		{
			// get undo block ID before any changes
			int nIDbefore = Project.UndoBlockId();
			
			// better to limit scope of undo block
			{
				// start new undo block and save all changes there
				UndoBlock block;
				
				// apply format to Graph2 page
				GraphPage pageDst1("Graph2");
				BOOL bb = pageDst1.ApplyFormat(tree);
				
				// apply format to Graph3 page
				GraphPage pageDst2("Graph3");
				bb = pageDst2.ApplyFormat(tree);
			}
			
			// get undo block ID after all changes
			int nIDafter = Project.UndoBlockId();
			
			// undo all changes from the added undo block
			Project.Undo();
		}
*/
class	UndoBlock
{
	private:
		UndoBlock()			{Project.UndoBlockBegin();}
		~UndoBlock()		{Project.UndoBlockEnd();}
};
#endif // _OC_VER > 0x0703

#endif //_PROJECT_H
