#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	unit_page,
	unit_inch,
	unit_cm,
	unit_mm,
	unit_pixel,
	unit_point,
	unit_link,
};
#include <..\Originlab\graph_utils.h>
#include <event_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

#define STR_INDICES_OF_LAYERS_TO_LINK_INVALID _L("Indices of Layers to link must be larger than that of the Layer to be linked")		///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER

//----Jake 06/07/07 ADD_ERROR_CHECKING
///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
//static int _check_error(TreeNode& trGetN)
static int _check_error(TreeNode& trGetN, string& strErrMsg)
///End INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
{
	GraphLayer gl;
	GraphPage gp;
	okxf_resolve_string_get_origin_object(trGetN.igl.strVal, &gl);
	
	if(!gl.IsValid())
	{
		///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
		//return CER_INVALID_GRAPH;
		strErrMsg = CER_INVALID_GRAPH;
		return false;
		///End INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	}
	
	vector<int> vnNums;
	okxf_resolve_string_get_origin_object(trGetN.igp.strVal, &gp);
	int nErr = get_indices_from_origin_object_index_range_string(trGetN.destlayers.strVal, vnNums, gp.Layers.Count());
	//if(CER_NO_ERROR != nErr)
			//strErrMsg = nErr;
	///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	//return nErr;
	if(nErr != CER_NO_ERROR)
	{
		strErrMsg = nErr;
		return false;
	}
	
	int nParentLayer = gl.GetIndex() + 1;		// 1 offset
	for(int ii=0; ii<vnNums.GetSize(); ii++)
	{
		if(vnNums[ii] <= nParentLayer)
		{
			strErrMsg = STR_INDICES_OF_LAYERS_TO_LINK_INVALID;
			return false;
		}
	}
	return true;
	///End INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
}
//----end ADD_ERROR_CHECKING

void laylink(const GraphPage& igp, const GraphLayer& igl, const string& destlayers, const int& XAxis, const int& YAxis, const int& unit)
{
	if(!igp || !igl)
		XF_THROW(CER_INVALID_ARGUMENT);	
	//----Jake 05/10/07 ADD_GET_LAYERS_FROM_STRDEST
	//	vector<string> vs;
	//	int nSize = destlayers.GetTokens(vs, '|'), nParentLayer = igl.GetIndex(), nUnit = unit;
	vector<int> vnLayers;
	int nParentLayer = igl.GetIndex(), nUnit = unit;
	int nMax = igp.Layers.Count();
	int nErr = get_indices_from_origin_object_index_range_string(destlayers, vnLayers, nMax);
	if(CER_NO_ERROR != nErr)
		XF_THROW(nErr);	
	///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	for(int ii=0; ii<vnLayers.GetSize(); ii++)
	{
		if(vnLayers[ii] <= nParentLayer + 1)
			XF_THROW(STR_INDICES_OF_LAYERS_TO_LINK_INVALID);
	}
	///End INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	
	BEFORE_UNDO_BLOCK	//------ Folger 08/08/07 GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE
	for(int ii = 0; ii < vnLayers.GetSize(); ii++)
	{
		int index = vnLayers[ii] -1;
		GraphLayer gl = igp.Layers(index);
		if(gl.IsValid())
			layer_set_link(gl, nParentLayer, XAxis, YAxis, &nUnit);
	}
	AFTER_UNDO_BLOCK	//------ Folger 08/08/07 GROUP_OPERATION_AS_BLOCK_TO_UNDO_ONCE
	//for(int ii = 0; ii < nSize; ii++)
	//{
		//GraphLayer gl = igp.Layers(atoi(vs[ii]) - 1);
		//if(gl.IsValid())
			//layer_set_link(gl, nParentLayer, XAxis, YAxis, &nUnit);
	//}
	//----end ADD_GET_LAYERS_FROM_STRDEST
}

//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 laylink_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return laylink_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	///Kyle 01/20/2009 INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	//int nErr = _check_error(trGetN);
	//if(CER_NO_ERROR != nErr)
	//{
		//bOKEnable = false;
		//strErrMsg = nErr;
	//}
	bOKEnable = _check_error(trGetN, strErrMsg);
	///End INDICES_OF_LAYERS_TO_LINK_MUST_LARGER_THAN_THAT_OF_INPUT_LAYER
	return false;

}

int laylink_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 laylink_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	///Kyle 01/22/2009 SET_DEFAULT_OF_DESTLAYERS_AS_EMPTY
	/////Jake 06/25/07 GET_ACTIVE_LAYER_FROM_DEST_LAYER_STRING
	//if(trGetN.destlayers.strVal.CompareNoCase(STR_ACTIVE) == 0)
	//{
	//GraphLayer layer = Project.ActiveLayer();
	//if(layer)
	//{
		//int nIndex = layer.GetIndex() +1;
		//trGetN.destlayers.strVal = nIndex;
	//}
	//}
	/////end GET_ACTIVE_LAYER_FROM_DEST_LAYER_STRING
	///End SET_DEFAULT_OF_DESTLAYERS_AS_EMPTY
}
//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 laylink_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
