/*------------------------------------------------------------------------------*
 * File Name: sys_utils.h				 										*
 * Creation: CPY 3/13/02														*
 * Purpose: Basic and common utilities for general Origin C development.		*
 * Copyright (c) OriginLab Corp.	2002, 2003, 2004, 2005, 2006, 2007			*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * EJP 07-10-2003 v7.0622 QA70-4745 SET_PAGE_IMPORT_INFO_ON_123_ASC_IMPORT		*
 * Frank 5/26/04  v8.0878 QA70-6418 GET_ALLUSER_FOLDEL_PATH						*
 * SY 10/13/2004 v8.0147 IMPORT_WIZARD_CLEANUP									*
 *------------------------------------------------------------------------------*/

#ifndef _SYS_UTILS_H
#define _SYS_UTILS_H

// Included files
#include <stdio.h>           // IO functions and string.h
#include <OC_const.h>        // MAXFULLPATH
#include <math.h>            // Mathematical functions
#include <utilities.h>       // LT_ functions
#include <complex.h>		 // For implementing the Re, Im, and Conj functions
#include <mswin.h>           // Windows API functions
#include <page.h>			 // GraphPage class

// Enumerated definitions
typedef enum { FDLOG_ORIGIN = 1, FDLOG_EXCEL, FDLOG_TEMPLATE, FDLOG_ASCII, FDLOG_LOTUS, FDLOG_IMPORT_EXCEL,
	FDLOG_DBASE, FDLOG_DIF, ORIGIN_LABTECH, FDLOG_SOUND, FDLOG_MATHEMATICA, FDLOG_KALEIDAGRAPH,
	FDLOG_IMAGE, FDLOG_CSV, FDLOG_PCLAMP, FDLOG_SCRIPT, FDLOG_NOTES, FDLOG_EDITOR, FDLOG_SIGMA_PLOT,
	FDLOG_ODAQ, FDLOG_THERMO_GALACTIC_SPC, FDLOG_MINI_TAB,
	FDLOG_FILTER_ASCII=10000, FDLOG_FILTER_BINARY, FDLOG_FILTER_USERDEFINED } FDLogUseGroup;
	 
typedef enum { FDLOG_TYPE_SAVE_AS = 0, FDLOG_TYPE_OPEN_SINGLE, FDLOG_TYPE_OPEN_MULTISEL,
	FDLOG_TYPE_MULTI_OPEN } FDLogDialogType;

// FDLog Multi-Selection/Multi-Open options
#define FDLOG_MULTI_OPEN_MULTI_SELECTION_ONLY	-1
#define FDLOG_MULTI_OPEN_SHOW_COL_DESIG			1
#define FDLOG_MULTI_OPEN_SHOW_TEMPLATE			2
#define FDLOG_MULTI_OPEN_SHOW_FILE_SIZE			4
#define FDLOG_MULTI_OPEN_SHOW_MODIFY			8

// Function prototypes
/** >User Interface
		Open an FDLog Browse (OpenPath) dialog box.
	Example:
		string strPath;
		strPath = BrowseGetPath();                                      // or
		strPath = BrowseGetPath( "C:\\Program Files\\" );               // or
		strPath = BrowseGetPath( GetAppPath() + "OriginC\\", "Browse" );
	Parameters:
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking  
		lpcszDialogName=Title of the dialog box, default NULL uses "Open" 
	Return:
		Returns the path browsed to or an empty string if Cancel button in dialog
		box is clicked.
*/
string BrowseGetPath( LPCSTR lpcszPath = NULL, LPCSTR lpcszDialogName = NULL );

