#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>

#include <o8dlg.h>		//------ Folger 12/05/08 v8.0983 ADD_HELP_FOR_COLINT

/* Modification Log */
//CPY CPY 7/30/08 QA70-11914-P3 WKS_SHOW_SAMPLING_INTERVAL_SHOULD_AUTO_SIZE
/// RVD 7/30/2008 qa70-11914 SAMPLE_INTERVAL_UNDO
/// CPY 9/5/08 QA70-12138 EVEN_SAMPLING_SHOULD_NOT_RESTRICT_TO_Y_ANY_MORE
/// Folger 12/05/08 v8.0983 ADD_HELP_FOR_COLINT

//put additional include files here
#define STR_INPUT_RANGE_NODE_NAME "rng"  
//put your own support static functions here
/// Max 7/9/07 CLEAN_CODE
/*
static void _update_tree_show(TreeNode& trGetN, vector<int>& vCols, Worksheet& wks)
{
	string strUnits, strLongName;
	double x0, xInc;
	for(int ii = 0; ii < vCols.GetSize(); ii++)
	{
		Column col(wks, vCols[ii]);
		if(col.IsEvenSampling(&x0, &xInc, strUnits, strLongName))
		{
			trGetN.x0.dVal = x0;
			trGetN.inc.dVal = xInc;
			trGetN.units.strVal = strUnits;
			trGetN.lname.strVal = strLongName;
			return;
		}
	}
}
*/
/// Max 7/9/07 for simplifying the code, not to get existing sampling interval
/*
static void _update_tree_show(TreeNode& trGetN)
{
	DataRange dr;
	TreeNode trInput = trGetN.r;
	vector<int> vCols;
	Worksheet wks;

	string strUnits, strLongName;
	double x0, xInc;

	if(okxf_resolve_tree_construct_range(&trInput, &dr))
	{
		if(_get_y_col_from_range(dr, vCols, wks))
		{
			/// show first sampling interval in GUI
			for(int ii = 0; ii < vCols.GetSize(); ii++)
			{
				Column col(wks, vCols[ii]);
				if(col.IsEvenSampling(&x0, &xInc, strUnits, strLongName))
				{
					trGetN.x0.dVal = x0;
					trGetN.inc.dVal = xInc;
					trGetN.units.strVal = strUnits;
					trGetN.lname.strVal = strLongName;
					return;
				}
			}
		}
	}
}
*/
///---
/// END CLEAN_CODE

static bool _get_x_and_y_col_from_range(DataRange& dr, vector<int>& vCols, Worksheet& wks)
{
	//Get selected X and Y columns from range
	for(int ii = 0; ii < dr.GetNumRanges(); ii++)
	{
		int r1, r2, c1, c2;
		if(dr.GetRange(ii, r1, c1, r2, c2, wks))
		{
			for(int nCol = c1; nCol <= c2; nCol++)
			{
				Column col(wks, nCol);
				if(col.GetType() != OKDATAOBJ_DESIGNATION_Y && col.GetType() != OKDATAOBJ_DESIGNATION_X)
					continue;
				else
					vCols.Add(nCol);	
			}
		}
	}
	//Haven't seleced any X or Y column
	if(vCols.GetSize() <= 0)
		return false;
	
	return true;
}

static int _check_input_error(TreeNode& trGetN, Worksheet& wks, int& nFirstXY)
{
	DataRange dr;
	TreeNode trInput = trGetN.rng;
	vector<int> vCols;

	int nErr = CER_NO_ERROR;
	
	if(!okxf_resolve_tree_construct_range(&trInput, &dr))
		nErr = XFERR_INVALID_RANGE;
	else if(!_get_x_and_y_col_from_range(dr, vCols, wks))
		nErr = XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED;
	
	if(vCols.GetSize() > 0)
		nFirstXY = vCols[0];
	
	return nErr;
}

static void _set_default_by_first_selected_x_or_y_col(TreeNode& trGetN, Worksheet& wks, int nFirstXY)
{
	Column col(wks, nFirstXY);
	if(col)
	{
		double x0, xInc;
		string strXUnits = NULL, strXLongName = NULL;
		if(!col.IsEvenSampling(&x0, &xInc, strXUnits, strXLongName))
		{
			x0 = 1;
			xInc = 1;
		}
		
		trGetN.x0.dVal = x0;
		trGetN.inc.dVal = xInc;
		trGetN.units.strVal = strXUnits;
		trGetN.lname.strVal = strXLongName;
	}
}


