#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	batch_active,
	batch_template,
};
enum{
	data_import,
	data_existing,
};
enum{
	mode_rows,
	mode_cols,
};
//put additional include files here

#include <..\OriginLab\theme_utils.h>

#include <..\OriginLab\Import_Utils.h>
#include <..\OriginLab\fu_utils.h>
#include <..\OriginLab\IWBase.h>
#include <..\OriginLab\AscImpOptions.h>
#include <..\OriginLab\dragNdrop.h>
#include <event_utils.h>		///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
#include <..\OriginLab\WksColLabels.h>

/*------------------------------------------------------------------------------*
* File Name: batchProcess.OXF													*
* Creation: Kenny 04/23/2009													*
* Purpose: OriginC Source C file												*
* Copyright (c) OriginLab Corp. 2009											*
* All Rights Reserved															*
*																				*
* Modification Log:																*
*	Sim 05-12-2009 QA80-13594 MAKE_USER_IMPORT_OC_CODE_COMPATIBLE				*
*	CPY 7/7/09 QA70-13875 PROGRESS_BAR_VISIBILITY_BY_MAIN_WND					*
*	Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT	*
*	Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
*	Folger 09/02/09 BATCH_PROCESS_APPEND_LABEL_ROWS_SKIP_EMPTY					*
*	Folger 09/02/09 NOT_SHOW_AUTOUPDATE_PROGRESSBOX_FOR_BATCH_PROCESS			*
*	Hong 09/04/09 QA80-14266 SELECT_FILTER_DLG_ADD_NEW_OPTIONS_FOR_BATCH_PROCESSING
*	Folger 09/10/09 BATCH_PROCESS_SHOULD_POPUP_FILTER_SELECTION_DIALOG_AT_MOST_ONCE
*	Folger 09/11/09 BATCH_PROCESS_SUPPORT_GET_FILTER_INFO_FROM_LAST_IMPORT		*
*	Folger 10/19/09 QA80-14459 BATCH_PROCESS_OPEN_OGW_HIDDENLY					*
*	Folger 12/09/09 QA81-14814-P2 FINDXY_TABLE_FAILS_TO_BE_APPENDED_TO_REPORT_SHEET
*	Folger 12/09/09 QA81-14786-S2 SHOW_INTERMEDIATE_BOOKS_AT_THE_END_IF_NOT_DELETE
*	Folger 12/09/09 QA81-14786-S1 MOVE_DELETE_INTERMEDIATE_BOOK_OUT_OF_OPTIONS_BRANCH
*	Folger 12/15/09 QA81-14851 BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT	*
*	Folger 03/17/10 QA81-15215 BATCH_PROCESS_SHOULD_SKIP_EMPTY_CELLS_WHEN_APPENDING
*	Folger 03/22/10 QA81-14867 BATCH_PROCESS_TOO_MANY_FILES_THAT_FILL_UP_MESSAGE_QUEUE_CRASH_ORIGIN
*	Folger 04/14/10 QA81-15293-P3 DYNA_CHECKBOX_SHOWN_IN_OUTPUT_SHEET_AFTER_SET_RESULT_SHEET_TO_NONE
*	Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER				*
*	Folger 08/20/2010 ORG-933-S2 BATCH_PROCESS_KEEP_ORIGINAL_ACTIVE_SHEET_AFTER_REPORT
*-------------------------------------------------------------------------------*/

//put your own support static functions here

#define STR_DEFAULT_FILE_SPEC			"*.*"
//#define STR_DEFAULT_APPEND_SHEET_NAME	_L("ToAppend")
//#define STR_DEFAULT_SUMMARY_BOOK_NAME	_L("Summary")
//#define STR_DEFAULT_SUMMARY_SHEET_NAME	_L("Results")

#define	STR_IMPORT_METHOD_WIZARD		"ImportWizard"
#define STR_IMPORT_METHOD_LABTALK		"LabTalk"

#define ITEM_SEPARATOR					'|'
#define	STR_ITEM_SEPARATOR				"|"
#define FILE_LIST_SEPARATOR				'\n'
#define STR_PATH_FINAL_BACKSLASH		"\\"

#define STR_IMP_EXP_XF_CATEGORY			"Import and Export"
#define STR_IMP_XF_PREFIX				"imp"