/** >User Interface
		Open an FDLog Open dialog box passing the file types to list in an array
		of strings.
	Example:
		string strPath;
		StringArray saFiletypes;
		saFiletypes.SetSize( 3 );
		saFiletypes[0]="[Project (*.OPJ)] *.OPJ";
		saFiletypes[1]="[Old version (*.ORG)] *.ORG";
		saFiletypes[2]="[Worksheets (*.OGW)] *.OGW";
		strPath = GetOpenBox( saFiletypes ); // or
		//strPath = GetOpenBox( saFiletypes, "C:\\Program Files\\" ); // or
		//strPath = GetOpenBox( saFiletypes, "C:\\Program Files\\", "Origin" ); // or
		//strPath = GetOpenBox( saFiletypes, "C:\\Program Files\\", "Origin", "OpenOPJ" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the Open dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		saFiletypes=Vector containing file types to list in the dialog box, each element
			of vector must follow syntax of LabTalk FDLog.TypeN$ object property
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string 
		lpcszDialogName=Title of the dialog box, default NULL uses "Open" 
	Return:
		Returns the path and filename of a selecetd file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetOpenBox( StringArray &saFiletypes, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >User Interface
		An FDLog.UseGroup version of GetOpenBox that uses an enumerated FDLog.UseGroup
		code to indicate the set of file types to list. See sys_utils.h or the Origin.ini
		file for a list of the enumerated FDLOG.UseGroup codes.
	Example:
		string strPath;
		strPath = GetOpenBox( FDLOG_ORIGIN ); // or
		//strPath = GetOpenBox( FDLOG_EXCEL, "C:\\Program Files\\" ); // or
		//strPath = GetOpenBox( FDLOG_ASCII, "C:\\Program Files\\", "Origin" ); // or
		//strPath = GetOpenBox( FDLOG_SCRIPT, "C:\\Program Files\\", "Origin", "OpenOGS" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the Open dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		nFDLogUseGroup=A LabTalk FDLog.UseGroup code as enumerated in sys_utils.h and in
			the Origin.ini file
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string
		lpcszDialogName=Title of the dialog box, default NULL uses "Open"
	Return:
		Returns the path and filename of a selected file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetOpenBox( FDLogUseGroup nFDLogUseGroup, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >User Interface
		An easier to use version of GetOpenBox that works for a single file type.
	Example:
		string strPath;
		strPath = GetOpenBox(); // or
		//strPath = GetOpenBox( "[Old version (*.ORG)] *.ORG" ); // or
		//strPath = GetOpenBox( "*.OPJ"); // or
		//strPath = GetOpenBox( "*.ocw Workspace", GetAppPath() + "OriginC\\" ); // or
		//strPath = GetOpenBox( "*.ocw Workspace", GetAppPath() + "OriginC\\", "Origin" ); // or
		//strPath = GetOpenBox( "*.ocw Workspace", "C:\\Program Files\\", "Origin", "Open Workspace" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the Open dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		lpcszFileType="*.ext description", or "[decription (*.ext)] *.ext", or just "*.ext"
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string
		lpcszDialogName=Title of the dialog box, default NULL uses "Open"
	Return:
		Returns the path and filename of a selecetd file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetOpenBox( LPCSTR lpcszFileType = "*.* All Files", LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >User Interface
		Open an FDLog SaveAs dialog box passing the file types to list in an array
		of strings.
	Example:
		string strPath;
		StringArray saFiletypes;
		saFiletypes.SetSize( 3 );
		saFiletypes[0]="[Project (*.OPJ)] *.OPJ";
		saFiletypes[1]="[Old version (*.ORG)] *.ORG";
		saFiletypes[2]="[Worksheets (*.OGW)] *.OGW";
		strPath = GetSaveAsBox( saFiletypes ); // or
		//strPath = GetSaveAsBox( saFiletypes, "C:\\Program Files\\" ); // or
		//strPath = GetSaveAsBox( saFiletypes, "C:\\Program Files\\", "Origin" ); // or
		//strPath = GetSaveAsBox( saFiletypes, "C:\\Program Files\\", "Origin", "SaveAsOPJ" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the SaveAs dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		saFiletypes=Vector containing file types to list in the dialog box, each element
			of vector must follow syntax of LabTalk FDLog.TypeN$ object property
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string 
		lpcszDialogName=Title of the dialog box, default NULL uses "SaveAs" 
	Return:
		Returns the path and filename of a selecetd file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetSaveAsBox( StringArray &saFiletypes, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >User Interface
		An FDLog.UseGroup version of GetSaveAsBox that uses an enumerated FDLog.UseGroup
		code to indicate the set of file types to list. See sys_utils.h or the Origin.ini
		file for a list of the enumerated FDLOG.UseGroup codes.
	Example:
		string strPath;
		strPath = GetSaveAsBox( FDLOG_ORIGIN ); // or
		//strPath = GetSaveAsBox( FDLOG_EXCEL, "C:\\Program Files\\" ); // or
		//strPath = GetSaveAsBox( FDLOG_ASCII, "C:\\Program Files\\", "Origin" ); // or
		//strPath = GetSaveAsBox( FDLOG_SCRIPT, "C:\\Program Files\\", "Origin", "SaveAsOGS" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the SaveAs dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		nFDLogUseGroup=A LabTalk FDLog.UseGroup code as enumerated in sys_utils.h and in
			the Origin.ini file
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string
		lpcszDialogName=Title of the dialog box, default NULL uses "SaveAs"
	Return:
		Returns the path and filename of a selected file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetSaveAsBox( FDLogUseGroup nFDLogUseGroup, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >User Interface
		An easier to use version of GetSaveAsBox that works for a single file type.
	Example:
		string strPath;
		strPath = GetSaveAsBox(); // or
		//strPath = GetSaveAsBox( "[Old version (*.ORG)] *.ORG" ); // or
		//strPath = GetSaveAsBox( "*.OPJ"); // or
		//strPath = GetSaveAsBox( "*.ocw Workspace", GetAppPath() + "OriginC\\" ); // or
		//strPath = GetSaveAsBox( "*.ocw Workspace", GetAppPath() + "OriginC\\", "Origin" ); // or
		//strPath = GetSaveAsBox( "*.ocw Workspace", "C:\\Program Files\\", "Origin", "SaveAs Workspace" );
		if( strPath.IsEmpty() )
			out_str( "User has cancelled the SaveAs dialog box." );
		else
			printf( "The file chosen is %s\n.", strPath );
	Parameters:
		lpcszFileType="*.ext description", or "[decription (*.ext)] *.ext", or just "*.ext"
		lpcszPath=Initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Initial filename when dialog opens, default NULL uses an empty string
		lpcszDialogName=Title of the dialog box, default NULL uses "SaveAs"
	Return:
		Returns the path and filename of a selecetd file or an empty string if Cancel button
		in dialog box is clicked.
*/
string GetSaveAsBox( LPCSTR lpcszFileType = "*.* All Files", LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL );

