#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	sel_none,
	sel_sel,
	sel_mask,
};
//---------------------------------------------------------
// Modification log
// CPY 5/17/07 change cond to test to make XF easier to use with 1st char, like wxt t:="r>0.2"
//	CPY 5/18/2007 SHOULD_USE_VC_FUNCTION_FOR_LT_CHECKING
// CPY 5/20/07 ADD_OPTION_TO_SEL_CELLS
// CPY 11/15/08 QA70-12589 WXT_XF_NEED_DEFAULT_NOT_TO_ACTIVATE_OUTPUT
/// Folger 04/03/09 QA80-13414 COLUMN_SPECIFICATION_FAILS_TO_WORK
/// Sim 11-25-2009 QA81-14731 SUPPORT_MASK_PASSED_CELLS
/// Folger 10/11/2010 ORG-1219-P1 WXT_FAILED_TO_MANIPULATE_DATA_FOR_ALL_COLUMNS
//---------------------------------------------------------

#include <oErrMsg.h>
//---- CPY 5/18/2007 SHOULD_USE_VC_FUNCTION_FOR_LT_CHECKING
/*
#include <..\Originlab\DialogEx.h> //ExtractWksData.h includes Menu class so need to include this header
#include <..\Originlab\ColumnList.h> //ExtractWksData.h includes ColumnList class so need to include this header
#include <..\Originlab\ExtractWksData.h>
*/
//put your own support static functions here

//---- CPY 5/18/2007 INIT_RANGE_IF_USING_DEFAULT
/*
static void _auto_computer_input_range_from_selection(TreeNode& trGetN)
{
		
	Worksheet 	wksIn;
	okxf_resolve_string_get_origin_object(trGetN.iw.strVal, &wksIn);
	if(!wksIn)
		return;
	
	int		nC1, nR1, nC2, nR2;
	
	//to computer r2
	wksIn.GetBounds(nR1, nC1, nR2, nC2);
	
	//to computer c2
	nC2 = wksIn.GetNumCols() - 1;
	int 	nFirstEmptyCol = wks_find_empty_column(wksIn);
	if(-1 != nFirstEmptyCol)
		nC2 = nC2 - nFirstEmptyCol;
	
	
	TreeNode	trC1 = trGetN.c1;
	if( 1 == octree_get_auto_support(&trC1) )
		trC1.nVal = nC1 + 1;
	
	TreeNode	trC2 = trGetN.c2;
	if( 1 == octree_get_auto_support(&trC2) )
		trC2.nVal = nC2 + 1;
	
	TreeNode	trR1 = trGetN.r1;
	if( 1 == octree_get_auto_support(&trR1) )
		trR1.nVal = nR1 + 1;
	
	TreeNode	trR2 = trGetN.r2;
	if( 1 == octree_get_auto_support(&trR2) )
		trR2.nVal = nR2 + 1;
	
}*/
// index with 0 offset and r2,c2 < 0 to indicate finding end of wks
static BOOL _check_wks_range(const Worksheet& wks, int& nC1, int& nR1, int& nC2, int& nR2)
{
	if(nC2 < 0)
	{
		nC2 = wks.FindFirstEmpty();
		if(nC2 < 0) nC2 = wks.GetNumCols()-1;
	}
	///------ Folger 10/11/2010 ORG-1219-P1 WXT_FAILED_TO_MANIPULATE_DATA_FOR_ALL_COLUMNS
	//else if(nC2 >= wks.GetNumCols()-1)
	else if ( nC2 >= wks.GetNumCols() )
	///------ End WXT_FAILED_TO_MANIPULATE_DATA_FOR_ALL_COLUMNS
		return false;
	if(nR1 < 0)
		return false;
	// row range can stay with nR2 = -1
	return true;
}
//----




