#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here

/*
/// Iris 8/17/2009 QA80-14157 STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
/// Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
/// Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
/// Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
*/

#include <..\Originlab\WksColLabels.h>		///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT

//put your own support static functions here
static int _find_in_list(int nVal, const vector<uint>& vn, bool bWasSortedAccending)
{
	if(vn.GetSize() < 1)
		return -1;

	for(int ii = 0; ii < vn.GetSize(); ii++)
	{
		if(vn[ii] == nVal)
			return ii;
		else if( bWasSortedAccending && vn[ii] > nVal )
			return -1;
	}
	return -1;
}

static bool _get_wks_and_col_selection(const Range& iy, Worksheet& wks, vector<uint>& vnIndices)
{
	if ( !iy || 0 == iy.GetNumRanges() || 0 == iy.GetNumData() )
		return false;
	
	for ( int iSub = 0; iSub < iy.GetNumRanges(); iSub++ )
	{
		Worksheet		wksRange;
		int				c1, c2;
		iy.GetRange(wksRange, c1, c2, iSub);
		if ( !wks )
			wks = wksRange;
		else
		///------ Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
			//ASSERT(is_same_layer(wks, wksRange));
		{
			if ( !is_same_layer(wks, wksRange) )
				continue;
		}
		///------ End UNSTACK_ERROR_CHECKING_IMPROVEMENT
		if ( -1 == c2 )
			c2 = wksRange.GetNumCols() - 1;
		for ( int ii = c1; ii <= c2; ii++)
		{
			if ( -1 == _find_in_list(ii, vnIndices, false) )
				vnIndices.Add(ii);
		}
	}
	return vnIndices.GetSize() > 0 ? true : false;
}

///Kyle 08/12/2009 QA80-13990-P14 FORBID_INTERSETION_BETWEEN_DATA_AND_GROUP_RANGE
static bool _have_intersection(const vector<uint>& vnColIndices1, const vector<uint>& vnColIndices2)
{
	vector<uint> vecIndex;
	for(int ii=vnColIndices1.GetSize()-1; ii>=0; ii--)
		if(vnColIndices2.Find(vecIndex, vnColIndices1[ii]) > 0)
			return true;
	return false;
}
///End FORBID_INTERSETION_BETWEEN_DATA_AND_GROUP_RANGE

/// Iris 8/17/2009 QA80-14157 STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
//static void _construct_label_names_and_types(vector<string>& vsLabelNames, vector<int>& vnLabelTypes)
//{
	//vsLabelNames.RemoveAll();
	//vnLabelTypes.RemoveAll();
	//
	//vsLabelNames.Add(GetLocalized(E_STR_UNITS));
	//vsLabelNames.Add(GetLocalized(E_STR_COMMENTS));
	//vsLabelNames.Add(GetLocalized(E_STR_PARAMETERS));	
	//
	//vnLabelTypes.Add(RCLT_UNIT);
	//vnLabelTypes.Add(RCLT_COMMENT);
	//vnLabelTypes.Add(RCLT_PARAM);	
	//
	//for(int ii = 2; ii <= PARAMS_MAX_NUM; ++ii)
	//{
		//vsLabelNames.Add(GetLocalized(E_STR_PARAMETERS) + ' ' + ii);
		//vnLabelTypes.Add(RCLT_PARAM + ii - 1);
	//}
	//vsLabelNames.Add(GetLocalized(E_STR_USER_DEFINED_PARAMETERS));
	//vnLabelTypes.Add(RCLT_UDL);
//}

//static void _gui_update_label_controls(TreeNode& trGetN, bool bInit)
//{
	//if( bInit )
	//{
		//vector<string> vsLabelNames;		
		//vector<int> vnLabelTypes;
		//
		//_construct_label_names_and_types(vsLabelNames, vnLabelTypes);
		//
		//// set combo string for label variable
		//string strCombo;
		//strCombo.SetTokens(vsLabelNames, '|');
		//trGetN.label.SetAttribute(STR_COMBO_ATTRIB, strCombo);
		//
		//// set default option for label variable
		//if( trGetN.label.IsEmpty() || is_empty_or_unassigned(trGetN.label.strVal) )
			//trGetN.label.strVal = GetLocalized(E_STR_COMMENTS);		
	//}
	//
	//trGetN.userdef.Show = ( RCLT_UDL == _get_label_type_from_label_name(trGetN.label.strVal) );