#define CHK_NODE_BEGIN(nodeName)	\
	if ( trGetN.nodeName  )\
	{\
		string& strNodeVal = trGetN.nodeName.strVal;

#define NODE_VAL_IS_EMPTY			( strNodeVal.IsEmpty() )
#define NODE_VAL_IS_FILE			( strNodeVal.IsFile() )
#define NODE_VAL_IS_PATH			( strNodeVal.IsPath() )

#define CHK_NODE_END				}

#define CHK_NODE(nodeName, failCondition, errmsg)	\
	CHK_NODE_BEGIN(nodeName)\
		if ( failCondition )\
		{\
			strErrMsg = errmsg;\
			return false;\
		}\
	CHK_NODE_END
	
static	bool	_check_data_files(TreeNode& trFileName, string& strErrMsg)
{
	return check_imported_file_name(trFileName.strVal, strErrMsg);
}

static bool _check_error(TreeNode& trGetN, int nEventID, LPCSTR lpcszNodeName, string& strErrMsg)
{
	if ( batch_template == trGetN.batch.nVal )
		CHK_NODE(name, !NODE_VAL_IS_FILE, XFERR_INVALID_ANALYSIS_TEMPLATE_NAME )

	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	if ( data_import == trGetN.data.nVal )
	{
		if ( !_check_data_files(trGetN.fname, strErrMsg) )
			return false;
	}
	else
	{
		if ( get_input_xyrange_num(trGetN.iy) < 1 )
		{
			strErrMsg = XFERR_AT_LEAST_ONE_XYRANGE;
			return false;
		}
	}
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT

	CHK_NODE(append, NODE_VAL_IS_EMPTY, XFERR_INVALID_APPEND_WKS_NAME )

	CHK_NODE(ow, NODE_VAL_IS_EMPTY, XFERR_INVALID_SUMMARY_WKB_NAME )
	
	if ( trGetN.fill.strVal.Compare(trGetN.append.strVal) == 0 )
	{
		strErrMsg = XFERR_NO_APPROPRIATE_RESULT_SHEET;
		return false;
	}
	
	///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	if ( trGetN.number.nVal <= 0 )
	{
		strErrMsg.Format("%d:%s", CER_INVALID_POSITIVE_INTEGER, STR_STARTING_ROW_NUMBER);
		return false;
	}
	///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	return true;
}

static int _get_imp_XF_list(vector<string>& vsXFnames, DWORD dwUsgCntxt, int nLocation = ORIGIN_PATH_PREFER_USER)
{
	if(UNDEF_FOLDER == nLocation)
		return 0;
	vector<string> vsNames, vsFiles;
	int nFiles = okutil_find_files_from_map(&vsNames, &vsFiles, SUPPORTFILE_XF, 0, &dwUsgCntxt, 1, NULL, NULL, nLocation);
	if(nFiles > 0)
	{
		int nPathType = UNDEF_FOLDER;
		string strCategory;

		for(int ii = 0; ii < nFiles; ii++)
		{
			string strName = okutil_separate_composite_name(vsNames[ii], &nPathType, &strCategory);
			if( strCategory.CompareNoCase(STR_IMP_EXP_XF_CATEGORY) == 0 && strName.Find(STR_IMP_XF_PREFIX) == 0)
			{
				vsXFnames.Add(strName);
			}
		}
		return vsXFnames.GetSize();
	}
	return 0;
}

static bool _init_imp_xf_list(TreeNode& trGetN)
{
	vector<string> vsImpMethods;
	_get_imp_XF_list(vsImpMethods, IDXF_USGCTXT_LABTALK);
	vsImpMethods.Add(STR_IMPORT_METHOD_WIZARD);
	vsImpMethods.Add(STR_IMPORT_METHOD_LABTALK);

	string strImpMethodCombo;
	strImpMethodCombo.SetTokens(vsImpMethods, ITEM_SEPARATOR);

	trGetN.method.SetAttribute(STR_COMBO_ATTRIB, strImpMethodCombo);

	if( vsImpMethods.GetSize() <= 0 )
	{
		ASSERT(FALSE);
		return false;
	}
	
	return true;
}

#define		STR_XF_NAME						"batchProcess"
#define		STR_FILE_LIST					"FileList"

#define		STR_EMPTY_COMBO					" " STR_ITEM_SEPARATOR

static	void	_check_append_pipe_char(string& str)
{
	if ( str.IsEmpty() )
		str = STR_EMPTY_COMBO;
	
	if ( str.Find(ITEM_SEPARATOR) < 0 )
		str += STR_ITEM_SEPARATOR;
}

struct	TemplateSheetsInfo
{
	vector<string>		vsSheetNames;
	vector<bool>		vbHasSheetTheme;
	vector<bool>		vbExcluded;
	Tree				trFilter;
};

static	LPCSTR	_get_template_name_for_update(TreeNode& trGetN)
{
	LPCSTR	lpcsz = NULL;
	if ( batch_template == trGetN.batch.nVal )
		lpcsz = trGetN.name.strVal;
	return lpcsz;
}

static	BOOL	_update_sheet_filter_indices(vector<int>& vnIndices, Worksheet& wks)
{
	vector<uint>	vnUIDs;
	wks.FindIncomingOperations(vnUIDs);
	if ( vnUIDs.GetSize() <= 0 )	
		return FALSE;
	
	vector<int>		vnFilterOutputIDs = { IDST_FIT_CURVES
		, IDST_FIT_RESIDUALS_SCATTER
		, IDST_FIT_RESIDUALS_DATA
		, IDST_FIT_RESIDUAL_ANALYSIS
		, IDST_FIT_RESIDUALS_VERSUS_FITS_DATA
		, IDST_FIT_RESIDUALS_VERSUS_ORDER_DATA
		, IDST_FIT_RESIDUALS_LAG_DATA
		, IDST_FIT_PARTIAL_REGRESSION_DATA
		, IDST_FIT_CONFIDENT_PLOT
		, IDST_PFM_BASELINE_DATA_TABLE
	};
	DWORD			dwMask = 0x0000ffff;
	int				ii = 0;
	for ( ii=0; ii<vnFilterOutputIDs.GetSize(); ++ii )
	{
		vnFilterOutputIDs[ii] &= dwMask;
	}
	
	BOOL			bFilterThis = FALSE;
	for ( ii=0; ii<vnUIDs.GetSize(); ++ii )
	{
		OperationBase& op = Project.GetOperationObject(vnUIDs[ii]);
		if ( op )
		{
			int		nOutputCount = op.GetOutputCount();
			for ( int jj=0; jj<nOutputCount; ++jj )
			{
				DataRange		dr;
				int				nNumRanges = 0;
				if ( op.GetOutput(dr, jj) && dr && (nNumRanges = dr.GetNumRanges()) > 0 )
				{
					for ( int kk=0; kk<nNumRanges; ++kk )
					{
						string		strName;
						int			r1, r2, c1, c2;
						Worksheet	wksTmp;
						dr.GetRange(kk, r1, c1, r2, c2, wksTmp, &strName);
						vector<uint>	vn;
						if ( vnFilterOutputIDs.Find(vn, atoi(strName) & dwMask) > 0 )
						{
							int		nIndex = wksTmp.GetIndex();
							vnIndices.Add(nIndex);
							if ( !bFilterThis && wks.GetIndex() == nIndex )
								bFilterThis = TRUE;
						}
					}
				}
			}
		}
	}
	
	return bFilterThis;
}

static	TemplateSheetsInfo&	_get_template_sheets_info(LPCSTR lpcszName = NULL, LPCSTR lpcszXFName = NULL)
{
	static	TemplateSheetsInfo	l_stTemplateSheetsInfo;
	
	if ( NULL != lpcszXFName )		/// means update
	{
		l_stTemplateSheetsInfo.vsSheetNames.SetSize(0);
		l_stTemplateSheetsInfo.vbHasSheetTheme.SetSize(0);
		l_stTemplateSheetsInfo.vbExcluded.SetSize(0);
		
		WorksheetPage	pgTempWks;
		bool			bSelfDeleted = true;
		if ( NULL == lpcszName )
		{
			pgTempWks = Project.Pages();
			bSelfDeleted = false;
		}
		else
		{
			string		strName = lpcszName;
			if ( strName.IsFile() )
				pgTempWks.Create(lpcszName, CREATE_KEEP_LAYER_NAMES | CREATE_HIDDEN);
		}
		
		if ( pgTempWks )
		{
			Tree		trTemp;
			vector<int>	vnIndices;
			foreach ( Layer lay in pgTempWks.Layers )
			{
				Worksheet		wks(lay);
				vector<uint>	vn;
				BOOL			bFilterThis = vnIndices.Find(vn, wks.GetIndex()) > 0;
								
				l_stTemplateSheetsInfo.vsSheetNames.Add(wks.GetName());
				l_stTemplateSheetsInfo.vbHasSheetTheme.Add(theme_active_book_sheet_storage(trTemp, lpcszXFName, PDS_SHEET, TRUE, NULL, &lay));
				
				if ( bFilterThis || _update_sheet_filter_indices(vnIndices, wks) )
				{
					l_stTemplateSheetsInfo.vbExcluded.Add(true);
					continue;
				}
				
				Grid	grid;
				grid.Attach(wks);
				l_stTemplateSheetsInfo.vbExcluded.Add((WP_SHEET_HIERARCHY & wks.GetSystemParam(0)));
			}
			
			l_stTemplateSheetsInfo.trFilter.Reset();
			fuLoadFilterFromPage(l_stTemplateSheetsInfo.trFilter, pgTempWks, FILTER_TYPE_ASCII);
		}
		
		if ( bSelfDeleted )
			pgTempWks.Destroy();
	}
	
	return l_stTemplateSheetsInfo;
}

static	vector<string>		s_vsFilterFiles;
static	vector<string>		s_vsFilterList;

static	string		_find_filter_file_by_display_name(LPCSTR lpcszFilter)
{
	int		nIndex = s_vsFilterList.Find(lpcszFilter);
	if ( nIndex >= 0 )
		return s_vsFilterFiles[nIndex];
	
	return NULL;
}

static	string		_get_default_filter()
{
	int		nSize = s_vsFilterList.GetSize();
	if ( 0 == nSize )
	{
		ASSERT(false);		/// s_vsFilterList not init yet, should not come here
		return NULL;
	}
	
	return nSize > 1 ? s_vsFilterList[1] : s_vsFilterList[0];
}

static	bool	_has_sheet_theme_in_template(LPCSTR lpcszSheet)
{
	TemplateSheetsInfo&		stTemplateSheetsInfo = _get_template_sheets_info();
	int						nIndex = stTemplateSheetsInfo.vsSheetNames.Find(lpcszSheet);
	
	return nIndex >= 0 && stTemplateSheetsInfo.vbHasSheetTheme[nIndex];
}

static	bool	_load_analysis_template_list(string& strTemplateList)
{
	bool			bRet = dlg_load_registry(STR_XF_NAME, STR_FILE_LIST, strTemplateList);
	strTemplateList.TrimRight(ITEM_SEPARATOR);
	vector<string>	vsInRegistry;
	strTemplateList.GetTokens(vsInRegistry, ITEM_SEPARATOR);
	
	vector<int>		vnPathTypes = {ORIGIN_PATH_USER, ORIGIN_PATH_GROUP};
	for ( int ii=0; ii<vnPathTypes.GetSize(); ++ii )
	{
		string			strPath = okutil_get_origin_path(vnPathTypes[ii]);
		vector<string>	vsFiles;
		FindFiles(vsFiles, strPath, "ogw");
		
		for ( int jj=vsFiles.GetSize()-1; jj>=0; --jj )
		{
			string	strFile = strPath + vsFiles[jj];
			int		nIndex = 0;
			if ( (nIndex = vsInRegistry.Find(strFile)) >= 0 )
				vsInRegistry.RemoveAt(nIndex);
			else
				strTemplateList += STR_ITEM_SEPARATOR + strFile;
		}
	}
	
	return bRet;
}

static	bool	_add_one_item_to_analysis_template_list(LPCSTR lpcszTemplate)
{
	string		strTemplateList;
	_load_analysis_template_list(strTemplateList);
	
	vector<string>	vsTemplates;
	strTemplateList.GetTokens(vsTemplates, ITEM_SEPARATOR);
	int		nIndex = -1;
	if ( (nIndex = vsTemplates.Find(lpcszTemplate)) >= 0 )
	{
		vsTemplates.RemoveAt(nIndex);
	}
	vsTemplates.InsertAt(0, lpcszTemplate);
	
	strTemplateList.SetTokens(vsTemplates, ITEM_SEPARATOR);
	return dlg_save_to_registry(STR_XF_NAME, STR_FILE_LIST, strTemplateList);
}

static	void	_check_update_append_list_value_by_import_list(TreeNode& trGetN)
{
	if ( 0 == trGetN.append.strVal.Compare(trGetN.fill.strVal) )
	{
		string			strCombo;
		vector<string>	vsList;
		trGetN.append.GetAttribute(STR_COMBO_ATTRIB, strCombo);
		strCombo.TrimRight(ITEM_SEPARATOR);		/// MUST !!!
		strCombo.GetTokens(vsList, ITEM_SEPARATOR);
		int				nIndex = (vsList.Find(trGetN.append.strVal) + 1) % vsList.GetSize();
			
		trGetN.append.strVal = vsList[nIndex];
		
		_check_hide_output_controls(trGetN);
	}
}

static	string	_init_sheet_to_import_and_append_list(TreeNode& trGetN)
{
	TemplateSheetsInfo&	stTemplateSheetsInfo = _get_template_sheets_info();
	
	vector<string>	vsList;
	for ( int ii=0; ii<stTemplateSheetsInfo.vsSheetNames.GetSize(); ++ii )
	{
		if ( !stTemplateSheetsInfo.vbExcluded[ii] )
			vsList.Add(stTemplateSheetsInfo.vsSheetNames[ii]);
	}
	
	string		strCombo;
	strCombo.SetTokens(vsList, ITEM_SEPARATOR);
	_check_append_pipe_char(strCombo);
	
	string	strDefault = strCombo.GetToken(0, ITEM_SEPARATOR);
	trGetN.fill.SetAttribute(STR_COMBO_ATTRIB, strCombo);
	int		nIndex = vsList.Find(trGetN.fill.strVal);
	trGetN.fill.strVal = nIndex < 0 ? strDefault : vsList[nIndex];
	
	if ( 0 != strCombo.Compare(STR_EMPTY_COMBO) && batch_active != trGetN.batch.nVal )
		strCombo = STR_NONE + STR_ITEM_SEPARATOR + strCombo;
		
	trGetN.append.SetAttribute(STR_COMBO_ATTRIB, strCombo);
	nIndex = vsList.Find(trGetN.append.strVal);
	trGetN.append.strVal = nIndex < 0 ? strDefault : vsList[nIndex];
	
	_check_update_append_list_value_by_import_list(trGetN);
	
	_init_xf_theme_list(trGetN);
	
	return strDefault;
}

static	string	_init_xf_theme_list(TreeNode& trGetN, LPCSTR lpcszMethod = NULL, LPCSTR lpcszFillSheet = NULL)
{
	vector<string>		vsList;
	vector<string>		vsFileName;
	
	if ( NULL == lpcszMethod )
		lpcszMethod = trGetN.method.strVal;
	if ( NULL == lpcszFillSheet )
		lpcszFillSheet = trGetN.fill.strVal;
	
	okutil_theme_get_class_settings(lpcszMethod, &vsFileName, &vsList, THTYPE_ANALYSIS, true, true, false
	, false
	, _has_sheet_theme_in_template(lpcszFillSheet)
	);
	
	int		nLastUsed = -1;
	if ( (nLastUsed = vsList.Find(STR_LAST_USED)) >= 0 )
		vsList.RemoveAt(nLastUsed);
	string		strCombo;
	strCombo.SetTokens(vsList, ITEM_SEPARATOR);
	_check_append_pipe_char(strCombo);
	
	string	strDefault = strCombo.GetToken(0, ITEM_SEPARATOR);
	if ( trGetN )
	{
		trGetN.theme.SetAttribute(STR_COMBO_ATTRIB, strCombo);
		trGetN.theme.strVal = strDefault;
	}
	
	return strDefault;
}

static	bool	_init_import_wizard_filter_list(TreeNode& trGetN, LPCSTR fname = NULL)
{
	fuGetFilterListForImportWizard(s_vsFilterList, FILTER_TYPE_ASCII, NULL == fname ? trGetN.fname.strVal : fname , _get_template_sheets_info().trFilter.FirstNode ? true : false, &s_vsFilterFiles);
	
	string		strCombo;
	strCombo.SetTokens(s_vsFilterList, ITEM_SEPARATOR);
	_check_append_pipe_char(strCombo);
	
	if ( trGetN )
	{
		trGetN.filter.SetAttribute(STR_COMBO_ATTRIB, strCombo);
		trGetN.filter.strVal = _get_default_filter();
	}
	
	return true;
}

static	void	_check_update_template_file_list(string& strTemplateList)
{
	vector<string>	vsTemplateList;
	strTemplateList.GetTokens(vsTemplateList, ITEM_SEPARATOR);
	
	for ( int ii=vsTemplateList.GetSize() - 1; ii>=0; --ii )
	{
		if ( !vsTemplateList[ii].IsFile() )
			vsTemplateList.RemoveAt(ii);
	}
	
	strTemplateList.SetTokens(vsTemplateList, ITEM_SEPARATOR);
}

static bool _dlg_init(TreeNode& trGetN)
{
	//trGetN.fname.strVal.Empty();
	
	Worksheet	wks = Project.ActiveLayer();
	if ( !wks )
		trGetN.batch.Enable = DISABLE;
	
	/// Init template list
	string		strTemplateList;
	_load_analysis_template_list(strTemplateList);
	_check_update_template_file_list(strTemplateList);
	_check_append_pipe_char(strTemplateList);
	
	string	strCombo;
	trGetN.name.GetAttribute(STR_COMBO_ATTRIB, strCombo);
	trGetN.name.SetAttribute(STR_COMBO_ATTRIB, strCombo + strTemplateList);
	trGetN.name.strVal = strTemplateList.GetToken(0, ITEM_SEPARATOR);
	
	// Init Import Methods
	_init_imp_xf_list(trGetN);
	
	_get_template_sheets_info(_get_template_name_for_update(trGetN), trGetN.method.strVal);
	
	_init_xf_theme_list(trGetN);
	
	_init_import_wizard_filter_list(trGetN);
	
	trGetN.hint_script.Enable = ENABLE_READ_ONLY;
	trGetN.hint_script.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_USE_LABEL);
	trGetN.hint_append.Enable = ENABLE_READ_ONLY;
	trGetN.hint_append.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_USE_LABEL);
	trGetN.hint_label.Enable = ENABLE_READ_ONLY;
	trGetN.hint_label.SetAttribute(STR_ATTRIB_DISPFMT, DISPLAY_EDITOR_USE_LABEL);
	
	/// Theme List, Filter List, Data Sheet and Result Sheet should not be localized
	trGetN.theme.SetAttribute(STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);
	trGetN.filter.SetAttribute(STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);
	trGetN.fill.SetAttribute(STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);
	trGetN.append.SetAttribute(STR_OCNTRL_OPTNS, OCNTRLPARAM1_NOT_LOCALIZED);

	return true;
}