/** >Mathematical
		This function is essentially the same as the rnd() function
	Parameters:
		nSeed = (optional) pass any nonzero value to set the seed for random number generation, or 0
				to use the current seed.
	Returns:
		A uniformly random number between 0. and 1.
	Example:
		// The example displays 10 random numbers between 0. and 1.
		void	run_rnd()
		{
			for (int ii = 0; ii < 10; ii++)
			{
				double	rr = ran();
				out_double("value = ", rr);
			}
		}
*/
double ran(int nSeed = 0);

/** >System
		Get the text data copied onto the clipboard.
	Example:
		string strClipboardText;
		BOOL bSuccess;
		bSuccess = GetClipboardText( strClipboardText );
		if( bSuccess )
			out_str( strClipboardText );
		else
			out_str( "Error reading Clipboard or Clipboard is empty." );
	Parameters:
		strData = Output text copied from clipboard
	Return:
		Returns TRUE and a string containing text copied onto the clipboard
		on success or returns FALSE and an empty string on failure or if
		the Clipboard is empty.
*/
BOOL GetClipboardText( string& strData );

/** >File Management
		This function constructs a temporary file name in the Windows Temp path
	Example:
		string strTempFile;
		if(GetTempFileName(strTempFile,"ABC"))
		{
			printf("You can use this file name as temp file:%s\n", strTempFile);
		}
	Parameters:
		strFile = a string to receive the temp file full path file name
		lpcszPrefix = The function uses the first three characters of this string as the prefix of the file name. 
		If left as NULL, "OTF" will be used. 

	Return:
		TRUE if success, FALSE if not able to fine a temp path.
*/
BOOL GetTempFileName(string &strFile, LPCSTR lpcszPrefix = NULL);

/** >File Management
		Get the file modification date of a file from an input string containing
		a path and filename.
	Example:
		string strFileDate, strDataFile = "C:\\Origin80\\Origin.ini";
		strFileDate = GetFileModificationDate(strDataFile);
	Parameters:
		strPathAndFilename=Input string containing a path and filename with filetype extension
	Return:
		Returns a Windows like file modification date formatted for display. 
*/
string GetFileModificationDate(LPCSTR lpcstrPathAndFilename, WORD wFormat=LDF_SHORT);

/** >File Management
	List all files of a specified file type found in a folder
Example:
	string strExePath = GetAppPath();
	StringArray saResult;
	FindFiles(saResult, strExePath, "otw");
Parameters:
	saResult = the referrence of string array will receive the finding results
	lpcszPath = the file path to search for files
	lpcszExt = the file extension to search for
	bCheckExist = true will check the given saReult to see if the file is already in that array
Return:
	Returns TRUE for success, otherwise failure.
*/	
BOOL FindFiles(StringArray& saResult, LPCSTR lpcszPath, LPCSTR lpcszExt, bool bCheckExist = false);