void colint(Range& rng, const double& x0, const double& inc, const string& units, const string& lname, const string& hint)
{
	vector<int> vCols;
	Worksheet wks;
	//------ Folger 01/17/08 QA70-10946 FIX_COLINT_WITH_SHEET_RANGE_LIST_CLASS
	//if(!rng.IsValid() || !_get_y_col_from_range(rng, vCols, wks))
		//XF_THROW(XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED);
	//
	//for(int ii = 0; ii < vCols.GetSize(); ii++)
	//{
		//Column col(wks, vCols[ii]); 
		//if(col)
		//{
			//if(wks.SetEvenSampling(x0, inc, col, units, lname))
				//XF_THROW(XFERR_SET_EVEN_SAMPLING_FAILED);
		//}
	//}
	
	//if(!is_equal(x0, 1.) || !is_equal(inc, 1.))
	//{
		//vector<int> vnLabel;
		//vnLabel.Add(RCLT_SAMPLE_RATE);
		//wks_add_show_labels(wks, vnLabel);
	//}
	
	if ( !rng )
		XF_THROW(XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED);
	SheetRangesList rngList(rng);
	int nNumSheet;
	if ( (nNumSheet = rngList.GetNumSheets()) == 0)
		XF_THROW(XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED);
	
	int nCount = 0;
	bool bUndo = true;	/// RVD 7/30/2008 qa70-11914 SAMPLE_INTERVAL_UNDO
	
	for ( int ii=0; ii<nNumSheet; ++ii )
	{
		int nNumSubRange = rngList.GetNumSubRange(ii);
		for ( int jj=0; jj< nNumSubRange; ++jj )
		{
			ORANGE orng;
			if ( rngList.GetRange(ii, wks, jj, &orng) )
			{
				//------ Folger 02/26/08 QA80-11173 COLINT_NOT_WORK_FOR_SELECT_WHOLE_SHEET
				if ( orng.c2 < 0 )
					orng.c2 = wks.GetNumCols();
				//------
				for ( ; orng.c1<=orng.c2; ++orng.c1 )
				{
					Column col(wks, orng.c1); 
					///------ CPY 9/5/08 QA70-12138 EVEN_SAMPLING_SHOULD_NOT_RESTRICT_TO_Y_ANY_MORE
					//if( col && col.GetType() == OKDATAOBJ_DESIGNATION_Y )
					if(col)
					///------
					{
						/// RVD 7/30/2008 qa70-11914 SAMPLE_INTERVAL_UNDO
						//if(wks.SetEvenSampling(x0, inc, col, units, lname))
						if(wks.SetEvenSampling(x0, inc, col, units, lname, bUndo))
						/// end SAMPLE_INTERVAL_UNDO
							XF_THROW(XFERR_SET_EVEN_SAMPLING_FAILED);
						++nCount;
					}
				}
			}
		}
		if(!is_equal(x0, 1.) || !is_equal(inc, 1.))
		{
			vector<int> vnLabel;
			vnLabel.Add(RCLT_SAMPLE_RATE);
			/// RVD 7/30/2008 qa70-11914 SAMPLE_INTERVAL_UNDO
			//wks_add_show_labels(wks, vnLabel);
			wks_add_show_labels(wks, vnLabel, false, bUndo);
			/// end SAMPLE_INTERVAL_UNDO
			wks.AutoSizeRow(RCLT_SAMPLE_RATE); // CPY CPY 7/30/08 QA70-11914-P3 WKS_SHOW_SAMPLING_INTERVAL_SHOULD_AUTO_SIZE
		}
	}
	
	if ( nCount == 0 )
		warning_msg_box(_L("No X or Y column is selected, set Sampling Interval fail"), false, 'E');
	//------ End FIX_COLINT_WITH_SHEET_RANGE_LIST_CLASS
}

//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 colint_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return colint_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	/// Max 7/9/07 CLEAN_CODE
	/*
	bOKEnable = true;
	//bool bIsChangingData = lstrcmpi(lpcszNodeName, STR_STR_NODE_NAME) == 0? true:false;
	//if(GETNE_ON_INIT == nEventID || bIsChangingData)
	TreeNode tr = trGetN.r;
	DataRange dr;
	if(!okxf_resolve_tree_construct_range(&tr, &dr))
	{
		strErrMsg = XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED;
		bOKEnable = false;
		return false;
	}
	vector<int> vCols;
	Worksheet wks;
	if(!_get_y_col_from_range(dr, vCols, wks))
	{
		strErrMsg = XFERR_NO_ANY_X_OR_Y_COLUMN_SELECTED;
		bOKEnable = false;
		return false;
	}
	
	_update_tree_show(trGetN, vCols, wks);
	*/
	/// Max 7/9/07 for simplifying the code, not to get existing sampling interval
	/*
	bool bIsChangingData = lstrcmpi(lpcszNodeName,STR_INPUT_RANGE_NODE_NAME) == 0? true:false;
	if(GETNE_ON_INIT == nEventID || bIsChangingData || GETNE_ON_THEME == nEventID)
		_update_tree_show(trGetN);
	*/
	//----
	Worksheet wks;
	int nFirstXY;
	int nErr = _check_input_error(trGetN, wks, nFirstXY);
	
	if(nErr != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErr;
	}
	else
	{
		bool bIsChangingData = lstrcmpi(lpcszNodeName, STR_INPUT_RANGE_NODE_NAME) == 0? true:false;
		if(bIsChangingData || GETNE_ON_INIT == nEventID)
			_set_default_by_first_selected_x_or_y_col(trGetN, wks, nFirstXY)
	}
	/// END CLEAN_CODE
	return false;

}

int colint_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 colint_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	//------ Folger 12/05/08 v8.0983 ADD_HELP_FOR_COLINT
	if ( is_xf_startup(nGetNDialog, dwCntrl) )
	{
		if(is_use_origin_chm())
			trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_colint);
	}
	//------ End ADD_HELP_FOR_COLINT
	
	if(0 == nGetNDialog && (dwCntrl&LTXF_THEME_USED) && (dwCntrl&LTXF_FROM_GUI_MENU) )
	{
		Worksheet wks;
		int nFirstXY;
		if(_check_input_error(trGetN, wks, nFirstXY) != CER_NO_ERROR)
			nRet = XFEVT_PROCEED_WITH_DLG;
	}
}
//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 colint_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