static	void	_clear_labtalk_variable_fname()
{
	LT_execute("fname$=\"\"");
}

///------ Folger 12/09/09 QA81-14814-P2 FINDXY_TABLE_FAILS_TO_BE_APPENDED_TO_REPORT_SHEET
static	void	_execute_all_dirty_operations()
{
	/******Regard of Yuri's proper fix, I need to roll back the code to call "run -p au" once.*******/
	/******YuI 12/09/09 QA70-14814 FIND_X_FROM_Y_MANUAL_INVOCATION_CONFLICT*******/
	///// The reason to execute "run -p au" twice here is there may exist some operations like FindXY,
	///// which is created by FitterOperation. If change input of parent(FitterOpertion), then both will
	///// become dirty. However, during AutoUpdate of parent, child(FindXY) will be updated to NOT DIRTY.
	///// Then during OnIdle, since input of child is dirty, AutoUpdate will be triggered.
	///// As case in BatchProcess, before OnIdle, data in append sheet will be added to Summary sheet, which
	///// is not ready yet. So, another "run -p au" is needed to trigger AutoUpdate. Ugly, but work ...
	//LT_execute("run -p au;run -p au;");
	LT_execute("run -p au;");
}
///------ End FINDXY_TABLE_FAILS_TO_BE_APPENDED_TO_REPORT_SHEET