/** >File Management
	Copy file and also set destination file's attribute
Example:
	string strThemeFile = get_theme_file_name(nSelRow, flx);
	string strPath = GetAppPath();
	strPath += "Deleted";
	if(CheckMakePath(strPath))
	{
		string strTemp = GetFileName(strThemeFile);
		FileCopy(strThemeFile, strPath + "\\" + strTemp);
		DeleteFile(strThemeFile);
		load_themes_to_grid();
	}
		
Parameters:
	lpcszSrc = [in] Pointer to a null-terminated string that specifies the name of an existing file. 
	lpcszDest =	[in] Pointer to a null-terminated string that specifies the name of the new file. 
	dwAttribute = the file attribute to set on the new file lpcszDest
	bSetCurrentTime = set the destination file to the current time or not
Return:
	Returns TRUE for success, otherwise failure.
Remark:
	This function will call CopyFile with default bFailIfExists = FALSE
*/
BOOL FileCopy(LPCSTR lpcszSrc, LPCSTR lpcszDest, DWORD dwAttribute = FILE_ATTRIBUTE_NORMAL, bool bSetCurrentTime = false);

/** >Import Export
	Export a page to an image using settings from a tree node.
Parameters:
	pg = reference to the page to export
	lpcszFileName = pointer to the target file name
	trExport = a tree node containing the export settings
*/
bool export_page(Page &pg, LPCSTR lpcszFileName, const TreeNode &trExport);

/** >Import Export
	Export a page to an image using the page's export settings
Parameters:
	pg = reference to the page to export
	lpcszFileName = pointer to the target file name
	lpcszFormat = pointer to the target format
Return:
	Returns 0 for success, non-zero for error.
Example:
	void run_export_page()
	{
		GraphPage		gp;
		gp.Create();
		if( !gp)
		{
			return;
		}
		
		string strExt("bmp");
		string strImagePath;
		strImagePath = GetAppPath(1) + "Test." + strExt;
		bool bRet = export_page(gp,strImagePath,strExt);	
	}
*/	
bool export_page(Page &pg, LPCSTR lpcszFileName, LPCSTR lpcszFormat = "EPS");

/** >Import Export
	Export a page to an image using current ini settings or prompt user with export options
Parameters:
	lpcszFileName = pointer to the target file name
	lpcszFormat = pointer to the target format
	pg = reference to the page to export
	bShowOptions = TRUE to show the export options dialog, FALSE to use current settings
Return:
	Returns 0 for success, non-zero for error.
Example:
	PageBase pbActive;
	pbActive = Project.Pages();
	string strPgName = pbActive.GetName();
	Page pg(strPgName);
	export_page_to_image( pg, "c:\\test.bmp", "bmp", false);
*/	
bool export_page_to_image(Page &pg, LPCSTR lpcszFileName, LPCSTR lpcszFormat, BOOL bShowOptions=FALSE);

/** >Import Export
	Export a page to an image using the specified settings
Parameters:
	lpcszFileName = pointer to target file name
	lpcszFormat = pointer to target image format
	pg = reference to source page
	nWidth = target image width in pixels.  If nHeight parameter is zero then nWidth specifies dots per inch.
	nHeight = target image height in pixels.  If zero then nWidth specifies dots per inch.
	nBitsOrHeight = target image bits per pixel
	nCompression = target image compression level.  This parameter is ignored by some image formats.
Return:
	Returns TRUE for success, FALSE for failure.
Example:
	void run_export_page_to_image()
	{
		GraphPage gp;
		gp.Create();
		if( !gp )
		{
			return;
		}
		
		string 	strImagePath("C:\\Test.bmp");
		int nRet = export_page_to_image(strImagePath, "bmp", gp, 1029, 789, 8, 0);
	}
*/	
bool export_page_to_image(LPCSTR lpcszFileName, LPCSTR lpcszFormat, Page &pg, int nWidth, int nHeight, int nBitsPerPixel, int nCompression=0);

//------------------- GJL v7.0357 QA70-4078 3/17/03 ORIGINC_MULTI_OPEN_SUPPORT
//////////////////////////////////////////////////////////////////////////////////
/** >User Interface
		Open an FDLog Open dialog box passing the file types to list in an array
		of strings. Optionally uses a simple Open dialog with multiple selection
		enabled or a Multi-Open dialog box.
	Example:
		int iNumSelFiles;
		string strPath;
		StringArray saFiletypes, saFilePaths;
		saFiletypes.SetSize( 3 );
		saFiletypes[0]="[Project (*.OPJ)] *.OPJ";
		saFiletypes[1]="[Old version (*.ORG)] *.ORG";
		saFiletypes[2]="[Worksheets (*.OGW)] *.OGW";
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes ); // or
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes, "C:\\Program Files\\" ); // or
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes, "C:\\Program Files\\", "Origin" ); // or
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes, "C:\\Program Files\\", "Origin", "OpenOPJ" ); // or
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes, "C:\\Program Files\\", "Origin", "OpenOPJ", true );
	Parameters:
		saFilePaths=Output vector of strings containing path and filename of all selected files
		saFiletypes=Input vector containing file types to list in the dialog box, each element
			of vector must follow syntax of LabTalk FDLog.TypeN$ object property
		lpcszPath=Input initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Input initial filename when dialog opens, default NULL uses an empty string 
		lpcszDialogName=Input title of the dialog box, default NULL uses "Open"
		bMultiSelection=Input flag specifiying to use multi-selection Open (default true) or Multi-Open (false) dialog box
	Return:
		Returns the path and filename of all selected files or an empty string if Cancel button
		in dialog box is clicked. Also returns the number of files selected.
*/
int GetMultiOpenBox( StringArray& saFilePaths, StringArray &saFiletypes, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL, bool bMultiSelection = true );

