#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
#include <event_utils.h>
#include <GetNbox.h>
#include <..\originlab\theme_utils.h>

//------ Folger 08/08/07 GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE
#define BEFORE_UNDO_BLOCK				int idBefore = Project.UndoBlockId(); { UndoBlock block;
#define AFTER_UNDO_BLOCK				} int idAfter = Project.UndoBlockId();
//------ End GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE

void _converse_row(const Worksheet &wks, int &nRow)
{
	if (nRow < 0)
	{
		int nLabelType = wks.GetLabelType(nRow);
		if (nLabelType < 0)
		{
			nLabelType = okutil_convert_negative_row_to_label_type(nRow);
			nRow = wks.GetLabelRow(nLabelType);
			//-------------Folger 06/29/07 ADD_INVALID_RANGE_CHECKING
			if (nRow == 0)
				nRow = -(RCLT_MAX_TYPE + 1);
			//-------------Folger 06/29/07 ADD_INVALID_RANGE_CHECKING
		}
	}
}


void wrowheight(const Range& irng, const double& height)
{
	//------ Folger 01/18/08 QA70-10946 SUPPORT_MULTIPLE_SHEETS_OPERATION_WITH_SHEET_RANGE_LIST_CLASS
	/*
	int nSubRange = irng.GetNumRanges(), r1, r2, c1, c2;
	if(!nSubRange)
		XF_THROW(XFERR_INVALID_ARG)
	Worksheet wks;
	vector<uint> vnRows, vnIndeces, uBegins, uEnds;
	for(int ii = 0; ii < nSubRange; ii++)
	{
		irng.GetRange(ii, r1, c1, r2, c2, wks);
		//-------------Folger 06/28/07 ADD_LABEL_SUPPORT
		_converse_row(wks, r1);
		_converse_row(wks, r2);
		if (r1 == 0 && r2 == -1) r2 = wks.GetNumRows() - 1;
		if (r1 > r2)
		{
			int nTmp;
			nTmp = r1; r1 = r2; r2 = nTmp;
		}
		//if(r1 < 0) r1 = 0;
		//if(r2 < 0) r2 = wks.GetNumRows() - 1;
		//-------------Folger 06/28/07 ADD_LABEL_SUPPORT
		//-------------Folger 06/29/07 ADD_INVALID_RANGE_CHECKING
		if (r1 == -(RCLT_MAX_TYPE + 1) || r2 == -(RCLT_MAX_TYPE + 1))
			XF_THROW(XFERR_INVALID_RANGE);
		//-------------Folger 06/29/07 ADD_INVALID_RANGE_CHECKING
		for(int nRow = r1; nRow <= r2; nRow++)
		{
			if(1 > vnRows.Find(vnIndeces, nRow))
				vnRows.Add(nRow);			
		}
	}
	int nRange = find_contiguous_range(vnRows, uBegins, uEnds);
	BEFORE_UNDO_BLOCK	//------ Folger 08/08/07 GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE
	for(ii = 0; ii < nRange; ii++)
		wks_set_cell_heights(wks, uBegins[ii], uEnds[ii], height*100, false);
	AFTER_UNDO_BLOCK	//------ Folger 08/08/07 GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE
	*/
	SheetRangesList rngList(irng);
	int nNumSheet = rngList.GetNumSheets();
	
	for ( int ii=0; ii<nNumSheet; ++ii )
	{
		int nNumSubRange = rngList.GetNumSubRange(ii);
		Worksheet wks;
		vector<uint> vnRows, vnIndeces;
		for ( int jj=0; jj< nNumSubRange; ++jj )
		{
			ORANGE orng;
			if ( rngList.GetRange(ii, wks, jj, &orng) )
			{
				_converse_row(wks, orng.r1);
				_converse_row(wks, orng.r2);
				if (orng.r1 == 0 && orng.r2 == -1) orng.r2 = wks.GetNumRows() - 1;
				if (orng.r1 > orng.r2)
				{
					int nTmp;
					nTmp = orng.r1; orng.r1 = orng.r2; orng.r2 = nTmp;
				}
				if (orng.r1 == -(RCLT_MAX_TYPE + 1) || orng.r2 == -(RCLT_MAX_TYPE + 1))
					XF_THROW(XFERR_INVALID_RANGE);
				for(int nRow = orng.r1; nRow <= orng.r2; nRow++)
				{
					if(1 > vnRows.Find(vnIndeces, nRow))
						vnRows.Add(nRow);			
				}
			}
		}
		if ( wks )
		{
			vector<uint> uBegins, uEnds;
			int nRange = find_contiguous_range(vnRows, uBegins, uEnds);
			for(jj = 0; jj < nRange; jj++)
				wks_set_cell_heights(wks, uBegins[jj], uEnds[jj], height*100, false);
		}
	}
	//------ End SUPPORT_MULTIPLE_SHEETS_OPERATION_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 wrowheight_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return wrowheight_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	int nErrCode = check_1_column(trGetN.irng, true, false);
	if(nErrCode != CER_NO_ERROR)
	{
		bOKEnable = false;
		strErrMsg = nErrCode;
		if(nErrCode == CER_ROW_NUM_TOO_FEW_EX)
			strErrMsg += ":" + 1;
	}
	if(GETNE_ON_INIT == nEventID && !lstrlen(trGetN.height.strVal))
	{
		int r1, r2, c1, c2;
		Worksheet wks;
		Range rData;
		TreeNode trRange = trGetN.irng;
		okxf_resolve_tree_construct_range(&trRange, &rData);
		if(rData && rData.GetNumRanges())
			rData.GetRange(0, r1, c1, r2, c2, wks);
		int nSize = wks_get_cell_heights(wks, r1, r2, false);
		trGetN.height.strVal = (string)(nSize/100.0);
	}
	if (trGetN.height.dVal < 0)
	{
		strErrMsg = CER_INVALID_POSITIVE_INTEGER;
		strErrMsg += ":" + _L("Input Height");
		bOKEnable = false;
		return true;
	}
	return true;

}

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

}
//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 wrowheight_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