//}

//static int _get_label_type_from_label_name(LPCSTR lpcszLabelName)
//{
	//vector<string> vsLabelNames;		
	//vector<int> vnLabelTypes;
	//_construct_label_names_and_types(vsLabelNames, vnLabelTypes);
	//
	//int nLabelType = RCLT_INVALID;
	//int nn = vsLabelNames.Find(lpcszLabelName);
	//if( nn >= 0 )
		//nLabelType = vnLabelTypes[nn];
	//return nLabelType;
//}

#define		STR_SHORT_NAME_E		"Short Name"

static	void	_gui_update_label_controls(TreeNode& trGetN)
{
	TreeNode		trRng = trGetN.irng1;
	DataRangeEx		rng;
	string			strCombo = " |";
	string			strDefault = " ";
	if ( okxf_resolve_tree_construct_range(&trRng, &rng) && rng.GetNumRanges() > 0 )
	{
		Worksheet		wks;
		rng.GetRange(wks, 0);
		
		if ( wks )
		{
			vector<string>	vsLabelNames;		
			vector<int>		vnLabelTypes;
			get_wks_shown_col_label_info_skip_specials(wks, vsLabelNames, vnLabelTypes);
			vsLabelNames.InsertAt(0, _L(STR_SHORT_NAME_E));
			strCombo.SetTokens(vsLabelNames, '|');
			strCombo += "|";
			if ( vsLabelNames.Find(trGetN.label.strVal) >= 0 )
				strDefault = trGetN.label.strVal;
			else
				strDefault = vsLabelNames.GetSize() > 1 ? vsLabelNames[1] : vsLabelNames[0];
		}
	}
	
	trGetN.label.SetAttribute(STR_COMBO_ATTRIB, strCombo);
	trGetN.label.strVal = strDefault;
}
///------ End UNSTACK_BETTER_LABEL_TYPES_SUPPORT

//static bool _check_add_column_label(Worksheet& wks, int& nLabel, LPCSTR lpcstrUserDefinedLabelName = NULL)
//{
	//if( !wks )
		//return false;
	//
	//if( nLabel <= RCLT_INVALID || nLabel > RCLT_MAX_TYPE )
		//return false;
	//
	//Grid grid;
	//grid.Attach(wks);	
	//if( nLabel >= RCLT_UDL )
	//{
		//bool bExisted = false;
		//
		//vector<string> vsUDLNames;
		//if( grid.GetUserDefinedLabelNames(vsUDLNames) )
		//{
			//int nn = vsUDLNames.Find(lpcstrUserDefinedLabelName);
			//if( nn >= 0 )
			//{
				//nLabel += nn;
				//bExisted = true;
			//}
			//else
			//{
				//nLabel += vsUDLNames.GetSize();
			//}
		//}
		//
		//if( !bExisted )
		//{
			//if( wks.CheckAddLabelByType(nLabel) >= 0 ) // return -1 for err
			//{
				//vsUDLNames.Add(lpcstrUserDefinedLabelName);
				//grid.SetUserDefinedLabelNames(vsUDLNames);
			//}
		//}		
	//}
	//else
	//{
		//bool bShow = grid.IsLabelsShown(nLabel);
		//if( !bShow )
			//grid.ShowLabels(nLabel);
	//}
	//return true;
//}
/////end STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID

///------ Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
static	void	_filter_one_cols_indices_from_other(vector<uint>& vnCoIndices, const vector<uint>& vnColOtherIndices)
{
	for ( int ii=0; ii<vnColOtherIndices.GetSize(); ++ii )
	{
		vector<uint>	vnIndices;
		if ( vnCoIndices.Find(vnIndices, vnColOtherIndices[ii]) > 0 )
		{
			vnCoIndices.RemoveAt(vnIndices[0]);
		}
	}
}

#define		RCLT_SHORT_NAME			-2