/** >User Interface
		An FDLog.UseGroup version of GetMultiOpenBox that uses an enumerated FDLog.UseGroup
		code to indicate the set of file types to list. See sys_utils.h or the Origin.ini
		file for a list of the enumerated FDLOG.UseGroup codes. Optionally uses a simple
		Open dialog with multiple selection enabled or a Multi-Open dialog box.
	Example:
		int iNumFiles;
		StringArray saFilePaths;
		iNumFiles = GetMultiOpenBox( saFilePaths, FDLOG_ORIGIN ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, FDLOG_EXCEL, "C:\\Program Files\\" ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, FDLOG_ASCII, "C:\\Program Files\\", "Origin" ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, FDLOG_SCRIPT, "C:\\Program Files\\", "Origin", "OpenOGS" );
		iNumFiles = GetMultiOpenBox( saFilePaths, FDLOG_SCRIPT, "C:\\Program Files\\", "Origin", "OpenOGS", false );
	Parameters:
		saFilePaths=Output vector of strings containing path and filename of all selected files
		nFDLogUseGroup=Input LabTalk FDLog.UseGroup code as enumerated in sys_utils.h and in
			the Origin.ini file
		lpcszPath=Input initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Input initial filename when dialog opens, default NULL uses an empty string 
		lpcszDialogName=Input title of the dialog box, default NULL uses "Open"
		bMultiSelection=Input flag specifiying to use multi-selection Open (default true) or Multi-Open (false) dialog box
	Return:
		Returns the path and filename of all selected files or an empty string if Cancel button
		in dialog box is clicked. Also returns the number of files selected.
*/
int GetMultiOpenBox( StringArray& saFilePaths, FDLogUseGroup nFDLogUseGroup, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL, bool bMultiSelection = true);

//////////////////////////////////////////////////////////////////////////////////
/** >User Interface
		An easier to use version of GetMultiOpenBox that works for a single file type.
		Optionally uses a simple Open dialog with multiple selection enabled or a
		Multi-Open dialog box.
	Example:
		int iNumFiles;
		StringArray saFilePaths;
		iNumFiles = GetMultiOpenBox(saFilePaths); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, "[Old version (*.ORG)] *.ORG" ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, "*.OPJ"); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, "*.ocw Workspace", GetAppPath() + "OriginC\\" ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, "*.ocw Workspace", GetAppPath() + "OriginC\\", "Origin" ); // or
		iNumFiles = GetMultiOpenBox( saFilePaths, "*.ocw Workspace", "C:\\Program Files\\", "Origin", "Open Workspace", false );
	Parameters:
		saFilePaths=Output vector of strings containing path and filename of all selected files
		lpcszFileType=Input file type string like "*.ext description", "[decription (*.ext)] *.ext", or just "*.ext"
		lpcszPath=Input initial path when dialog opens, default NULL uses FDLog tracking
		lpcszFileName=Input initial filename when dialog opens, default NULL uses an empty string 
		lpcszDialogName=Input title of the dialog box, default NULL uses "Open"
		bMultiSelection=Input flag specifiying to use multi-selection Open (default true) or Multi-Open (false) dialog box
	Return:
		Returns the path and filename of all selected files or an empty string if Cancel button
		in dialog box is clicked. Also returns the number of files selected.
*/
int GetMultiOpenBox( StringArray& saFilePaths, LPCSTR lpcszFileType = NULL, LPCSTR lpcszPath = NULL, LPCSTR lpcszFilename = NULL,
	 LPCSTR lpcszDialogName = NULL, bool bMultiSelection = true );
//------------------- QA70-4078

