/*------------------------------------------------------------------------------*
 *	File Name: 	ocutilEx.cpp													*
 *	Purpose:	utility functions for OC, octree_Utils, okutil					*
 *	Author:		DSC																*
 *  Date:		4-20-06 														*
 *  Copyright OriginLab Corp. 2000-2006											*
 *	DSC 4/25/06 QA70-8636 v8.0399 PARSE_KEY_VALUE_STRINGS						*
 *	DSC 5/18/06 QA70-8635 LOCALIZED_TIPS_OF_THE_DAY								*
 *	CPY 7/6/06 QA70-8088 CENTRALIZED_ERR_MSG_DLL								*
 *	Arvin 02/02/07 MOVE_DISCRETE_FREQUENCIES_TO_OKUTILS							*
 *	ML 5/2/2007 OCU_LOAD_STRING_AND_SHOW_MESSAGEBOX_IN_ONE_CALL					*
 *	Folger 06/29/07 FUNC_OCU_SEPARATE_CHAR_WITH_NUMERIC_SUFFIX					*
 *	Hong 08/02/07 v8.0672 THEME_FILE_ALLOW_NOT_SAVE_UNCHANGE_NODE				*
 *	DSC 8/17/07 QA70-10217 CENTRALIZE_ATTACH_PATH_CODES							*
 *	ML 9/19/2007 WRONG_TYPE														*
 *	EJP 2007-10-18 v8.0729 QA70-10528 OC_ABILITY_TO_DEL_FILES_WITH_EXCEPTIONS	*
 *	Hong 11/17/07 v8.0750 FIX_THEME_NOT_SAVE_UNCHANGE_LABEL_INCORRECT			*
 *	Folger 01/09/08 QA70-10925 SUPPORT_SKIP_ALL_CPP_COMMENTS					*
 *	Folger 07/16/08 QA80-11855 BETTER_FORMATTING_FOR_XF_HELP_DUMPING			*
 *	EJP 2008-10-14 v8.0956 QA80-12377 OC_MAKE_REL_PATH_FUNC						*
 *	Kyle 01/06/2009 v8.0993e QA80-12905 OCU_GET_CORRECT_LT_EXPRESSION_SHOULD_IGNORE_KEY_QUOTED
 *	Folger 04/23/10 QA81-15347 LT_ACCESS_TO_WKS_SELECTION_BY_XF					*
 *------------------------------------------------------------------------------*/
 // DSC 4/20/06 MOVE_OCUTILS_TO_MFC
 // OcUtils project was moved from Module to MFC.
 // Dependency is okutil<--octree_Utils<--ocUtils
 // ocUtilEx.h replaces ocUtils.h.
 // Hong 7/05/06 OKUSORT_MOVE_TO_OCUTILS
 // Hong 7/06/06 MOVE_OCUTILEX_H_TO_OCUTILEXP_H


#ifndef _OCUTILSEX_H
#define _OCUTILSEX_H

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the OCUTILS_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// OCUTILS_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.