///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
#define		BEFORE_BATCH_ANALYSIS_LOOPING(_wksPage, _wksImport, _bUseActivePage, _bNeedAppend, _bHide, _vsBooks) \
			{																									\
				WorksheetPage	_wksPage;																		\
				Worksheet		_wksImport;																		\
				bool			_bUseActivePage = NULL == lpcszAnalysisTemplate;								\
				if ( _bUseActivePage )																			\
				{																								\
					_wksPage = Project.Pages();																	\
					_wksImport = _wksPage.Layers(lpcszFillSheet);												\
				}																								\
																												\
				bool	_bNeedAppend = NULL != lpcszAppend;														\
				if ( _bNeedAppend )																				\
				{																								\
					/*///------ Folger 10/19/09 QA80-14459 BATCH_PROCESS_OPEN_OGW_HIDDENLY*/					\
					/*if ( is_same_folder(wksSummary.GetPage().GetFolder(), Project.ActiveFolder()) )*/			\
						/*wksSummary.CheckShowActivate();*/														\
					/*///------ End BATCH_PROCESS_OPEN_OGW_HIDDENLY*/											\
				}																								\
				bool _bHide = IsWindowVisible(GetWindow()) ? false : true;										\
				progressBox pb("", 0, _bHide);																	\
				vector<string>		_vsBooks; 
				
			
#define		SET_PROGRESS_BOX_TIPS_AND_PREPARE_ANALYSIS_TEMPLATE(_bHide, _Size, _ii, _strTips, _bUseActivePage, _wksPage, _wksImport, _nActiveSheet)	\
			if ( !_bHide )																												\
				pb.CheckReopen();																										\
			pb.SetText(_L("Analysis Processing") + STR_THREE_DOTS, PBOXT_TITLE);														\
			pb.SetRange(0, (_Size));																									\
			if ( pb.Set(_ii) )																											\
				pb.SetText(_strTips, PBOXT_MIDCENTER);	        																		\
			else																														\
				break;																													\
																																		\
			if ( !_bUseActivePage )																										\
			{																															\
				/*///------ Folger 10/19/09 QA80-14459 BATCH_PROCESS_OPEN_OGW_HIDDENLY*/												\
				/*_wksPage.Create(lpcszAnalysisTemplate);*/																				\
				_wksPage.Create(lpcszAnalysisTemplate, CREATE_HIDDEN | CREATE_KEEP_LAYER_NAMES);										\
				/*///------ End BATCH_PROCESS_OPEN_OGW_HIDDENLY*/																		\
				if ( _wksPage )																											\
					_wksImport = _wksPage.Layers(lpcszFillSheet);																		\
			}																															\
																																		\
			if ( !_wksImport )																											\
				return -1;																												\
			/*///------ Folger 08/20/2010 ORG-933-S2 BATCH_PROCESS_KEEP_ORIGINAL_ACTIVE_SHEET_AFTER_REPORT*/ \
			int		_nActiveSheet = _wksPage.Layers().GetIndex(); \
			/*///------ End BATCH_PROCESS_KEEP_ORIGINAL_ACTIVE_SHEET_AFTER_REPORT*/ \
			/*///------ Folger 10/19/09 QA80-14459 BATCH_PROCESS_OPEN_OGW_HIDDENLY*/													\
			/*_wksImport.CheckShowActivate();*/																							\
			page_set_active_layer(_wksPage, _wksImport.GetIndex());																		\
			/*///------ End BATCH_PROCESS_OPEN_OGW_HIDDENLY*/
			
#define		CHECK_APPEND_RESULTS_TO_SUMMARY_SHEET(_bNeedAppend, _wksPage, _bUseActivePage, _ii, _vsBooks, _xy, _nLabelType, _nActiveSheet)			\
			/*///------ Folger 12/09/09 QA81-14814-P2 FINDXY_TABLE_FAILS_TO_BE_APPENDED_TO_REPORT_SHEET*/											\
			/*LT_execute("run -p au");*/																											\
			_execute_all_dirty_operations();																										\
			/*///------ End FINDXY_TABLE_FAILS_TO_BE_APPENDED_TO_REPORT_SHEET*/																		\
																																					\
			if ( _bNeedAppend )																														\
			{																																		\
				DWORD	_dwCntrl = CPYT_EXTERN_UPDATE_ORIGIN | (bAppendLabelRows ? 0 : (wksSummary.GetPage().GetType() == EXIST_EXTERN_WKS ?  0 : CPYT_COPY_COLUMN_LABELS)) \
								| CPYT_COPY_COLUMN_FORMAT \
								| CPYT_COPY_COLUMN_DESIGNATIONS \
								/*///------ Folger 03/17/10 QA81-15215 BATCH_PROCESS_SHOULD_SKIP_EMPTY_CELLS_WHEN_APPENDING*/ \
								| CPYT_SKIP_EMPTY \
								; \
								/*///------ End BATCH_PROCESS_SHOULD_SKIP_EMPTY_CELLS_WHEN_APPENDING*/ \
				/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				int		_nColOffset = 0; \
				/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				if ( bAppendByRows )																												\
				{ \
					_dwCntrl |= CPYT_APPEND_BY_ROW;																									\
					/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
					if ( _xy ) \
						_nColOffset = 1; \
					/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				} \
																																					\
				Worksheet		_wksSrc = _wksPage.Layers(lpcszAppend);																				\
				if ( !_wksSrc )																														\
					return -1;																														\
				\
				/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				int		_nSummaryR1 = -1, _nSummaryR2 = -1; \
				/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
																																					\
				if ( 0 == _ii )																														\
				{																																	\
					/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
					wksSummary.GetBounds(_nSummaryR1, 0, _nSummaryR2, -1); \
					/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
					if ( bClearSummarySheetBeforeAppend )																							\
					{																																\
						if ( bAppendByRows )																										\
						{																															\
							wksSummary.ClearData(CWOD_SHRINK_COLS, 0, -1, nRowStart);																\
							if ( 0 == wksSummary.GetNumCols() )																						\
								wksSummary.SetSize(-1, _wksSrc.GetNumCols());																		\
							wksSummary.SetBounds(0, 0, nRowStart - 1, -1);																			\
							/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
							_nSummaryR2 = nRowStart - 1; \
							/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
						}																															\
						else																														\
						{																															\
							wksSummary.SetSize(-1, 0);																								\
						}																															\
					}																																\
					if ( bAppendLabelRows )																											\
					{ \
						append_label_rows(wksSummary, _wksSrc);																						\
						/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
						if ( _nColOffset > 0 ) \
						{ \
							wksSummary.SetCell(_nSummaryR2 + 1, 0, BATCH_STR_LABEL_DATASET_NAME); \
						} \
						/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
					} \
					/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
					else \
					{ \
						if ( _nColOffset > 0 ) \
						{ \
							Column	col1(wksSummary, 0); \
							if ( col1 ) \
								col1.SetLongName(BATCH_STR_LABEL_DATASET_NAME); \
						} \
					} \
					/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				}																																	\
																																					\
				_wksSrc.CopyTo(wksSummary, 0, -1, 0, -1, -1 - _nColOffset, -1, _dwCntrl);															\
				
				/*///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
				if ( 0 != _nColOffset && _xy ) \
				{ \
					int			_nR1, _nR2; \
					_wksSrc.GetBounds(_nR1, 0, _nR2, -1); \
					string		_str = batch_get_data_identifier_string(_xy, _nLabelType); \
					int			_nSize = _nR2 - _nR1 + 1; \
					batch_check_append_col_results(wksSummary, 0, _nSize, _str, _nSummaryR2 + 1); \
				} \
				/*///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER*/ \
			}																																		\
			if ( NULL != lpcszScriptAfterEachProcess && '\0' != *lpcszScriptAfterEachProcess )														\
				LT_execute(lpcszScriptAfterEachProcess);																							\
			/*///------ Folger 12/09/09 QA81-14786-S2 SHOW_INTERMEDIATE_BOOKS_AT_THE_END_IF_NOT_DELETE*/											\
			/*if ( _bNeedAppend && !_bUseActivePage && bDeleteTempateWindowsAfterAppend )*/															\
				/*_wksPage.Destroy();*/																												\
			if ( !_bUseActivePage ) \
			{ \
				if ( _bNeedAppend && bDeleteTempateWindowsAfterAppend ) \
					_wksPage.Destroy(); \
				else \
				{ \
					/*///------ Folger 08/20/2010 ORG-933-S2 BATCH_PROCESS_KEEP_ORIGINAL_ACTIVE_SHEET_AFTER_REPORT*/ \
					page_set_active_layer(_wksPage, _nActiveSheet); \
					/*///------ End BATCH_PROCESS_KEEP_ORIGINAL_ACTIVE_SHEET_AFTER_REPORT*/ \
					_vsBooks.Add(_wksPage.GetName()); \
				} \
			} \
			/*End SHOW_INTERMEDIATE_BOOKS_AT_THE_END_IF_NOT_DELETE*/
			
#define		AFTER_BATCH_ANALYSIS_LOOPING(_bNeedAppend, _vsBooks)									\
				/*///------ Folger 12/09/09 QA81-14786-S2 SHOW_INTERMEDIATE_BOOKS_AT_THE_END_IF_NOT_DELETE*/ \
				for ( int _ii=0; _ii<_vsBooks.GetSize(); ++_ii ) \
				{ \
					Page	_pg(_vsBooks[_ii]); \
					if ( _pg ) \
						_pg.SetShow(); \
				} \
				/*End SHOW_INTERMEDIATE_BOOKS_AT_THE_END_IF_NOT_DELETE*/ \
				if ( _bNeedAppend )																	\
				{																					\
					if ( is_same_folder(wksSummary.GetPage().GetFolder(), Project.ActiveFolder()) )	\
						wksSummary.GetPage().SetShow();												\
				}																					\
				if ( NULL != lpcszScriptAtTheEnd && '\0' != *lpcszScriptAtTheEnd )					\
					LT_execute(lpcszScriptAtTheEnd);												\
			}