/**#
		Compute a LabTalk (1 based) index from a C (0 based) index and add an offset.
	Parameters:
		iCindex=Input 0 based C index
		nOffset=Input offset, default is 0
	Return:
		Returns a LabTalk 1 based index with added offset.
*/
int c_index_to_labtalk_index(int iCindex, int nOffset = 0);

/**#
		Compute a C (0 based) index from a LabTalk (1 based) index and add an offset.
	Parameters:
		iLTindex=Input 1 based LabTalk index
		nOffset=Input offset, default is 0
	Return:
		Returns a C 0 based index with added offset.
*/
int labtalk_index_to_c_index(int iLTindex, int nOffset = 0);



/**#
*/
BOOL	worksheets_are_same(Worksheet &wks1, Worksheet &wks2, bool bCheckSheetName = true);


/**#
*/
int FDLogInit();

/**#
*/
bool validate_identifier_name(string &strName);

/**# >Note Window
*/
bool	get_create_Note(string &strNoteWnd);

/** >Character/String Manipulation
	It appends to the string str the ' ' characters until its size reaches nSize. 

*/
void	append_blanks_to_size(string &str, int nSize);

/// EJP 07-10-2003 v7.0622 QA70-4745 SET_PAGE_IMPORT_INFO_ON_123_ASC_IMPORT
/** >Import Export
	Set the page.info.import properties.
	Parameters:
		pgTarget = reference to the page that will receive the import info
		lpcszFile = pointer to the name of the file imported
		iDataType = the type of data
	Return:
		TRUE for success, FALSE for failure
*/
BOOL set_page_import_info(Page &pgTarget, LPCSTR lpcszFile, int iDataType);
/// end SET_PAGE_IMPORT_INFO_ON_123_ASC_IMPORT

/** >File Management
	Add file extension to given string 
	Parameters:
		strFilename = filename to check and add extension 
		lpcszExt = file extension, without the dot.
	Return:
		true if extension is added, false if filename already has given extension
		
	Example:
		string str = GetAppPath() + "origin.ini";
		bool bRet = add_file_extension(str, "ini");
		ASSERT(!bRet);
		bRet = add_file_extension(str, "txt");
		ASSERT(bRet);
		string strFilename = GetFileName(str);
		ASSERT(strFilename == "origin.ini.txt");
*/
bool add_file_extension(string& strFilename, LPCSTR lpcszExt);

/** >File Management
		Check to find the filename that does not already exist 
	Parameters:
		strFilename = filename to check and update if needed 
		bCheckCreatePath = if path dose not existed, to create or just return false
	Return:
		true strFilename is a good new file name that is not in conflict with existing files
		
	Example:
		string str = GetAppPath() + "origin.ini";
		bool bRet = get_next_file_name(str);
		ASSERT(bRet);
		string strOld = GetAppPath() + "origin.ini";
		ASSERT(strOld != str);// since origin.ini must already existed
*/
bool get_next_file_name(string& strFilename, bool bCheckCreatePath = true);

/** >File Management
		Check to see if specified string is a valid file name, no path is allowed
	Parameters:
		lpcszFilename = filename to check 
	Return:
		true if lpcszFilename is not empty and does not contain illegal characters, return false if lpcszFilename contains path or has other invalid characters for filename
	Example:
		string str = "origin*.ini";
		ASSERT(!is_str_valid_for_filename(str));
		str = "origin.ini";
		ASSERT(is_str_valid_for_filename(str));
		str = GetAppPath() + "origin.ini";
		ASSERT(str.IsFile());
		ASSERT(!is_str_valid_for_filename(str));
		
		ASSERT(!is_str_valid_for_filename("abc?ef"));
		ASSERT(is_str_valid_for_filename("abcef"));
*/
bool is_str_valid_for_filename(LPCSTR lpcszFilename);

/** >Character/String Manipulation
	check and see if given string is in list
*/
bool is_in_list(LPCSTR lpcszName, const vector<string>& vsList, bool bCaseSensitive = false);

/** >Character/String Manipulation
	filter a vector of stirngs by another vector, remove all those that are not in the second list
	Return:
		number of elements removed.
*/
int remove_if_not_in_list(vector<string>& vsToCheck, const vector<string>& vsList, bool bCaseSensitive = false);

