#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
/// Modificaiton Log 
//CPY 6/13/07, clean up, and rewrite, will need to remove all comments later
/*
nRet:
v1.Size > v2.Size : -1
v1.Size < v2.Size : -2
v1.Size == v2.Size : Size
*/
static int _vector_size(const vector v1, const vector v2)
{
	int nSize1 = v1.GetSize();
	int nSize2 = v2.GetSize();
	return nSize1 > nSize2 ? -1 : (nSize1 < nSize2 ? -2 : nSize1);
}
static bool _is_element_repeated(vector vSrc)
{
	int nSize = vSrc.GetSize();
	vSrc.Sort();
	for (int ii=0; ii<nSize -1; ii++)
	{
		if (vSrc[ii] == vSrc[ii+1]) return true;
	}
	return false;
}

static bool _is_binary(const vector &vSrc)
{
	int nSize = vSrc.GetSize();
	for (int ii=0; ii<nSize; ii++)
	{
		if (vSrc[ii]!=0 && vSrc[ii]!=1) return false;
	}
	return true;
}

//CPY 6/13/07 these code are too slow and do not actually handle text, so should not do sorting like this
/*
static VU _vector_order(const vector &v1, vector &v2, int order, int missing)
{
	VU vuOrder;
	int nSize1 = v1.GetSize();
	int nSize2 = v2.GetSize();
	vuOrder.Data(0, nSize2 -1);
	int ii, jj;
	while (1)
	{
		while (jj<nSize1 && jj<nSize2 && (jj==0 || v1[jj] == v1[jj-1])) jj++;
		if (jj - ii > 1)
		{
			VU vuOrd;
			vector vTmp;
			v2.GetSubVector(vTmp, ii, jj-1);
			vTmp.Sort(order, missing, vuOrd);
			vuOrd += ii;
			v2.SetSubVector(vTmp, ii);
			vuOrder.SetSubVector(vuOrd, ii);
		}
		ii = jj;
		if (ii == nSize1 || ii == nSize2) break;
		jj++;
	}
	return vuOrder;
}

static void _reorder(Worksheet &w, int col, const VU &vuOrder)
{
	Dataset dsSel(w, col);
	Dataset dsTmp(dsSel);
	int nSize = vuOrder.GetSize();
	dsTmp.SetSize(nSize);
	if (dsSel.GetSize() < nSize)
	{
		dsSel.SetSize(nSize);
	}
	for (int ii=0; ii<nSize; ii++)
	{
		if (ii != vuOrder[ii]) dsSel[ii] = dsTmp[vuOrder[ii]];
	}
}
*/


void wsort(Worksheet& w, const int& bycol, const int& descending, const int& sortnumeric, const vector& nestcols, const vector& order, const int& c1, const int& c2, const int& r1, const int& r2, const int& missing)
{
	
	if(!w)
		XF_THROW(CER_NO_WORKSHEET)
	BOOL bMissingSmallest = missing?false:true;
	// first to see if we are doing nested sort
	if(NULL == nestcols) // not nested, sorting by a single col
	{
		int nCntrl = descending? SORT_DESCENDING:SORT_ASCENDING;
		if (sortnumeric)
			nCntrl |= SORT_NUMERIC_SUFFIX;
		if(w.Sort(bycol-1, nCntrl, bMissingSmallest, r1-1, c1-1, r2-1,c2-1))
			return;
		XF_THROW(XF_OC_METHOD_ERR)
	}
	
	// nested sort
	int nSize;
	if ((nSize = _vector_size(nestcols, order)) < 0)
	{
		XF_THROW(_L("Criteria Columns and rules must be the same size"));
	}
	if (_is_element_repeated(nestcols))
	{
		XF_THROW(_L("Criteria Columns has repeated elements"));
	}
	if (!_is_binary(order))
	{
		XF_THROW(_L("Input rules error"));
	}
	vector<int> vnSortByCols;
	vnSortByCols = nestcols-1; // convert from LT to OC
	vector<BOOL> vbOrder;
	vbOrder = order;
	if(w.Sort(vnSortByCols, vbOrder, bMissingSmallest, r1-1, c1-1, r2-1,c2-1))
		return;
	
	XF_THROW(XF_OC_METHOD_ERR)
	
	
}

//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 wsort_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