static	int		_get_label_type_by_name(Worksheet& wks, LPCSTR lpcszLabel)
{
	if ( compare_string_localization(lpcszLabel, STR_SHORT_NAME_E, true) )
		return RCLT_SHORT_NAME;
	
	return get_label_type_by_name_or_indentifier(wks, lpcszLabel);
}

static	bool	_is_group_columns_have_empty_wanted_label(Worksheet& wksGroup, const vector<uint>& vnGrpColIndices, LPCSTR lpcszLabel, string* pstrErrMsg)
{
	if ( NULL == lpcszLabel )
		return true;
	
	int		nType = RCLT_INVALID;
	if ( (nType = _get_label_type_by_name(wksGroup, lpcszLabel)) <= RCLT_INVALID )
	{
		if ( RCLT_SHORT_NAME == nType )
			return false;
		
		if ( pstrErrMsg )
			*pstrErrMsg = XFERR_GROUP_IDENTIFIER_NOT_EXIST;
		return true;
	}
	
	for ( int ii=0; ii<vnGrpColIndices.GetSize(); ++ii )
	{
		Column	col(wksGroup, vnGrpColIndices[ii]);
		if ( !col )
		{
			if ( pstrErrMsg )
				*pstrErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
			return true;
		}
		
		string		str;
		col.GetExtendedLabel(str, nType);
		if ( str.IsEmpty() )
		{
			if ( pstrErrMsg )
				*pstrErrMsg = XFERR_GROUP_IDENTIFIER_IS_EMPTY;
			return true;
		}	
	}
	
	return false;
}

static	bool	_check_input_ranges(TreeNode& trGetN, string* pstrErrMsg = NULL, Worksheet* pwksData = NULL)
{
	vector<uint>	vnColIndices;
	Worksheet		wksData, wksGroup;
	Range			rng;
	TreeNode		trRng = trGetN.irng1;
	if ( !okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wksData, vnColIndices) )
	{
		if ( pstrErrMsg )
			*pstrErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		return false;
	}
	
	trRng = trGetN.irng2;
	vector<uint>	vnGrpColIndices;
	if ( !okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wksGroup, vnGrpColIndices) )
	{
		if ( pstrErrMsg )
			*pstrErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		return false;
	}
	
	if( !is_same_layer(wksData, wksGroup) )
	{
		if ( pstrErrMsg )
			*pstrErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		return false;
	}
	
	if ( _is_group_columns_have_empty_wanted_label(wksGroup, vnGrpColIndices, trGetN.label.strVal, pstrErrMsg) )
		return false;
	
	///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	trRng = trGetN.other;
	if ( PDS_OPTIONAL != okutil_cvt_str_to_predefined_type(trGetN.other.strVal) && !okxf_resolve_tree_construct_range(&trRng, &rng) )
	{
		if ( pstrErrMsg )
			*pstrErrMsg = XFERR_INVALID_RANGE;
		return false;
	}
	///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	
	if ( pwksData )
		*pwksData = wksData;
	return true;
}
///------ End UNSTACK_ERROR_CHECKING_IMPROVEMENT

///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
static	void	_check_update_other_columns_range(TreeNode& trGetN)
{
	if ( trGetN.nonstack.nVal && PDS_OPTIONAL == okutil_cvt_str_to_predefined_type(trGetN.other.strVal) )
	{
		DataRange		rng;
		TreeNode		trRng = trGetN.irng1;
		Worksheet		wks;
		vector<uint>	vnColIndices;
		if ( !okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wks, vnColIndices) )
			return;
		
		vector<uint>	vnIndicesAll;
		vnIndicesAll.Data(0, wks.GetNumCols() - 1);
		_filter_one_cols_indices_from_other(vnIndicesAll, vnColIndices);
		
		trRng = trGetN.irng2;
		if ( !okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wks, vnColIndices) )
			return;
		
		_filter_one_cols_indices_from_other(vnIndicesAll, vnColIndices);
		
		DataRange	dr;
		for ( int ii=0; ii<vnIndicesAll.GetSize(); ++ii )
		{
			dr.Add("X", wks, 0, vnIndicesAll[ii], -1, vnIndicesAll[ii]);
		}

		string	str;
		if ( dr )
			dr.GetRangeString(str);
		trGetN.other.strVal = str;
	}
}