void wxt(const string& test, const Worksheet& iw, const int& c1, const int& c2, const int& r1, const int& r2, const int& sel, Worksheet& ow, vector& val, vector& pass, int& num)
{
	int nC1 = c1 - 1;
	int nR1 = r1 - 1;
	//---- CPY 5/18/2007 INIT_RANGE_IF_USING_DEFAULT
	//int	nC2 = (-1 == c2)? iw.GetNumCols() - 1 : c2 - 1;	
	//int	nR2 = (-1 == r2)? iw.GetNumRows() - 1 : r2 - 1;
	int nC2 = c2 > 0? c2-1:c2;
	int nR2 = r2 > 0? r2-1:r2;
	if(!_check_wks_range(iw, nC1, nR1, nC2, nR2))
		XF_THROW(XFERR_INVALID_RANGE);
	//----
	
	string	strCondition = test;
	//---- CPY 5/18/2007 SHOULD_USE_VC_FUNCTION_FOR_LT_CHECKING
	//get_correct_LT_expression(test, strCondition);
	if(!ocu_get_correct_LT_expression(test, &strCondition))
		XF_THROW(XFERR_INVALID_CONDITION);
	//---
		
	vector<uint> 	vnRowIndices;
	int 	nNumRows = iw.SelectRows(strCondition, vnRowIndices, nR1, nR2, -1);
	if(-1 == nNumRows)
	{
		XF_THROW(XFERR_INVALID_CONDITION);
		return;
	}
	int		nNumCols = nC2 - nC1 + 1;
	///------ Folger 04/03/09 QA80-13414 COLUMN_SPECIFICATION_FAILS_TO_WORK
	vector<uint> 	vnColIndices;
	vnColIndices.Data(nC1, nC2, 1);
	///------ End COLUMN_SPECIFICATION_FAILS_TO_WORK
	
	int numPass = vnRowIndices.GetSize();
	if(num != NULL)
		num = numPass;
	//------ CPY 5/20/07 ADD_OPTION_TO_SEL_CELLS
	///---Sim 11-25-2009 QA81-14731 SUPPORT_MASK_PASSED_CELLS
	//if(sel)
	//{
	switch (sel)
	{
	case sel_none:
		break;
	case sel_sel:
	///---END QA81-14731 SUPPORT_MASK_PASSED_CELLS
		{
			Grid gg;
			if(gg.Attach(iw))
			{
				vector<int> vnRows; vnRows = vnRowIndices;
				///------ Folger 04/03/09 QA80-13414 COLUMN_SPECIFICATION_FAILS_TO_WORK
				vector<int> vnCols;
				vnCols = vnColIndices;
				///------ End COLUMN_SPECIFICATION_FAILS_TO_WORK
				if(numPass)
					///------ Folger 04/03/09 QA80-13414 COLUMN_SPECIFICATION_FAILS_TO_WORK
					//gg.SetSelection(vnRows);
					gg.SetSelection(vnRows, vnCols);
					///------ End COLUMN_SPECIFICATION_FAILS_TO_WORK
				else
					gg.SetSelection(NULL);
			}
		}
	///---Sim 11-25-2009 QA81-14731 SUPPORT_MASK_PASSED_CELLS
	//}
		break;
	case sel_mask:
		vector<byte> vMask(iw.GetNumRows());
		vMask.Replace(vnRowIndices, 1);
		for ( int ii = 0; ii < vnColIndices.GetSize(); ii++ )
		{
			int nCol = vnColIndices[ii];
			DatasetObject dsObj(iw.Columns(nCol));
			if ( dsObj )
			{
				dsObj.SetMask(vMask);
			}
		}
		break;
	}
	///---END QA81-14731 SUPPORT_MASK_PASSED_CELLS
	//------
	if(ow)
	{
		///------ Folger 04/03/09 QA80-13414 COLUMN_SPECIFICATION_FAILS_TO_WORK
		//vector<uint> 	vnColIndices;
		//vnColIndices.Data(nC1, nC2, 1);
		///------ End COLUMN_SPECIFICATION_FAILS_TO_WORK
		//--- CPY 11/15/08 QA70-12589 WXT_XF_NEED_DEFAULT_NOT_TO_ACTIVATE_OUTPUT
		//iw.Extract(ow, vnRowIndices, vnColIndices);
		DWORD dw = DCTRL_COPY_KEEP_SHEET_NAME;
		//if(activate) cPY 11/22/08 per Max, no need to allow activate
		//	dw |= DCTRL_COPY_MAKE_ACTIVATE;
		iw.Extract(ow, vnRowIndices, vnColIndices, dw);
		//--- end WXT_XF_NEED_DEFAULT_NOT_TO_ACTIVATE_OUTPUT
	
	}
	
	//output 1 or 0 as result to a column
	if(NULL != val)
	{		
		val.SetSize(iw.GetNumRows());
		val = 0;
		for(int ii = 0; ii < numPass; ii++)
		{
			val[vnRowIndices[ii]] = 1;
		}
	}
	
	//output the index of extracted rows
	if(NULL != pass)
	{	
		pass = vnRowIndices + 1;		
	}
}

//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 wxt_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return wxt_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//_auto_computer_input_range_from_selection(trGetN);
	return true;

}

int wxt_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 wxt_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	//---- CPY 5/18/2007 INIT_RANGE_IF_USING_DEFAULT
	/*
	if(0 == nGetNDialog)
	{
		string 	strCond = trGetN.test.strVal;
		if(strCond.IsEmpty())
		{
			nRet = XFEVT_ABORT;
			return;
		}
		
		Worksheet 	wksIn;
		okxf_resolve_string_get_origin_object(trGetN.iw.strVal, &wksIn);
		if(!wksIn.IsValid())
		{
			nRet = XFEVT_ABORT;
			return;
		}	
	}
	
	_auto_computer_input_range_from_selection(trGetN);
	*/
	
}
//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 wxt_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