/** >Font
		Get system font name
	Example:
		void show_sys_fonts()
		{
			vector<string> vsNames = {
				"SYSTEM_FONT", "DEVICE_DEFAULT_FONT", "DEFAULT_GUI_FONT", "ANSI_VAR_FONT", "OEM_FIXED_FONT",
				"ANSI_FIXED_FONT", "SYSTEM_FIXED_FONT"};
			vector<int> vnIDs = {
				SYSTEM_FONT, DEVICE_DEFAULT_FONT, DEFAULT_GUI_FONT, ANSI_VAR_FONT, OEM_FIXED_FONT, 
				ANSI_FIXED_FONT, SYSTEM_FIXED_FONT};
				
			printf("%20s\t%s\n", "Font", "Font Face");
			out_str("-------------------------------------");
			for(int ii = 0; ii < vsNames.GetSize(); ii++)
				printf("%20s\t%s\n", vsNames[ii], get_system_font_name(vnIDs[ii]));
		}
		
	Parameters:
		nType = OEM_FIXED_FONT, SYSTEM_FONT etc const, can also pass in GSFI_TYPE_DEFAULT, GSFI_TYPE_FIXED_WIDTH, GSFI_TYPE_SCALABLE for Origin fonts
	Return:
		name of the specified font type, or an empty string if specified type is not valid
*/
string get_system_font_name(int nType = ANSI_VAR_FONT, int* lpnCharSet = NULL);

/** >System
		Test Windows version to see if it is Windows 2000 or later
	Parameters:
		bAndLater = false if you need to test to see if OS is exactly Windows 2000
	Return:
		TRUE or FALSE
*/
bool is_win2k(bool bAndLater = true);

/** >Character/String Manipulation
		Reverse of atof with LabTalk formatting options
	Parameters:
		dVal = double value to convert
		lpcszFmt = LabTalk formatting string, default (NULL) will use "*"
	Return:
		formatted string
	Example:
		double aa = PI;
		out_str(ftoa(aa));// default as "*", controlled by internal Origin preference settings
		out_str(ftoa(aa, "*3"));// show as 3 significant digits		
*/
string ftoa(double dVal, LPCSTR lpcszFmt = NULL);

/** >System
		Test origin to see if it is Professional version or regular version
	Return:
		TRUE for Professional
*/
bool is_pro_version();

///Frank 5/26/04  v8.0878 QA70-6418 GET_ALLUSER_FOLDEL_PATH						
/**#
		get the all user folder path, if you set bCreateIfNoExist = true will create the folder if not exist
	Parameters:
		bCreateIfNoExist = true to create the folder if not exist.
	Returns:
		path of all user folder, if not exist return "".
 */
string get_alluserfolder_path(bool bCreateIfNoExist = false);
///End    GET_ALLUSER_FOLDEL_PATH


//---- CPY 5/6/04 QA70-6367 HISTOGRAM_GRAPHS
/**#
// replace return false with this function to allow error message to directly display
*/
bool error_report(LPCSTR lpcszErrMsg);
//----
///Frank 9/14/04  v8.0131 QA70-6903 PAD_CHAR_TO_STRING	
string	str_pad_char(LPCSTR lpcstr, int nTotalLength, int nPaddingFormat, char	chPading = ' ');
///End PAD_CHAR_TO_STRING	



/// SY 10/13/2004 v8.0147 IMPORT_WIZARD_CLEANUP
#if _OC_VER >= 0x0800

///Frank 9/23/04  v8.0137 QA70-6027 CONVERT_NUM_TO_STRING_VECTOR
/**#
// nSize = expected size, so that if vd is too small, then fill vs with empty cells
*/
int convert_tree_double_vector_to_str_vector(const TreeNode& trVec, vector<string>& vs, uint nSize, string strFmt = "*");
int convert_str_vector_to_num_vector(const vector<string>& vs, vector<double>& vd);
void str_vector_to_double_vector_treenode(TreeNode& tr, const vector<string>& vs);
void init_vector_string(vector<string> &vsEmptyVec, int nSize, string strDefault = "");
///End CONVERT_NUM_TO_STRING_VECTOR

/**
	Read specified lines from a text file into an array of strings.
Example:
	StringArray saLines;
	int iError = ReadFileLines(saLines, "C:\\Origin80\\Origin.ini");
Parameters:
	saLines=Reference to a string array that will hold the lines
	lpcszFile=Name of file to read
	iNumLines=Number of lines to read into the string array. If 0 then all lines are read.
	iFirstLine=Zero based index of the first line to read into the string array.
	iSkipLines=Number of lines to skip after every one line read.
Return:
	Returns zero for success or non-zero to indicate error.  
*/
int ReadFileLines(StringArray &saLines, LPCSTR lpcszFile, uint iNumLines=0, uint iFirstLine=0, uint iSkipLines=0);

//
#define GFIF_NO_ERROR			0
#define GFIF_NO_FILES_FOUND_ERROR	-1