#ifdef __AFX_H__

	#ifdef OCUTILS_DLL
		#define OCUTILS_API __declspec(dllexport)
	#else
		#define OCUTILS_API __declspec(dllimport)
	#endif

	///DSC INCLUDE_OC_TO_VC_H
	/*
	#define string 			CString
	
	//
	//#define	TreeNode		OCXmlWrapperBase
	#define	StringArray		CScriptMocaObject
	//#define	IntArray		CScriptMocaObject
	//#define	DoubleArray		CScriptMocaObject 
	// may need these #include "MocaMain.h", #include "OXMLWrapper.h" for above

	*/
	#include "OCtoVC.h"
	///end INCLUDE_OC_TO_VC_H


	extern "C" {
		///////////////////////////////////////////////////////////////////////
		// the following functions are used in VC level only
		///////////////////////////////////////////////////////////////////////
/// Hong 7/06/06 MOVE_OCUTILEX_H_TO_OCUTILEXP_H
/*

OCUTILS_API int	ocutilsGetTokens(LPCTSTR lpcszSrc, CStringArray* psaResult, char cDelimiter, LPINT lpErr, int nTrimQuotes='"');
//OCUTILS_API int	ocutils_get_tokens(LPCTSTR lpcszSrc, StringArray* psaResult, char cDelimiter, LPINT lpErr, int nTrimQuotes='*');

OCUTILS_API int	ocutilsSetTokens(CString& strTokensAsStr, const CStringArray& cstrarrTokens, char chSep);

///DSC 4/25/06 QA70-8636 v8.0399 PARSE_KEY_VALUE_STRINGS
OCUTILS_API int ocutilsSeparateKeyValues(LPCSTR lpcszSrc, CStringArray* pcsaKeys, CStringArray* pcsaVals, int nSeparator = ';');
OCUTILS_API int ocutilsMakeKeyValuesStr(string* pstrResult, CStringArray* pcsaKeys, CStringArray* pcsaVals, int nSeparator = ';');
///end PARSE_KEY_VALUE_STRINGS

/// DSC 5/18/06 QA70-8635 LOCALIZED_TIPS_OF_THE_DAY
OCUTILS_API int ocutilsTokenizeOneCSVLine(LPCSTR pCSVLine, CStringArray* pcsaCols); 
/// end LOCALIZED_TIPS_OF_THE_DAY
*/
/// end MOVE_OCUTILEX_H_TO_OCUTILEXP_H

		///////////////////////////////////////////////////////////////////////
		// end VC level functions
		///////////////////////////////////////////////////////////////////////


#else
	#define OCUTILS_API
	#pragma dll(OCUtils)	// Associate all functions below to OUtils.dll which must be in the Origin EXE folder
	//#define	IntArray	vector<int>
	//#define DoubleArray vector<double>

#endif	//__AFX_H__


//#define			OCUTILS_EXP_FUNC(returnType)					returnType	OCUTILS_API


//-- for use in OC
/**#
 *
 */
OCUTILS_API int ocu_nan_inf_to_NANUM(double* pData, UINT nSize);


/**#
 *
 */
OCUTILS_API int ocu_NANUM_to_nan(double* pData, UINT nSize);



/// DSC 4/20/06 MOVE_TO_OCUTILS	
/**#
 *
 */
OCUTILS_API string	ocu_str_pad_char(LPCSTR lpcstr, int nTotalLength, int nPaddingFormat, char	chPading = ' ');





	
/// end MOVE_TO_OCUTILS


/**#
 *
 */
OCUTILS_API int ocu_separate_key_values(LPCSTR lpcszSrc, StringArray* psaKeys, StringArray* psaVals, int nSeparator = ';');

/**#
 *
 */
OCUTILS_API int ocu_make_key_values_str(string* pstrResult, StringArray* psaKeys, StringArray* psaVals, int nSeparator = ';');

//--------Folger 06/29/07 FUNC_OCU_SEPARATE_CHAR_WITH_NUMERIC_SUFFIX
/**# 
	Separate chars with legal checking

	Parameters:
		plczs = [input]chars to be separated
		psaChars = [output]result strings after separated
		lpcszLegalCharsSingle = [input]legal single chars
		lpcszLegalCharsNumSuffix = [input]legal chars with number suffix
	Return:
		return numbers of chars if successful, else
		return -1 if the first char is number
		return -2 if there is illegal combination of chars
		return -3 if there is illegal char
		return -4 if there is duplicated legal char
	Example1:

 */
OCUTILS_API int ocu_separate_char_with_numeric_suffix(LPCSTR lpcsz, StringArray* psaChars, LPCSTR lpcszLegalCharsSingle, LPCSTR lpcszLegalCharsNumSuffix);
//--------Folger 06/29/07 FUNC_OCU_SEPARATE_CHAR_WITH_NUMERIC_SUFFIX

/// DSC 5/18/06 QA70-8635 LOCALIZED_TIPS_OF_THE_DAY
OCUTILS_API int ocu_tokenize_one_csv_line(LPCSTR pCSVLine, StringArray* psaCols);
/// end LOCALIZED_TIPS_OF_THE_DAY


///  Comments last updated by Sandy 2006-6-13
/**# >Character and String Manipulation
		strings multiple reorder
	Parameters:

	Return:
		return 0 if successful
	Example1:

 */
OCUTILS_API int ocu_multi_str_reorder(int strNum, StringArray*  pstrOut, int* pIndex,  int refNum, StringArray*  pstrRef);


//------ CPY 7/6/06 QA70-8088 CENTRALIZED_ERR_MSG_DLL
/**$
Example:
	#include <oErrMsg.h>
	#include <ocUtilEx.h>	
	void dd()
	{
		string str;
		if(ocu_load_err_msg_str(CER_COL_NUM_NOT_TWO, &str))
			out_str(str);
	}
*/
OCUTILS_API BOOL ocu_load_err_msg_str(int nMsgID, string* pstr, int nLanguage = -1);
//------

//------ CPY 5/22/2007 QA70-8088 CENTRALIZED_ERR_MSG_DLL
/**$
	load a string from oErrMsg.dll with optional arguments

	//------ Folger 12/20/07 STRING_FORMAT_ARGUMENTS_EXPLANATION
	support at most two arguments(no argument is fine), that means formats below will work:
	("...%s...%s...", lpcszArg, lpcszArg2);
	("...%s...%d...", lpcszArg, *lpnParam);
	("...%d...%s...", *lpnParam, lpcszArg);
	("...%s...", lpcszArg);
	("...%d...", *lpnParam);
	while other arguments are NULL
	//------

*/
OCUTILS_API BOOL ocu_load_msg_str(int nMsgID, string* pstr, LPCSTR lpcszArg = NULL, int* lpnParam = NULL, LPCSTR lpcszArg2 = NULL, int nLanguage = -1);
//------

/// ML 5/2/2007 OCU_LOAD_STRING_AND_SHOW_MESSAGEBOX_IN_ONE_CALL
/**$
		It loads the string from the centralized message DLL and shows message box.
		It returns whatever the MessageBox function returns.
	Parameters:
		nMsgID=the resource id of the message string.
		nType=the standard Windows values MB_* that determine what buttons and icon to show
				on the message box.
		lpcszArg=[input] optional string for first %s format specifier in message.
		lpnParam=[input] optional int for only %d format specifier in message.
		lpcszArg2=[input] optional string for second %s format specifier in message.
	Returns:
		IDOK, IDCANCEL, IDYES, etc.
*/
///DSC 8/17/07 QA70-10217 CENTRALIZE_ATTACH_PATH_CODES
// OCUTILS_API int		ocu_err_msgbox(int nMsgID, UINT nType = MB_OK);
OCUTILS_API int		ocu_err_msgbox(int nMsgID, UINT nType = MB_OK, LPCSTR lpcszArg = NULL, int* lpnParam = NULL, LPCSTR lpcszArg2 = NULL);
///end CENTRALIZE_ATTACH_PATH_CODES


/// end OCU_LOAD_STRING_AND_SHOW_MESSAGEBOX_IN_ONE_CALL


///------ Hong 7/31/06 
OCUTILS_API BOOL ocu_get_correct_LT_expression(LPCSTR lpcszExp, string* strOut);
///Kyle 01/06/2009 v8.0993e QA80-12905 OCU_GET_CORRECT_LT_EXPRESSION_SHOULD_IGNORE_KEY_QUOTED
//OCUTILS_API int ocu_keyword_replace(string* pstr, LPCSTR lpcszKey, LPCSTR lpcszValue);
OCUTILS_API int ocu_keyword_replace(string* pstr, LPCSTR lpcszKey, LPCSTR lpcszValue, bool bSkipQuoted = false);
///End OCU_GET_CORRECT_LT_EXPRESSION_SHOULD_IGNORE_KEY_QUOTED
///------ 

//Category last updated by Iris 7/28/2008
/**$ >Character and String Manipulation
		convert a string with ascii codes into C string with where the ascii codes are converted into C escape codes
	SeeAlso:
		expand_C_escape_codes
*/
OCUTILS_API void ocu_make_C_string_from_ascii(LPCSTR lpcszSrc, string* strOut);//------- CPY QA70-9221 IMPORT_ASV_NEED_READING_MULTI_LINE_CELLS

///Arvin 02/02/07 MOVE_DISCRETE_FREQUENCIES_TO_OKUTILS
enum{
	DF_CASE_SENSITIVE			= 0x01,
	DF_TRIM_LEFT_RIGHT_SPACE	= 0x02,
};
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocu_discrete_frequencies_(global_function)
*/
OCUTILS_API BOOL ocu_discrete_frequencies(StringArray* pocvsSource, StringArray* pocvsData, double* pFreqs, int* pnFreqs, DWORD dwCntrl = 0);
///END MOVE_DISCRETE_FREQUENCIES_TO_OKUTILS

//------ Folger 01/09/08 QA70-10925 SUPPORT_SKIP_ALL_CPP_COMMENTS
//OCUTILS_API int ocu_skip_C_comments(string* str);//--------- CPY 5/17/07 QA70-9794 XF_SEPARATE_INTO_TWO_CLASSES_AND_CACHE
OCUTILS_API int ocu_skip_C_comments(string* str, BOOL bSkipLeadCommentOnly = true);
//------

/// Hong 08/02/07 v8.0672 THEME_FILE_ALLOW_NOT_SAVE_UNCHANGE_NODE
/**$
		It compare the CString value by same ID, if value is the same, then remove from pocvsDest and according ID in pocvnDest
	Parameters:
		pocvnSrcIDs =[input] the source IDs to map
		pocvsSrcVals =[input] the source datas to compare
		pocvnDestIDs =[modify] the destination IDs to map and modify
		pocvsDestVals =[modify] the destination datas to compare and modify
		pocvsDestLabels =[optional] the destination labels to modify
	Returns:
		Number of removed items, negative value for error
*/
/// Hong 11/17/07 v8.0750 FIX_THEME_NOT_SAVE_UNCHANGE_LABEL_INCORRECT
//OCUTILS_API int ocu_remove_unchanged_items_by_id(IntArray* pocvnSrcIDs, StringArray* pocvsSrcVals, IntArray* pocvnDestIDs, StringArray* pocvsDestVals);
OCUTILS_API int ocu_remove_unchanged_items_by_id(IntArray* pocvnSrcIDs, StringArray* pocvsSrcVals, IntArray* pocvnDestIDs, StringArray* pocvsDestVals, StringArray* pocvsDestLabels = NULL);
//// end FIX_THEME_NOT_SAVE_UNCHANGE_LABEL_INCORRECT
/// end THEME_FILE_ALLOW_NOT_SAVE_UNCHANGE_NODE

//------ Folger 09/19/07 MAKE_COPY_DIRECTORY_CAN_SKIP_SPECIFIED_FOLDER_AND_FILE
OCUTILS_API BOOL ocu_copy_directory(LPCSTR lpcszSourceDir, LPCSTR lpcszDestDir, BOOL bRecursive = FALSE, StringArray *psaFolderSkip = NULL, StringArray *psaFileSkip = NULL, BOOL bSetNormalAttrib=true);
/// ML 9/19/2007 WRONG_TYPE
//OCUTILS_API BOOL ocuCopyDirectory(LPCSTR lpcszSourceDir, LPCSTR lpcszDestDir, BOOL bRecursive = FALSE, CStringArray *pcsaFolderSkip = NULL, CStringArray *pcsaFileSkip = NULL);
/// end WRONG_TYPE
//------ End MAKE_COPY_DIRECTORY_CAN_SKIP_SPECIFIED_FOLDER_AND_FILE

//------- CPY 9/25/2007 QA70-8261 READ_FLEXLM_SERVER_PORT_GROUP_SUPPORT
enum {
	RTFL_SKIP_EMPTY = 0x01,
	RTFL_TRIM_BOTH_ENDS = 0x02,
};
// return -1 if failed to open file
// return number of lines read otherwise
OCUTILS_API int ocu_read_text_file_lines(LPCSTR lpcszFilename, StringArray* pocvsLines, DWORD dwCntrl= RTFL_SKIP_EMPTY | RTFL_TRIM_BOTH_ENDS);
//-------

/// EJP 2007-10-18 v8.0729 QA70-10528 OC_ABILITY_TO_DEL_FILES_WITH_EXCEPTIONS
/**+
http://ocwiki.originlab.com/index.php?title=OriginC:ocu_delete_files_(global_function)
*/
OCUTILS_API int ocu_delete_files(LPCSTR lpcszPath, LPCSTR lpcszNamePattern = NULL, StringArray *pcsaFileSkip = NULL);
/// end OC_ABILITY_TO_DEL_FILES_WITH_EXCEPTIONS

//------- Folger 07/16/08 QA80-11855 BETTER_FORMATTING_FOR_XF_HELP_DUMPING
/**$
	Remarks:
		This function wrap a long text to customer settings 
	
	Example1:
		void ocu_wrap_text_ex1()
		{
		    string strLong = "abcdefghijklmnopqrstuvwxyz";
		    int nNumLine = ocu_wrap_text(strLong, 20, 4); //-->nNumLine is -1, fail to wrap since the word is too long
		    out_str(strLong);
		    //output will be:
		    //abcdefghijklmnopqrstuvwxyz
		    
		    string strNormal = "abcdefg hijklmn opq rst uvwxyz";
		    nNumLine = ocu_wrap_text(strNormal, 20, 4); //--> nNumLine is 2
		    out_str(strNormal);
		    //output will be:
		    //abcdefg hijklmn opq 
		    //    rst uvwxyz
		    return;
		}
	Parameters:
		str = [input]The long text to be wrapped 
		nLengthLimit = [input]Number of characters allowed in one line. 
		nPadSpaces = [input]Number of space to pad ahead of each line(except for the first line). 
	
	Returns:
		Numer of lines, if fail to wrap, return -1. 

*/
OCUTILS_API int ocu_wrap_text(string* str, int nLengthLimit, int nPadSpaces = 0);
//-------

/// EJP 2008-10-14 v8.0956 QA80-12377 OC_MAKE_REL_PATH_FUNC
/**$
		Construct the relative path between a fullpath file name with a fullpath
	Parameters:
		pstrRelPath =[output] result of the relative path. If lpcszfilename is in the same folder as lpcszParentPath, then strRelPath should hold only the file name portion wihtout any path.
		lpcszParentPath =[input] a fullpath that we need to be relative to
		lpcszfilename =[input] a fullpath filename that we need to convert to be relative
		nMaxStepsWalkUp =[input] max number of levels of folders that form the common root
	Returns:
		0 = success
		-1 = lpcszfilename has no path
		-2 = lpcszfilename and lpcszParentPath does not share a common root path
		-3 = too many levels to walk up to find common root
*/
OCUTILS_API int ocu_make_relative_path(string* pstrRelPath, LPCSTR lpcszParentPath, LPCSTR lpcszfilename, int nMaxStepsWalkUp = 3);
/// end OC_MAKE_REL_PATH_FUNC

///------ Folger 04/23/10 QA81-15347 LT_ACCESS_TO_WKS_SELECTION_BY_XF
OCUTILS_API	int	ocu_separate_by_str(LPCSTR lpcsz, StringArray* psaResult, LPCSTR lpcszSep);
OCUTILS_API	int	ocu_set_tokens_by_str(string* pstrResult, StringArray* pcsaTokens, LPCSTR lpcszSep);
///------ End LT_ACCESS_TO_WKS_SELECTION_BY_XF


#ifdef __AFX_H__
	}  // end extern "C"

  
#endif	//__AFX_H__

#endif //_OCUTILSEX_H