///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT

static	int		_batch_analysis_processing(LPCSTR		lpcszAnalysisTemplate
										, LPCSTR		lpcszFillSheet
										, bool			bUseLastImportSettings
										, const			StringArray& saFiles
										, LPCSTR		lpcszImportXF
										, LPCSTR		lpcszTheme
										, LPCSTR		lpcszFilter
										, LPCSTR		lpcszScript
										, LPCSTR		lpcszAppend
										, Worksheet&	wksSummary
										, bool			bAppendByRows
										, bool			bClearSummarySheetBeforeAppend
										, bool			bDeleteTempateWindowsAfterAppend
										, LPCSTR		lpcszScriptAfterEachProcess
										, LPCSTR		lpcszScriptAtTheEnd
										///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
										, int			nRowStart
										, bool			bAppendLabelRows
										///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
										)
{
	if ( NULL == lpcszImportXF && NULL == lpcszFilter && NULL == lpcszScript || 0 == saFiles.GetSize() )
	{
		ASSERT(false);
		return -1;
	}
	
	Tree	trFilter;
	
	if ( NULL != lpcszImportXF )
	{
		if ( PDS_AUTO == okutil_cvt_str_to_predefined_type(lpcszTheme) )
		{
			lpcszTheme = _init_xf_theme_list(NULL, lpcszImportXF, lpcszFillSheet);
		}
	}
	else if ( NULL != lpcszFilter )
	{
		if ( PDS_AUTO == okutil_cvt_str_to_predefined_type(lpcszFilter) )
		{
			_init_import_wizard_filter_list(NULL, saFiles[0]);
			lpcszFilter = _get_default_filter();
		}
		
		string	strFilterFile = _find_filter_file_by_display_name(lpcszFilter);
		if ( 0 == strFilterFile.Compare(SZ_IW_PAGE_FILTER) )
		{
			trFilter = _get_template_sheets_info().trFilter;
		}
		else if ( strFilterFile.IsFile() )
		{
			fuLoad(trFilter, strFilterFile);
		}
	}
	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	//WorksheetPage	wksPage;
	//Worksheet		wksImport;
	//bool			bUseActivePage = NULL == lpcszAnalysisTemplate;
	//if ( bUseActivePage )
	//{
		//wksPage = Project.Pages();
	//}
	//
	//bool	bNeedAppend = NULL != lpcszAppend;
	//if ( bNeedAppend )
	//{
		//if ( bClearSummarySheetBeforeAppend )
			//wksSummary.SetSize(-1, 0);
		//wksSummary.CheckShowActivate();
	//}
	////----- CPY 7/7/09 QA70-13875 PROGRESS_BAR_VISIBILITY_BY_MAIN_WND
	////progressBox pb("", PBOX_TOPMOST);
	//bool bHide = IsWindowVisible(GetWindow())? false:true;
	//progressBox pb("", PBOX_TOPMOST, bHide);
	////-----
	//pb.SetText(_L("Analysis Processing") + STR_THREE_DOTS, PBOXT_TITLE);
	//pb.SetRange(0, saFiles.GetSize());
	///------ Folger 03/22/10 QA81-14867 BATCH_PROCESS_TOO_MANY_FILES_THAT_FILL_UP_MESSAGE_QUEUE_CRASH_ORIGIN
	OC_POST_MESSAGE_BREAKER(PMBC_RUN_SCRIPT_AFTER_IMPORT | PMBC_SET_PAGE_CHANGED);
	///------ End BATCH_PROCESS_TOO_MANY_FILES_THAT_FILL_UP_MESSAGE_QUEUE_CRASH_ORIGIN
	BEFORE_BATCH_ANALYSIS_LOOPING(wksPage, wksImport, bUseActivePage, bNeedAppend, bHide, vsBooks)
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	for ( int ii=0; ii<saFiles.GetSize(); ++ii )
	{
		string	strTips;
		strTips.Format("%d/%d %s", ii + 1, saFiles.GetSize(), saFiles[ii]);
		///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
		//if ( pb.Set(ii) )
			//pb.SetText(strTips, PBOXT_MIDCENTER);	        
		//else	        
			//break;		/// user abort
		//
		//if ( !bUseActivePage )
		//{
			//wksPage.Create(lpcszAnalysisTemplate);
		//}
		//
		//if ( wksPage )
			//wksImport = wksPage.Layers(lpcszFillSheet);
		//
		//if ( !wksImport )
			//return -1;
		//
		//wksImport.CheckShowActivate();
		SET_PROGRESS_BOX_TIPS_AND_PREPARE_ANALYSIS_TEMPLATE(bHide, saFiles.GetSize(), ii, strTips, bUseActivePage, wksPage, wksImport, nActiveSheet)
		///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
		string		str;
		str.Format("fname$=%s", saFiles[ii]);
		LT_execute(str);
		
		if ( NULL != lpcszImportXF )
		{
			string		strImportXF = lpcszImportXF;
			if ( '\0' != *lpcszTheme )
				strImportXF.Format("%s -t %s", lpcszImportXF, lpcszTheme);
				
			LT_execute(strImportXF);
		}
		else if ( NULL != lpcszFilter )
		{
			vector<string>		vsFiles;
			vsFiles.Add(saFiles[ii]);
			///---Sim 05-12-2009 QA80-13594 MAKE_USER_IMPORT_OC_CODE_COMPATIBLE
			//ImportFiles(vsFiles, wksPage.GetName(), wksImport.GetIndex(), NULL, NULL, IMPORT_FILES_IGNORE_DRAG_AND_DROP_SUPPORT);
			/// Hong 09/04/09 QA80-14266 SELECT_FILTER_DLG_ADD_NEW_OPTIONS_FOR_BATCH_PROCESSING
			//import_files_ex(vsFiles, wksPage.GetName(), wksImport.GetIndex(), NULL, NULL, IMPORT_FILES_IGNORE_DRAG_AND_DROP_SUPPORT);
			///------ Folger 09/10/09 BATCH_PROCESS_SHOULD_POPUP_FILTER_SELECTION_DIALOG_AT_MOST_ONCE
			//DWORD				dwCntrl = IMPORT_FILES_IGNORE_DRAG_AND_DROP_SUPPORT | IMPORT_FILES_SEL_FILTER_DLG_HIDE_IMP_WIZ_BTN | IMPORT_FILES_SEL_FILTER_DLG_SHOW_SAVE_TO_PAGE_CHKBX;
			//import_files_ex(vsFiles, wksPage.GetName(), wksImport.GetIndex(), NULL, NULL, dwCntrl);
			DWORD				dwCntrl = IMPORT_FILES_IGNORE_DRAG_AND_DROP_SUPPORT
										| IMPORT_FILES_SEL_FILTER_DLG_HIDE_IMP_WIZ_BTN
										| IMPORT_FILES_SEL_FILTER_DLG_NO_APPLY_TO_ALL
										| (bUseLastImportSettings ? IMPORT_FILES_CHECK_USE_LAST_IMPORT_SETTINGS	: 0)	///------ Folger 09/11/09 BATCH_PROCESS_SUPPORT_GET_FILTER_INFO_FROM_LAST_IMPORT
										| IMPORT_FILES_FORCE_ASCII_FILTER_IF_NONE
										| (0 == ii ? 0 : IMPORT_FILES_NO_FILTER_APPLICABLE_CHECKING)
										;
			
			/// since wksPage is hidden when import, then it's impossible to put something into labels, needs to create Grid temporary
			Grid	grid;
			grid.Attach(wksImport);
			import_files_ex(vsFiles, wksPage.GetName(), wksImport.GetIndex(), trFilter, NULL, dwCntrl, trFilter.IsEmpty() ? &trFilter : NULL);
			if ( 0 == ii && trFilter.IsEmpty() )
			{
				if ( !bUseActivePage )
					wksPage.Destroy();
				return -1;
			}
			///------ End BATCH_PROCESS_SHOULD_POPUP_FILTER_SELECTION_DIALOG_AT_MOST_ONCE
			/// end SELECT_FILTER_DLG_ADD_NEW_OPTIONS_FOR_BATCH_PROCESSING
			///---END QA80-13594 MAKE_USER_IMPORT_OC_CODE_COMPATIBLE
		}
		else if ( NULL != lpcszScript )
		{
			LT_execute(lpcszScript);
		}
		///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
		//LT_execute("run -p au");
		//
		//if ( bNeedAppend )
		//{
			//DWORD	dwCntrl = CPYT_EXTERN_UPDATE_ORIGIN | CPYT_COPY_COLUMN_LABELS | CPYT_COPY_COLUMN_FORMAT | CPYT_COPY_COLUMN_DESIGNATIONS;
			//if ( bAppendByRows )
				//dwCntrl |= CPYT_APPEND_BY_ROW;
			//
			//Worksheet		wksSrc = wksPage.Layers(lpcszAppend);
			//if ( !wksSrc )
				//return -1;
			//
			//wksSrc.CopyTo(wksSummary, 0, -1, 0, -1, -1, -1, dwCntrl);
			//
			//if ( !bUseActivePage && bDeleteTempateWindowsAfterAppend )
				//wksPage.Destroy();
		//}
		XYRange		xyDummy;
		CHECK_APPEND_RESULTS_TO_SUMMARY_SHEET(bNeedAppend, wksPage, bUseActivePage, ii, vsBooks, xyDummy, RCLT_INVALID, nActiveSheet)
		///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	}
	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	//if ( bNeedAppend )
	//{
		//wksSummary.CheckShowActivate();
	//}
	AFTER_BATCH_ANALYSIS_LOOPING(bNeedAppend, vsBooks)
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	_clear_labtalk_variable_fname();
	
	return 0;
}

///------ Folger 12/15/09 QA81-14851 BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
enum
{
	TARGETCLOUMN_INVALID			 = -1,
	TARGETCLOUMN_XY					 = 0,
	TARGETCLOUMN_Y,
};

static	BOOL	_check_target_columns(Column& col1, Column& col2)
{
	if ( !col1 )
		return TARGETCLOUMN_INVALID;
	
	if ( !col2 )
	{
		if ( col1.GetType() != OKDATAOBJ_DESIGNATION_Y )
			return TARGETCLOUMN_INVALID;
		
		col2 = col1;
		return TARGETCLOUMN_Y;
	}

	return col1.GetType() == OKDATAOBJ_DESIGNATION_X && col2.GetType() == OKDATAOBJ_DESIGNATION_Y ? TARGETCLOUMN_XY : TARGETCLOUMN_INVALID;
}

static	void	_copy_xy_columns(Column& colDesX, Column& colDesY, Column& colSrcX, Column& colSrcY, int nTargetType)
{
	DWORD		dwOptions = COPY_COL_FORMAT
							| COPY_COL_LONGNAME
							| COPY_COL_UNITS
							| COPY_COL_COMMENTS
							| COPY_COL_PARAMETERS
							| COPY_COL_UDL
								;
	
	copy_col(colSrcY, colDesY, dwOptions);
	vectorbase&		vbDesY = colDesY.GetDataObject();
	vbDesY = colSrcY.GetDataObject();
	
	double dX0 = NANUM;
	double dXInc = NANUM;
	string strUnits;
	string strLongName;
	
	if ( TARGETCLOUMN_Y == nTargetType )
	{
		if ( colSrcY.IsEvenSampling(&dX0, &dXInc, &strUnits, &strLongName) )
		{
			colDesY.SetEvenSampling(dX0, dXInc, strUnits, strLongName);
		}
	}
	else
	{
		ASSERT(TARGETCLOUMN_XY == nTargetType);
		
		vectorbase&		vbDesX = colDesX.GetDataObject();
		
		if ( colSrcX )
		{
			copy_col(colSrcX, colDesX, dwOptions);
			vbDesX = colSrcX.GetDataObject();
		}
		else
		{
			vector		vX;
			int			nUpperBound = colSrcY.GetUpperBound();
			if ( colSrcY.IsEvenSampling(&dX0, &dXInc, &strUnits, &strLongName) )
			{
				if( dXInc == 0.0 )
				{
					vX.SetSize(nUpperBound + 1);
					vX = dX0;
				}
				else
				{
					vX.Data(dX0, dX0 + dXInc * nUpperBound, dXInc);
				}
				colDesX.SetLongName(strLongName);
				colDesX.SetUnits(strUnits);
			}
			else
			{
				vX.Data(1, nUpperBound + 1);
			}
			vbDesX = vX;
		}
	}
}
///------ End BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT

///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
static	int		_batch_process_on_xyranges(LPCSTR			lpcszAnalysisTemplate
										, LPCSTR			lpcszFillSheet
										, const XYRange&	iy
										, LPCSTR			lpcszAppend
										, Worksheet&		wksSummary
										, bool				bAppendByRows
										, bool				bClearSummarySheetBeforeAppend
										, bool				bDeleteTempateWindowsAfterAppend
										, LPCSTR			lpcszScriptAfterEachProcess
										, LPCSTR			lpcszScriptAtTheEnd
										///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
										, int				nRowStart
										, bool				bAppendLabelRows
										///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
										///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
										, LPCSTR			lpcszLabel
										///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
										)
{
	DWORD	dwRules = DRR_NO_FACTORS | DRR_NO_WEIGHTS | DRR_GET_DEPENDENT;
	int		nNumData = iy.GetNumData(dwRules);
	
	///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
	int		bAddDatasetIdentifier = !compare_string_localization(lpcszLabel, BATCH_STR_NONE_E, true);
	int		nLabelType = RCLT_INVALID;
	///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
		
	BEFORE_BATCH_ANALYSIS_LOOPING(wksPage, wksImport, bUseActivePage, bNeedAppend, bHide, vsBooks)
	
	for ( int ii=0; ii<nNumData; ++ii )
	{
		DataRange	drSub;
		iy.GetSubRange(drSub, dwRules, ii);
		
		string	strTips;
		string	strRange;
		drSub.GetRangeString(strRange);
		///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
		if ( bAddDatasetIdentifier && RCLT_INVALID == nLabelType )
		{
			Worksheet	wks;
			int			c1, c2;
			drSub.GetRange(wks, c1, c2);
			if ( wks )
			{
				nLabelType = batch_get_label_type_by_name(wks, lpcszLabel);
				ASSERT(RCLT_INVALID != nLabelType);
			}
		}
		///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
		strTips.Format("%d/%d %s", ii + 1, nNumData, strRange);
		
		SET_PROGRESS_BOX_TIPS_AND_PREPARE_ANALYSIS_TEMPLATE(bHide, nNumData, ii, strTips, bUseActivePage, wksPage, wksImport, nActiveSheet)
		
		Column		colDesX(wksImport, 0);
		Column		colDesY(wksImport, 1);
		///------ Folger 12/15/09 QA81-14851 BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		int			nTargetType = TARGETCLOUMN_INVALID;
		if ( (nTargetType = _check_target_columns(colDesX, colDesY)) == TARGETCLOUMN_INVALID )
			return -1;
		///------ End BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		
		XYRange		xySub = drSub;
		vector		vSrcX, vSrcY;
		xySub.GetData(vSrcY, vSrcX);
		Column		colSrcX, colSrcY;
		xySub.GetXColumn(colSrcX);
		xySub.GetYColumn(colSrcY);
		///------ Folger 12/15/09 QA81-14851 BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		if ( TARGETCLOUMN_Y == nTargetType && colSrcX )
			continue;
		///------ End BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		Worksheet	wks;
		colSrcY.GetParent(wks);
		
		wksImport.SetName(wks.GetName());
		wksImport.GetPage().SetLongName(wks.GetPage().GetLongName());		
		///------ Folger 12/15/09 QA81-14851 BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		//copy_col(colSrcX, colDesX, dwOptions);
		//copy_col(colSrcY, colDesY, dwOptions);
		//
		///// copy data
		//vectorbase&		vbDesY = colDesY.GetDataObject();
		//vectorbase&		vbDesX = colDesX.GetDataObject();
		//vbDesY = colSrcY.GetDataObject();
		//vbDesX = colSrcX.GetDataObject();
		_copy_xy_columns(colDesX, colDesY, colSrcX, colSrcY, nTargetType);
		///------ End BATCH_XYRANGE_PROCESSING_EVEN_SAMPLING_SUPPORT
		
		XYRange		xyDummy;
		CHECK_APPEND_RESULTS_TO_SUMMARY_SHEET(bNeedAppend, wksPage, bUseActivePage, ii, vsBooks, bAddDatasetIdentifier ? xySub : xyDummy, nLabelType, nActiveSheet);
	}
	
	AFTER_BATCH_ANALYSIS_LOOPING(bNeedAppend, vsBooks)
	
	return 0;
}
///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT

static	bool	_is_import_method_using_labtalk_script(LPCSTR lpcszImportXF)
{
	return 0 == lstrcmpi(lpcszImportXF, STR_IMPORT_METHOD_LABTALK);
}

static	bool	_is_import_method_using_import_wizard(LPCSTR lpcszImportXF)
{
	return 0 == lstrcmpi(lpcszImportXF, STR_IMPORT_METHOD_WIZARD);
}

static	void	_set_show_method_related_nodes(TreeNode& trGetN)
{
	trGetN.script.Show = trGetN.hint_script.Show = _is_import_method_using_labtalk_script(trGetN.method.strVal);
	//trGetN.filter.Show = _is_import_method_using_import_wizard(trGetN.method.strVal);
	//trGetN.theme.Show = !trGetN.filter.Show && !trGetN.script.Show;
}

static	void	_check_hide_output_controls(TreeNode& trGetN)
{
	BOOL	bShow = TRUE;
	if ( PDS_NONE == okutil_cvt_str_to_predefined_type(trGetN.append.strVal) )
	{
		//trGetN.clear.Show = trGetN.hint_append.Show = trGetN.ow.Show = trGetN.mode.Show = trGetN.remove.Show = FALSE;
		bShow = FALSE;
	}
	//trGetN.clear.Show = trGetN.hint_append.Show = trGetN.ow.Show = trGetN.mode.Show = TRUE;
	trGetN.number.Show = trGetN.hint_append.Show = trGetN.ow.Show = bShow;
	trGetN.remove.Show = batch_active != trGetN.batch.nVal;
	///------ Folger 12/09/09 QA81-14786-S1 MOVE_DELETE_INTERMEDIATE_BOOK_OUT_OF_OPTIONS_BRANCH
	if ( trGetN.remove.Show )
	{
		trGetN.remove.Enable = bShow;
		if ( !bShow )
			trGetN.remove.nVal = FALSE;
	}
	///------ End MOVE_DELETE_INTERMEDIATE_BOOK_OUT_OF_OPTIONS_BRANCH
}

static	void	_check_hide_analysis_template_list(TreeNode& trGetN)
{
	trGetN.remove.Show = trGetN.name.Show = batch_template == trGetN.batch.nVal ? TRUE : FALSE;
}

///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
static	void	_check_hide_data_source(TreeNode& trGetN)
{
	trGetN.last.Show = trGetN.fname.Show = data_import == trGetN.data.nVal;
	trGetN.id.Show = trGetN.iy.Show = !trGetN.fname.Show;
}
///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT

///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
static	void	_check_disable_append_row_number(TreeNode& trGetN)
{
	trGetN.number.Enable = (trGetN.clear.nVal && mode_rows == trGetN.mode.nVal )? ENABLE : DISABLE;
}

static	void	_check_disable_append_label_rows(TreeNode& trGetN)
{
	trGetN.label.Enable = mode_rows == trGetN.mode.nVal ? ENABLE : DISABLE;
}
///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING

///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
static	void	_update_data_indentifiers(TreeNode& trGetN)
{
	batch_update_data_indentifiers(trGetN, "id", TRUE);
}
///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER


void batchProcess(const int& batch, const string& name, const string& _sep1, const int& data, const int& last, const string& fname, const XYRange& iy, const string& id, const string& method, const string& theme, const string& filter, const string& hint_script, const string& script, const string& fill, const string& append, const string& hint_append, Worksheet& ow, const int& remove, const int& number, const int& clear, const int& label, const string& hint_label, const int& mode, const string& loopscript, const string& endscript)
{
	///------ Folger 09/02/09 NOT_SHOW_AUTOUPDATE_PROGRESSBOX_FOR_BATCH_PROCESS
	LTVarTempChange			tempChange("@AUB", 0);
	///------ End NOT_SHOW_AUTOUPDATE_PROGRESSBOX_FOR_BATCH_PROCESS
	
	if ( batch_template == batch && !name.IsFile() )
		XF_THROW(XFERR_INVALID_ANALYSIS_TEMPLATE_NAME);
	
	fname.TrimLeft();
	fname.TrimRight();
	StringArray vsDataFileList;
	fname.GetTokens(vsDataFileList, FILE_LIST_SEPARATOR);
	
	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	bool	bDataImport = data_import == data;
	if ( bDataImport )
	{
		if ( 0 == vsDataFileList.GetSize() )
			XF_THROW(CER_INVALID_FILENAME);
	}
	else
	{
		if ( iy.GetNumData(DRR_GET_DEPENDENT) < 1 )
			XF_THROW(XFERR_AT_LEAST_ONE_XYRANGE);
	}
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	
	LPCSTR		lpcszImportXF = method;
	LPCSTR		lpcszFilter = STR_NONE_E;
	LPCSTR		lpcszScript = NULL;
	if ( _is_import_method_using_import_wizard(lpcszImportXF) )
	{
		lpcszImportXF = NULL;
		if ( filter )
			lpcszFilter = filter;
	}
	else if ( _is_import_method_using_labtalk_script(lpcszImportXF) )
	{
		lpcszImportXF = NULL;
		lpcszScript = script;
	}
	
	LPCSTR	lpcszAppend = NULL;
	if ( append )
		lpcszAppend = append;
	
	LPCSTR	lpcszName = NULL;
	if ( batch_template == batch )
		lpcszName = name;
	
	///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	if ( number <= 0 )
		XF_THROW_EX(CER_INVALID_POSITIVE_INTEGER, STR_STARTING_ROW_NUMBER);
	bool	bAppendLabelRows = label;
	if ( mode_cols == mode )
		bAppendLabelRows = false;
	///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	
	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	int		nRet = 0;
	if ( bDataImport )
		nRet = _batch_analysis_processing(lpcszName, fill, last, vsDataFileList, lpcszImportXF, theme, lpcszFilter, lpcszScript, lpcszAppend, ow, mode_rows == mode ? true : false, clear, remove, loopscript, endscript, number - 1, bAppendLabelRows);
	else
		nRet = _batch_process_on_xyranges(lpcszName, fill, iy, lpcszAppend, ow, mode_rows == mode ? true : false, clear, remove, loopscript, endscript, number - 1, bAppendLabelRows, id);
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	if ( 0 != nRet )
		XF_THROW("\r\n");
	
	_add_one_item_to_analysis_template_list(name);
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int batchProcess_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return batchProcess_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	if ( GETNE_ON_THEME == nEventID )
	{
		_init_imp_xf_list(trGetN);
	}
	
	if ( 0 == lstrcmpi(lpcszNodeName, "method") )
	{
		_set_show_method_related_nodes(trGetN);
		_init_xf_theme_list(trGetN);
	}
	
	else if ( 0 == lstrcmpi(lpcszNodeName, "name") || 0 == lstrcmpi(lpcszNodeName, "batch") )
	{
		_get_template_sheets_info(_get_template_name_for_update(trGetN), trGetN.method.strVal);
		_init_sheet_to_import_and_append_list(trGetN);
		_init_import_wizard_filter_list(trGetN);
		if ( 0 == lstrcmpi(lpcszNodeName, "batch") )
		{
			_check_hide_analysis_template_list(trGetN);
		}
	}
	
	else if ( 0 == lstrcmpi(lpcszNodeName, "fill") )
	{
		_init_xf_theme_list(trGetN);
		_check_update_append_list_value_by_import_list(trGetN);
	}
	
	else if ( 0 == lstrcmpi(lpcszNodeName, "fname") )
	{
		_init_import_wizard_filter_list(trGetN);
	}
	
	else if ( 0 == lstrcmpi(lpcszNodeName, "append") )
	{
		_check_hide_output_controls(trGetN);
	}
	///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	else if ( 0 == lstrcmpi(lpcszNodeName, "data") )
	{
		_check_hide_data_source(trGetN);
	}
	///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
	///------ Folger 08/28/09 QA80-4588 BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	else if ( 0 == lstrcmpi(lpcszNodeName, "clear") )
	{
		_check_disable_append_row_number(trGetN);
	}
	else if ( 0 == lstrcmpi(lpcszNodeName, "mode") )
	{
		_check_disable_append_row_number(trGetN);
		_check_disable_append_label_rows(trGetN);
	}
	///------ End BATCH_PROCESS_SUPPORT_SPECIFY_START_ROW_FOR_APPENDING
	///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
	else if ( 0 == lstrcmpi(lpcszNodeName, "iy") )
	{
		_update_data_indentifiers(trGetN);
	}
	///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
	if( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID || lpcszNodeName && *lpcszNodeName )
	{
		if ( nEventID < 0 )
		{
			///------ Folger 05/05/10 ORG-88 BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
			_update_data_indentifiers(trGetN);
			///------ End BATCH_PROCESS_SUPPORT_DATASET_IDENTIFIER
			_set_show_method_related_nodes(trGetN);
			_init_sheet_to_import_and_append_list(trGetN);
			//_check_hide_output_controls(trGetN);
			_check_hide_analysis_template_list(trGetN);
			_check_hide_data_source(trGetN);		///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
			_check_disable_append_row_number(trGetN);
			_check_disable_append_label_rows(trGetN);
		}
		
		if( !_check_error(trGetN, nEventID, lpcszNodeName, strErrMsg) )
			bOKEnable = false;
	}
	
	return true;

}

int batchProcess_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	return false;
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void batchProcess_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		if ( nGetNDialog > 0 )
			_dlg_init(trGetN);
		else
			_get_template_sheets_info(_get_template_name_for_update(trGetN), trGetN.method.strVal);
		
		///------ Folger 04/14/10 QA81-15293-P3 DYNA_CHECKBOX_SHOWN_IN_OUTPUT_SHEET_AFTER_SET_RESULT_SHEET_TO_NONE
		trGetN.ow.RemoveAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK);
		trGetN.iy.RemoveAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK);
		///------ End DYNA_CHECKBOX_SHOWN_IN_OUTPUT_SHEET_AFTER_SET_RESULT_SHEET_TO_NONE
	}
	
	if ( is_xf_before_execute_body(nGetNDialog, dwCntrl) )
	{
		if ( PDS_NONE == okutil_cvt_str_to_predefined_type(trGetN.append.strVal) )
			trGetN.ow.SetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, 0);
		///------ Folger 07/27/09 QA80-14018 BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
		if ( data_import == trGetN.data.nVal )
			trGetN.iy.SetAttribute(STR_ATTRIB_DYNACONTROL_USE_CHECK, 0);
		///------ End BATCH_PROCESS_SUPPORT_MULTIPLE_XYRANGES_INPUT
		///------ Folger 09/10/09 BATCH_PROCESS_SHOULD_POPUP_FILTER_SELECTION_DIALOG_AT_MOST_ONCE
		if ( nGetNDialog < 0 )		/// on OK
		{
			trGetN.filter.strVal.Empty();
		}
		///------ End BATCH_PROCESS_SHOULD_POPUP_FILTER_SELECTION_DIALOG_AT_MOST_ONCE
	}
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int batchProcess_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
