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

//put additional include files here
#include <event_utils.h>		//------ Folger 08/07/07 MS2O_IMPROVEMENT
//put your own support static functions here

//------ Folger 08/07/07 MS2O_IMPROVEMENT
/// Hong 08/23/07 v8.0688 IMPROVE_CODE_NOT_CHECK_OUTPUT_MLAYER
//static int _check_the_same_dimension(const MatrixPage &mp, string strSheets, vector<int> &vnLayers = NULL)
static int _check_the_same_dimension(const MatrixPage &mp, string strSheets, vector<int> &vnLayers = NULL, const MatrixLayer& destMLayer = NULL)
/// end IMPROVE_CODE_NOT_CHECK_OUTPUT_MLAYER
{
	vector<int> vnLayersTmp;
	int nMax = mp.Layers.Count();
	int nErr = get_indices_from_origin_object_index_range_string(strSheets, vnLayersTmp, nMax);
	if (nErr != CER_NO_ERROR)
		return nErr;

	int nSize = vnLayersTmp.GetSize();
	/// Hong 08/23/07 v8.0688 IMPROVE_CODE_NOT_CHECK_OUTPUT_MLAYER
	/*
	for (int ii=0; ii<nSize-1; ii++)
	{
		MatrixLayer ml1 = mp.Layers(vnLayersTmp[ii] - 1);
		MatrixLayer ml2 = mp.Layers(vnLayersTmp[ii+1] - 1);
		if (ml1.GetNumCols() != ml2.GetNumCols() || ml1.GetNumRows() != ml2.GetNumRows())
			return CER_DIFFERENT_DIMENSION;
	}
	*/
	if ( nSize > 0)
	{
		MatrixLayer ml1 = mp.Layers(vnLayersTmp[0] - 1), ml2;
		for (int ii =1; ii < nSize; ii++)
		{		
			ml2 = mp.Layers(vnLayersTmp[ii] - 1);
			if ( NULL != destMLayer && destMLayer == ml2 )
				continue;
			
			if ( ml1.GetNumCols() != ml2.GetNumCols() || ml1.GetNumRows() != ml2.GetNumRows() )
				return CER_DIFFERENT_DIMENSION;
		}
	}
	/// end IMPROVE_CODE_NOT_CHECK_OUTPUT_MLAYER
	
	if (vnLayers)
		vnLayers = vnLayersTmp;
	return CER_NO_ERROR;
}
//------ End MS2O_IMPROVEMENT

void ms2o(const MatrixPage& imp, const string& sheets, MatrixLayer& oms)
{
	//------ Folger 08/07/07 MS2O_IMPROVEMENT
	/*
	int nSheet = s1 - 1;
	if( nSheet < 0 )
		nSheet = 0;
	
	int nLastSheet = s2 - 1;
	if( nLastSheet < 0 )
		nLastSheet = mpi.Layers.Count();
	
	while( nSheet <= nLastSheet )
	{
		MatrixLayer mlSrc = mpi.Layers(nSheet++);
		if( !mlSrc )
			continue;
	
		/// EJP 2006-12-15 v8.0527 QA70-8682 XF_MS2O_TO_NEW_SHEET_IN_SAME_BOOK_FAIL
		if( mlSrc == mso )
			continue; // Nothing to do
		/// end XF_MS2O_TO_NEW_SHEET_IN_SAME_BOOK_FAIL
	
		UINT nCount = mlSrc.MatrixObjects.Count();
		if( 0 == nCount )
			continue;
	
		while( nCount-- )
		{
			// When moving all object in a loop we always move the first
			// object because after it is moved the other objects will
			// shift causing the 2nd object to become the 1st object.
			MatrixObject moSrc = mlSrc.MatrixObjects(0);
			if( !matobj_move(moSrc, mso) )
				XF_THROW(ERR_FAIL_MOVE); // error moving object
		}
	}
	*/
	vector<int> vnLayers;
	int nMax = imp.Layers.Count();
	//int nErr = _check_the_same_dimension(imp, sheets, vnLayers);
	int nErr = _check_the_same_dimension(imp, sheets, vnLayers, oms); /// Hong 08/23/07 v8.0688 IMPROVE_CODE_NOT_CHECK_OUTPUT_MLAYER
	if(nErr != CER_NO_ERROR)
		XF_THROW(nErr);
	
	int nSize = vnLayers.GetSize();
	int nTotal = 0;
	for (int ii=0; ii<nSize; ii++)
	{
		MatrixLayer mlSrc = imp.Layers(vnLayers[ii] - 1 - ii);
		string strSrcName = mlSrc.GetName();
		if (!mlSrc || mlSrc == oms)
			continue;
		
		int nCount = mlSrc.MatrixObjects.Count();
		bool bEnum = false;
		for (int jj=0; jj<nCount; jj++)
		{
			MatrixObject moSrc = mlSrc.MatrixObjects(0);
			string strLongName = moSrc.GetLongName();
			///Kyle 08/05/2010 ORG-723-P1 COPY_PALETTE_INFO_FOR_MO2S_AND_MS2O
			//if (!matobj_move(moSrc, oms))
			if (!matobj_move(moSrc, oms, true))
			///End COPY_PALETTE_INFO_FOR_MO2S_AND_MS2O
				XF_THROW(XFERR_MOVE_MATOBJ_FAILED);
			MatrixObject moDes = oms.MatrixObjects(nTotal++);
			if (strLongName.IsEmpty())
			{
				strLongName = strSrcName;
				if (jj > 0)
					strLongName += "_" + (jj + 1);
			}
			moDes.SetLongName(strLongName);
		}
		
		mlSrc.Destroy();
	}
	//------ End MS2O_IMPROVEMENT
}

//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 ms2o_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return ms2o_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//------ Folger 08/07/07 MS2O_IMPROVEMENT
	//if (trGetN.method.nVal == 1)
		//trGetN.option.Show = true;
	//else
		//trGetN.option.Show = false;
		
	MatrixPage mp;
	okxf_resolve_string_get_origin_object(trGetN.imp.strVal, &mp);
	if (!mp)
	{
		strErrMsg = CER_NO_MATRIX;
		bOKEnable = false;
		return 0;
	}
	
	if (trGetN.sheets.strVal.IsEmpty())
	{
		strErrMsg = CER_EMPTY_VARIABLE;
		strErrMsg += ":" + _L("Input Index");
		bOKEnable = false;
		return 0;
	}
	
	int nErr;
	if ((nErr = _check_the_same_dimension(mp, trGetN.sheets.strVal)) != CER_NO_ERROR)
	{
		strErrMsg = nErr;
		bOKEnable = false;
		return 0;
	}
	//------ End MS2O_IMPROVEMENT
	return true;

}

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