static	void	_check_hide_other_columns_range(TreeNode& trGetN)
{
	trGetN.other.Show = trGetN.nonstack.nVal;
	_check_update_other_columns_range(trGetN);
}
///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS


void wunstackcol(const Range& irng1, const Range& irng2, const string& label, const int& nonstack, const Range& other, const int& missing, Worksheet& ow)
{
	if ( !irng1 || !irng2 )
		XF_THROW(CER_INVALID_WKS);	
	
	Worksheet			wksSrc1;
	vector<uint>		vnColDataIndices;
	if ( !_get_wks_and_col_selection(irng1, wksSrc1, vnColDataIndices) )
		XF_THROW(XFERR_INVALID_RANGE);
	
	Worksheet			wksSrc2;
	vector<uint>		vnColIDIndices;
	if ( !_get_wks_and_col_selection(irng2, wksSrc2, vnColIDIndices) )
		XF_THROW(XFERR_INVALID_RANGE);
	
	///------ Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
	if ( !is_same_layer(wksSrc1, wksSrc2) )
		XF_THROW(XFERR_UNSTACK_NOT_SAME_SHEET);
	
	_filter_one_cols_indices_from_other(vnColDataIndices, vnColIDIndices);
	
	if ( vnColDataIndices.GetSize() == 0 )
		XF_THROW(XFERR_UNSTACKED_DATA_EMPTY);
	///------ End UNSTACK_ERROR_CHECKING_IMPROVEMENT	
	
	///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	vector<uint>*		pvn = NULL;
	vector<uint>		vnColOtherIndices;
	Worksheet			wksOther;
	if ( _get_wks_and_col_selection(other, wksOther, vnColOtherIndices) )
	{
		_filter_one_cols_indices_from_other(vnColOtherIndices, vnColDataIndices);
		_filter_one_cols_indices_from_other(vnColOtherIndices, vnColIDIndices);
		pvn = &vnColOtherIndices;
	}
	
	if ( wksOther && !is_same_layer(wksSrc1, wksOther) )
		XF_THROW(XFERR_UNSTACK_OTHER_COLS_NOT_SAME_SHEET);
	///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	
	DWORD				dwCntrl = 0;
	if ( nonstack )
		dwCntrl |= WKSUNSTACKCOL_INCLUDE_NON_UNSTACK_COLUMNS;
	if ( missing )
		dwCntrl |= WKSUNSTACKCOL_INCLUDE_MISSING_AS_ONE_GROUP;
	
	/// Iris 8/17/2009 QA80-14157 STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
	//int					nRet = wksSrc1.UnstackColumns(ow, vnColDataIndices, vnColIDIndices, dwCntrl);
	///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
	//int nLabelType = _get_label_type_from_label_name(label);
	//bool bRet = _check_add_column_label(ow, nLabelType, userdef);
	//ASSERT(bRet);	
	int nLabelType = _get_label_type_by_name(wksSrc1, label);
	///------ End UNSTACK_BETTER_LABEL_TYPES_SUPPORT
	
	///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	//int nRet = wksSrc1.UnstackColumns(ow, vnColDataIndices, vnColIDIndices, dwCntrl, nLabelType);
	int nRet = wksSrc1.UnstackColumns(ow, vnColDataIndices, vnColIDIndices, dwCntrl, nLabelType, pvn);
	///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	///end STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
	if ( nRet < 0 )
		XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet); // Hong, to do, need improve
		
}