#define GFIF_FILE_WITH_PATH		0
#define GFIF_FILE_NO_PATH		1
#define GFIF_FILE_NO_EXT		2
/**
		Search a windows folder adding any filenames that match a specified file filter to an output string.
		Options specify whether or not subfolders are to be recursively searched and whether or not path
		and file extension are to be included with file name.
	Example:
		string strTemplateFileList;
		GetFilenamesInFolder(strTemplateFileList, "", "*.otw", FALSE, 3);
	Parameters:
		strListOfFilenames=Output list of formatted filenames found in folder 
		lpcstrPath=Input path to start searching, default "" is path to Origin software folder  
		lpcstrFileFilter=Input file filter which may include DOS wild card characters, default is "*.*"
		bRecursive=Input option to recursively search subfolders, default is FALSE
		wDisplayOptions=Input bitwise flag specifying display options, default value GFIF_FILE_WITH_PATH
			displays path, filename and filetype, GFIF_FILE_NO_PATH displays filename and filetype without
			path, GFIF_FILE_NO_EXT displays path and filename with out filetype extension, and
			GFIF_FILE_NO_PATH | GFIF_FILE_NO_EXT displays file name without path or filetype extension
	Return:
		Returns GFIF_NO_ERROR on success or an GFIF warning or error code on failure.
*/
int GetFilenamesInFolder(
	string& strListOfFilenames,
	LPCSTR lpcstrPath = "",
	LPCSTR lpcstrFileFilter = "",
	BOOL bRecursive = FALSE,
	UINT wDisplayOptions = GFIF_FILE_WITH_PATH);


////////////////////////////////////////////////////////////////////////////////////
// File related functions
////////////////////////////////////////////////////////////////////////////////////
//
/**
	List all files of a specified file type found in the Origin
	App Data folder and/or in the Origin software folder. 
	
Example:
	int iRetCode;
	StringArray saResult;
	iRetCode = GetSystemFiles(saResult, "otw");
Parameters:
	saResult = the referrence of string array will receive the finding results
	lpcszExt = the file extension name to matach file finding.
Return:
	Returns TRUE for success, otherwise failure.
*/
BOOL GetSystemFiles(StringArray& saResult, LPCSTR lpcszExt);

/**
		Get the path and/or just filename without extension from a string containing a path and/or
		just filename. 
	Example:
		string strFilenameWithoutExt, strFilenameWithExt;
		strFilenameWithExt = "Default.oaf";
		strFilenameWithoutExt = GetFilenameWithoutExt( strFilenameWithExt );
		ASSERT( strFilenameWithoutExt.Compare( "Default" ) == 0 );
	Parameters:
		strFilenameWithExt=Input string containing an optional path and a filename with filetype extension
	Return:
		Returns a filename without filetype extension (but with path if in original string) from an optional
		path and filename with extension.
*/
string GetFilenameWithoutExt( string strPathAndFilename );

/**
		Builds a list of the layer numbers in the active graph. The list is returned
		as a series of tokens separated by the | character. The active layer number
		is also returned.
	Example:
		string str;
		int iActive;
		iActive = GetLayerNumbers(str);
	Return:
		Returns a list of the layer numbers in the active graph as a series of tokens
		separated by the | character. The layer number of the active layer is returned
		on success and -1 is returned on failure.
*/
int GetLayerNumbers(string& strLayerNumbers);

/**
	Get the contents of a text file.
Example:
	string strText;
	int iError = LoadTextFile(strText, "C:\\Origin80\\Origin.ini");
Parameters:
	lpcszFile=Input full path and file name to read
	iNumLines=Input number of lines to read not counting skipped lines, default 0 reads all lines (after iFirstLine) 
	iFirstLine=Input first line to read, default 0 reads first line
	iSkipLines=Input number of lines to skip for every one line read, default 0 skips no lines
Return:
	Returns the contents of a text file on success and "" on failure.  
*/
int LoadTextFile(string &strText, LPCSTR lpcszFile, uint iNumLines = 0, uint iFirstLine = 0, uint iSkipLines = 0);

/**
		Get the file size of a file from an input string containing a path
		and filename.
	Example:
		string strFileSize, strDataFile = "C:\\Origin80\\Origin.ini";
		strFileSize = GetFileSize(strDataFile);
	Parameters:
		strPathAndFilename=Input string containing a path and filename with filetype extension
	Return:
		Returns a Windows like file size formatted for display. 
*/
string GetFileSize(string strPathAndFilename);


bool OpenExistingFile(file& filSrc, LPCSTR lpcszFile, UINT nOpenFlags);
#endif //_OC_VER >= 0x0800
/// end IMPORT_WIZARD_CLEANUP

#endif //_SYS_UTILS_H
