#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
//put additional include files here
///////////// modification log /////////////
//CPY 6/25/09 COPY_COL_LN_NEEDED
//Kenny 11/18/2009 QA81-14679-P1 IMPROVE_XF_WRCOPY_TO_SUPPORT_APPENDING_DATA_BY_ROW 
//Kenny 12/4/2009 QA81-14679-P6 WRCOPY_SHOULD_ALLOW_COPY_TO_SAME_SHEET_IF_NOT_INTERSECT
//Kenny 12/4/2009 QA81-14679-P7 WRCOPY_NEED_AN_OPTION_TO_COPY_COL_FORMAT
//Kenny 12/7/2009 QA81-14800 WRCOPY_NEED_AN_OPTION_TO_ALLOW_TRANSPOSE_THE_DATA_WHILE_COPYING
//Kenny 12/7/2009 QA81-14679-P8 WRCOPY_FAIL_TO_COPY_THE_LAST_ROW_OF_DATA


///Kenny 12/7/2009 QA81-14800 WRCOPY_NEED_AN_OPTION_TO_ALLOW_TRANSPOSE_THE_DATA_WHILE_COPYING
static int _wrcopy(const Worksheet& iw, 
				Worksheet& ow, 
				int nC1, 
				int nC2, 
				int nR1, 
				int nR2, 
				int nDestC1, 
				int nLNRow = -1, 
				DWORD dwCntrl = 0,
				int nDestR1 = 0, 
				vector<int>* pvnLabelTypes = NULL,
				bool bTranspose = false
				)
{
	///Kenny 12/7/2009 QA81-14679-P8 WRCOPY_FAIL_TO_COPY_THE_LAST_ROW_OF_DATA
	if ( nR2 >= 0 )
	{
		++nR2;	// nR2 is exclusive in Worksheet::CopyTo
	}
	///End QA81-14679-P8 WRCOPY_FAIL_TO_COPY_THE_LAST_ROW_OF_DATA
	
	int nRet = 0;
	if ( bTranspose )
	{
		Worksheet wksTmp;
		BOOL bCreated = wksTmp.Create("Origin", CREATE_TEMP);
		if ( !bCreated )
			XF_THROW(CER_FAILED_CREATE_WKS);
		ASSERT( wksTmp.IsValid() );
		// Column related info should be ignored here since they don't make sense.
		dwCntrl &= ~(CPYT_COPY_COLUMN_LABELS | CPYT_COPY_COLUMN_FORMAT);
		nLNRow = -1;
		
		nRet = iw.CopyTo(wksTmp, nC1, nC2, nR1, nR2, 0, nLNRow, dwCntrl, 0, NULL);
		if (0 == nRet)
		{
			nRet = wksTmp.Transpose();
			if (0 == nRet)
			{
				nRet = wksTmp.CopyTo(ow, 0, -1, 0, -1, nDestC1, nLNRow, dwCntrl, nDestR1, NULL);
			}
		}
		wksTmp.Destroy();
	}
	else
	{
		nRet = iw.CopyTo(ow, nC1, nC2, nR1, nR2, nDestC1, nLNRow, dwCntrl, nDestR1, pvnLabelTypes);
	}
	return nRet;
}
///End QA81-14800 WRCOPY_NEED_AN_OPTION_TO_ALLOW_TRANSPOSE_THE_DATA_WHILE_COPYING


void wrcopy(const Worksheet& iw, Worksheet& ow, const int& c1, const int& c2, const int& r1, const int& r2, const int& name, const int& dc1, const int& dr1, const string& label, const string& hint_label, const int& format, const int& transpose)
{
	if(!iw.IsValid())
		XF_THROW(CER_NO_WORKSHEET);
	
	///Kenny 11/18/2009 QA81-14679-P1 IMPROVE_XF_WRCOPY_TO_SUPPORT_APPENDING_DATA_BY_ROW
	/*DWORD dwCntrl = label?CPYT_COPY_COLUMN_LABELS:0;//CPY 6/25/09 COPY_COL_LN_NEEDED
	
	int nRet = iw.CopyTo(ow, c1-1, c2-1, r1-1, r2-1, dc1-1, name-1, dwCntrl);*/
	
	// These following checking may looks odd but just for backward-compatibility
	bool bCopyAllLabel			= label == "1";
	bool bDoNotCopyLabel		= label == "0";
	bool bCopyLabel				= !bDoNotCopyLabel && label.GetLength() > 0;
	bool bCopySpecifiedLabel	= bCopyLabel && !bCopyAllLabel;
	///Kenny 12/4/2009 QA81-14679-P6 WRCOPY_SHOULD_ALLOW_COPY_TO_SAME_SHEET_IF_NOT_INTERSECT
	//DWORD dwCntrl				= bCopyLabel ? CPYT_COPY_COLUMN_LABELS : 0;
	DWORD dwCntrl				= CPYT_ALLOW_SAME_LAYER_IF_NOT_INTERSECT;
	if (bCopyLabel)
		dwCntrl	|= CPYT_COPY_COLUMN_LABELS;
	///End QA81-14679-P6 WRCOPY_SHOULD_ALLOW_COPY_TO_SAME_SHEET_IF_NOT_INTERSECT
	
	///Kenny 12/4/2009 QA81-14679-P7 WRCOPY_NEED_AN_OPTION_TO_COPY_COL_FORMAT
	if (format)
		dwCntrl	|= CPYT_COPY_COLUMN_FORMAT;
	///End QA81-14679-P7 WRCOPY_NEED_AN_OPTION_TO_COPY_COL_FORMAT
	
	vector<int> vnLabelTypes;
	if( bCopySpecifiedLabel && !okutil_convert_labels_string_to_indices(label, &vnLabelTypes) )
	{
		XF_THROW(CER_UNKNOWN_ERROR);	/// TODO
		return;
	}
	
	///Kenny 12/7/2009 QA81-14800 WRCOPY_NEED_AN_OPTION_TO_ALLOW_TRANSPOSE_THE_DATA_WHILE_COPYING
	//int nRet = iw.CopyTo(ow, c1-1, c2-1, r1-1, r2-1, dc1-1, name-1, dwCntrl, dr1-1, bCopySpecifiedLabel ? &vnLabelTypes : NULL);
	int nRet = _wrcopy(iw, ow, c1-1, c2-1, r1-1, r2-1, dc1-1, name-1, dwCntrl, dr1-1, 
						bCopySpecifiedLabel ? &vnLabelTypes : NULL, 
						transpose);
	///End QA81-14800 WRCOPY_NEED_AN_OPTION_TO_ALLOW_TRANSPOSE_THE_DATA_WHILE_COPYING
	
	///End QA81-14679-P1 IMPROVE_XF_WRCOPY_TO_SUPPORT_APPENDING_DATA_BY_ROW 
	if(nRet != 0)
		out_int("err = ", nRet);
		
}

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

}

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