//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 wunstackcol_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return wunstackcol_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
	if ( GETNE_ON_INIT == nEventID || GETNE_ON_THEME == nEventID )
	{
		_gui_update_label_controls(trGetN);
		///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
		_check_hide_other_columns_range(trGetN);
		///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	}
	
	if ( 0 == lstrcmpi(lpcszNodeName, "irng1") )
	{
		_gui_update_label_controls(trGetN);
	}
	///------ End UNSTACK_BETTER_LABEL_TYPES_SUPPORT
	
	///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	if ( 0 == lstrcmpi(lpcszNodeName, "nonstack") )
	{
		_check_hide_other_columns_range(trGetN);
	}
	///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
	
	/// Hong 07/14/09 QA80-8454 ADD_UNSTACK_NO_SELECTED_COLS_CHECKING
	if ( bOKEnable )
	{
		///------ Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
		//vector<uint>	vnColIndices;
		//Worksheet		wksData, wksGroup;
		//Range			rng;
		//TreeNode		trRng = trGetN.irng1;
		//if ( !okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wksData, vnColIndices) )
		//{
			//bOKEnable = false;
			//strErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		//}
		//
		//trRng = trGetN.irng2;
		//vector<uint>	vnGrpColIndices;
		//if ( bOKEnable && (!okxf_resolve_tree_construct_range(&trRng, &rng) || !_get_wks_and_col_selection(rng, wksGroup, vnGrpColIndices)) )
		//{
			//bOKEnable = false;			
			//strErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		//}
		//
		//if( bOKEnable && !is_same_layer(wksData, wksGroup))
		//{
			//bOKEnable = false;
			//strErrMsg = XFERR_UNSTACK_COL_INVALID_RANGE;
		//}
		Worksheet	wksData;
		if ( bOKEnable = _check_input_ranges(trGetN, &strErrMsg, &wksData) )
		{
			///------ Folger 09/08/09 UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
			_check_update_other_columns_range(trGetN);
			///------ End UNSTACK_SUPPORT_SPECIFY_OTHER_COLUMNS
		}
		///------ End UNSTACK_ERROR_CHECKING_IMPROVEMENT
		///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
		/////Kyle 08/12/2009 QA80-13990-P14 FORBID_INTERSETION_BETWEEN_DATA_AND_GROUP_RANGE
		//if( bOKEnable && _have_intersection(vnColIndices, vnGrpColIndices))
		//{
			//bOKEnable = false;
			//strErrMsg = XFERR_UNSTACK_COL_NOT_ALLOW_INTERSECTED_RANGE;
		//}
		/////End FORBID_INTERSETION_BETWEEN_DATA_AND_GROUP_RANGE
		///------ End UNSTACK_BETTER_LABEL_TYPES_SUPPORT
		/// Iris 8/17/2009 QA80-14157 STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
		if( bOKEnable )
		{
			Worksheet ow;
			if( okxf_resolve_string_get_origin_object(trGetN.ow.strVal, &ow)  ) // if out worksheet already exist, then need check if out wks is equal to source wks?
			{			
				if( is_same_layer(wksData, ow) )
				{
					bOKEnable = false;
					strErrMsg = XFERR_NOT_ALLOW_OUT_TO_INPUT_WKS;				
				}
				else if( ow.IsWriteProtected() )
				{
					bOKEnable = false;
					strErrMsg = XFERR_WORKSHEET_HAS_COL_LOCKED;
				}
			}
		}
		///end STACK_UNSTACK_COLUMNS_SUPPORT_SPECIFY_EXTEBDED_TYPE_LABEL_FOR_ID
		///------ Folger 09/01/09 UNSTACK_BETTER_LABEL_TYPES_SUPPORT
		//if( bOKEnable && _get_label_type_from_label_name(trGetN.label.strVal) >= RCLT_UDL && trGetN.userdef.IsEmpty() )
		//{
			//bOKEnable = false;
			//strErrMsg = XFERR_USER_DEFINED_PARAM_LABEL_CANNOT_EMPTY;
		//}
		///------ End UNSTACK_BETTER_LABEL_TYPES_SUPPORT
	}
	/// END ADD_UNSTACK_NO_SELECTED_COLS_CHECKING
	
	//_gui_update_label_controls(trGetN, GETNE_ON_INIT == nEventID);
	return true;

}

int wunstackcol_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 wunstackcol_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///------ Folger 09/01/09 UNSTACK_ERROR_CHECKING_IMPROVEMENT
	if ( (0 == nGetNDialog) && (dwCntrl & LTXF_THEME_USED) && (dwCntrl & LTXF_FROM_GUI_MENU) )
	{
		if ( !_check_input_ranges(trGetN) )
		{
			nRet = XFEVT_PROCEED_WITH_DLG;
			return;
		}
	}
	///------ End UNSTACK_ERROR_CHECKING_IMPROVEMENT
}
//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 wunstackcol_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
