#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>
enum{
	type_normal,
	type_topx,
	type_righty,
	type_lefty,
	type_txry,
	type_bxry,
	type_inset,
	type_insetdata,
	type_noxy,
};
enum{
	xaxis_none,
	xaxis_straight,
	xaxis_custom,
};
enum{
	yaxis_none,
	yaxis_straight,
	yaxis_custom,
};
//put additional include files here
#include <..\Originlab\graph_utils.h>
#include <ocUndoIds.h>
/*------------------------------------------------------------------------------*
 * Iris 12/31/2008 QA80-12887-S1 SET_ADDED_LAYER_TO_FIXED_FACTOR_TO_1			*
 * Iris 01/06/2009 QA80-12887-S1 UNDO_SET_ADDED_LAYER_TO_FIXED_FACTOR_TO_1		*
 * Max 1/7/09 v8.0994b CP_SUGGEST_TO_REUSE_INSET.OTP							*
 * Jasmine 02/11/09 NEED_CHECK_IF_ADD_LAYER_FAIL								*
 * Jasmine 03/20/09 CENTRAILIZE_ADD_LAYER_CODE_IN_LAYADD_XF_AND_LAYERMANAGEMENT	*
 * Jasmine 03/23/09 SET_LAYER_NAME_WITH_ADDING_TYPE								*
 * Kenny 03/31/2009 USE_FUNC_GET_INSET_LAYER_SIZE_INSTEAD						*
 * Kenny 04/01/2009 NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER							*
 * Kenny 04/01/2009 ADD_LAYER_LINK_TO_OVERLAPPED_ANCESTOR						*
 * Jasmine 04/07/09 USER_DEFINE_WILL_CHANGE_TYPE_SETTING						*
 * Kenny 04/07/2009 CORRECT_DETERMINE_CODE_CHECKING_LINK_LAYER					*
 * Iris 10/13/2009 QA80-14405 INSET_DATA_LAYER_NEED_KEEP_GROUP_IF_SOURCE_LAYER_HAS_GROUPING
 *------------------------------------------------------------------------------*/

///Kenny 03/31/2009 USE_FUNC_GET_INSET_LAYER_SIZE_INSTEAD
/*
#define		INSET_LAYER_LEFT	75
#define		INSET_LAYER_TOP		0
#define		INSET_LAYER_WIDTH	25
#define		INSET_LAYER_HEIGHT	25
*/
///End USE_FUNC_GET_INSET_LAYER_SIZE_INSTEAD

static void _update_settings_by_type_change(TreeNode& trGetN)
{
	int	nAddingType = trGetN.type.nVal;
	int nActive 	= trGetN.linkto.nVal - 1;
	
	//_enable_disable_axes_and_link_branch(trGetN, false); Jasmine 03/20/09 already called outside
	
	GraphPage 	gp;
	okxf_resolve_string_get_origin_object(trGetN.igp.strVal, &gp);
	
	if(gp && 0 > nActive)
		nActive = gp.Layers().GetIndex();
	
	///Kenny 04/01/2009 ADD_LAYER_LINK_TO_OVERLAPPED_ANCESTOR
	if (AUTO_FIND_LAYER_LINK_TO == trGetN.linkto.nVal)
	{
		int nAncestor = get_linked_layer_ancestor(gp, nActive, true);
		if ( nAncestor >= 0 )
			nActive = nAncestor;
	}
	///End ADD_LAYER_LINK_TO_OVERLAPPED_ANCESTOR
	
	///Jasmine 03/20/09 CENTRAILIZE_ADD_LAYER_CODE_IN_LAYADD_XF_AND_LAYERMANAGEMENT
	int 	bottom, left, top, right, xaxis, yaxis;
	bool 	link;
	AddingLayerType _typeObj;
	if( !_typeObj.GetAxisSettings(nAddingType, bottom, left, top, right, link, xaxis, yaxis) )
		ASSERT(0);
	
	trGetN.bottom.nVal 	= bottom;
	trGetN.left.nVal 	= left;
	trGetN.top.nVal 	= top;
	trGetN.right.nVal 	= right;
	trGetN.linkto.nVal 	= link? nActive + 1 : false;
	trGetN.xaxis.nVal 	= xaxis;
	trGetN.yaxis.nVal 	= yaxis;
	///End CENTRAILIZE_ADD_LAYER_CODE_IN_LAYADD_XF_AND_LAYERMANAGEMENT
}

static void _enable_disable_axes_and_link_branch(TreeNode& trGetN, bool bEnable)
{
	TreeNode trStartNode = trGetN.bottom;
	TreeNode trEndNode = trGetN.yaxis;
	
	for(TreeNode trN = trStartNode; ; trN = trN.NextNode)
	{
		trN.Enable = bEnable;
		if(0 == lstrcmp(trN.tagName, trEndNode.tagName))
			break;
	}
}

static void _construct_linkto_list(TreeNode& trGetN)
{
	GraphPage 	gp;
	okxf_resolve_string_get_origin_object(trGetN.igp.strVal, &gp);
	
	vector<string> vsList;
	vsList.Add("None");
	
	for(int nLayer = 0; nLayer < gp.Layers.Count(); nLayer++)
	{
		int 	nn = nLayer + 1;
		string 	str = "Layer" + nn;
		vsList.Add(str);
	}
	string strList;
	strList.SetTokens(vsList, '|');
	trGetN.linkto.SetAttribute(STR_COMBO_ATTRIB, strList);
	
}

//------ Folger 12/21/07 IMPROVE_LAYADD
static void _prepare_gui(TreeNode &trGetN)
{
	_enable_disable_axes_and_link_branch(trGetN, trGetN.userdef.nVal);
	if ( trGetN.type.Enable = !trGetN.userdef.nVal )
		_update_settings_by_type_change(trGetN);
	_construct_linkto_list(trGetN);
}
//------


void layadd(const GraphPage& igp, const int& type, const int& userdef, const int& bottom, const int& left, const int& top, const int& right, const int& linkto, const int& xaxis, const int& yaxis, const int& offset, const int& activate)
{
	UndoBlock ub(ID_MENUTEXT_UNDO_CREATE);
	int nNewLayer;
	int nUnit 		= M_LINK;
	int nSourceLayer= linkto - 1;
	
	/// Kenny 04/01/2009 NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
	const int nAutoInitSizePosition = offset ? ADD_LAYER_INIT_SIZE_POS_MOVE_OFFSET : ADD_LAYER_INIT_SIZE_POS_SAME_AS_PREVIOUS;
	///End NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
	
	AddingLayerType _typeObj;
	if( _typeObj.IsInset(type) )
	{
		///Kenny 03/31/2009 USE_FUNC_GET_INSET_LAYER_SIZE_INSTEAD
		/*
		int		nLeft = INSET_LAYER_LEFT;
		int		nTop = INSET_LAYER_TOP;
		int		nWidth = INSET_LAYER_WIDTH;
		int		nHeight = INSET_LAYER_HEIGHT;
		*/
		int		nLeft, nTop, nWidth, nHeight;
		_typeObj.GetInsetLayerSize(&nLeft, &nTop, &nWidth, &nHeight);
		///End USE_FUNC_GET_INSET_LAYER_SIZE_INSTEAD
		/// Kenny 04/01/2009 NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
		/// Iris 01/06/2009 v8.0993e ADD_LAYER_BY_INSET8_OTP_TO_SET_SIZE_ON_AXIS_LABEL
		//nNewLayer = page_add_layer(igp, bottom, left, top, right, true, nSourceLayer, xaxis, yaxis, &nUnit, &nLeft, &nTop, &nWidth, &nHeight);	
		//nNewLayer = page_add_layer(igp, bottom, left, top, right, true, nSourceLayer, xaxis, yaxis, &nUnit, &nLeft, &nTop, &nWidth, &nHeight, -1, "inset8");	///Max 1/7/09 v8.0994b CP_SUGGEST_TO_REUSE_INSET.OTP
		//nNewLayer = page_add_layer(igp, bottom, left, top, right, true, nSourceLayer, xaxis, yaxis, &nUnit, &nLeft, &nTop, &nWidth, &nHeight, -1, "inset");
		nNewLayer = page_add_layer(igp, bottom, left, top, right, nAutoInitSizePosition, activate, nSourceLayer, xaxis, yaxis, &nUnit, &nLeft, &nTop, &nWidth, &nHeight, -1, "inset");
		///end ADD_LAYER_BY_INSET8_OTP_TO_SET_SIZE_ON_AXIS_LABEL
		///End NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
		
		if(_typeObj.IsInsetData(type) && nNewLayer > 0)
		{
			GraphLayer glSource = igp.Layers(nSourceLayer);
			GraphLayer glNew = igp.Layers(nNewLayer);
			if( glSource && glNew )
			{
				foreach(DataPlot dp in glSource.DataPlots)
				{
					glNew.AddPlot(dp);
				}	
				
				/// Iris 10/13/2009 QA80-14405 INSET_DATA_LAYER_NEED_KEEP_GROUP_IF_SOURCE_LAYER_HAS_GROUPING
				vector<int> vn;
				glSource.DataplotsGrouping(vn, false);
				glNew.DataplotsGrouping(vn, true);
				///end INSET_DATA_LAYER_NEED_KEEP_GROUP_IF_SOURCE_LAYER_HAS_GROUPING
				
				glNew.Rescale();
			}
		}
		
		/// Iris 01/06/2009 QA80-12887-S1 UNDO_SET_ADDED_LAYER_TO_FIXED_FACTOR_TO_1
		//layer_set_scale_elements(igp.Layers(nNewLayer), 1, 1); /// Iris 12/31/2008 QA80-12887-S1 SET_ADDED_LAYER_TO_FIXED_FACTOR_TO_1
		///end UNDO_SET_ADDED_LAYER_TO_FIXED_FACTOR_TO_1
	}
	else
	{
		///Kenny 04/07/2009 CORRECT_DETERMINE_CODE_CHECKING_LINK_LAYER
		///Folger 06/20/07 SEPARATE_USER_DEFINED_FROM_TYPE
		//if(type_normal == type || (type_User_Defined == type && nSourceLayer == -1))
		//if( !_typeObj.IsLink(type) || (userdef && nSourceLayer == -1) )
		if( (!userdef && !_typeObj.IsLink(type)) || (userdef && nSourceLayer == -1) )
		///End SEPARATE_USER_DEFINED_FROM_TYPE
		///End CORRECT_DETERMINE_CODE_CHECKING_LINK_LAYER
			nUnit = M_PERCENT;
			
		/// Kenny 04/01/2009 NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
		nNewLayer = page_add_layer(igp, bottom, left, top, right, nAutoInitSizePosition, activate, nSourceLayer, xaxis, yaxis, &nUnit);	
		/// End NEW_FEATURE_TO_FUNC_PAGE_ADD_LAYER
	}
	
	///Jasmine 02/11/09 NEED_CHECK_IF_ADD_LAYER_FAIL
	if(nNewLayer < 0)
		XF_THROW(XFERR_FAIL_TO_ADD_LAYER);
	///End NEED_CHECK_IF_ADD_LAYER_FAIL
	
	//------Folger 07/20/07 REMOVE_LEGEND_FROM_NEW_LAYER_IS_NEEDED
	GraphLayer glNew = igp.Layers(nNewLayer);
	if (glNew)
	{
		//glNew.RemoveGraphObject("Legend");///Jasmine 03/25/09 page_add_layer_SHOULD_NOT_ADD_LEGEND, move in page_add_layer
		
		///Jasmine 03/23/09 SET_LAYER_NAME_WITH_ADDING_TYPE
		string strName;
		//if( !glNew.GetName(strName) )	///Jasmine 04/07/09 USER_DEFINE_WILL_CHANGE_TYPE_SETTING
		if( !userdef && !glNew.GetName(strName) )
		{
			strName = _typeObj.GetAddingName(type);
			glNew.SetName(strName, OCD_ENUM_NEXT);
		}
		///End SET_LAYER_NAME_WITH_ADDING_TYPE
	}
	//------End REMOVE_LEGEND_FROM_NEW_LAYER_IS_NEEDED
	//page_set_active_layer(igp, nNewLayer, false);
}

//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 layadd_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return layadd_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	//------ Folger 12/21/07 IMPROVE_LAYADD
	if ( nEventID == GETNE_ON_THEME )
	{
		_prepare_gui(trGetN);
		return true;
	}
	//------
	
	if( 0 == lstrcmp(lpcszNodeName, "type") )
	{
		//trGetN.userdef.nVal = 0;		///Folger 06/20/07 SEPARATE_USER_DEFINED_FROM_TYPE
		_enable_disable_axes_and_link_branch(trGetN, trGetN.userdef.nVal);		//------ Folger 12/21/07 IMPROVE_LAYADD
		_update_settings_by_type_change(trGetN);
	}
	
	if( 0 == lstrcmp(lpcszNodeName, "userdef") )
	{
		_enable_disable_axes_and_link_branch(trGetN, trGetN.userdef.nVal);
		//------ Folger 12/21/07 IMPROVE_LAYADD
		if ( trGetN.type.Enable = !trGetN.userdef.nVal )
			_update_settings_by_type_change(trGetN);
		//------
	}
		
	if( 0 == lstrcmp(lpcszNodeName, "igp") )		
	{
		_construct_linkto_list(trGetN);
	}
	
	if( 0 == lstrcmp(lpcszNodeName, "linkto") || 0 == lstrcmp(lpcszNodeName, "type"))		
	{
		/// Iris 02/12/2007 v8.0560 DISABLE_ALL_OPTIONS_FOR_BUILDIN_TYPES
		/*
		if(0 == trGetN.linkto.nVal)//0: None
		{
			trGetN.xaxis.Enable = false;
			trGetN.xaxis.nVal = 0;
			
			trGetN.yaxis.Enable = false;
			trGetN.yaxis.nVal = 0;
		}
		else
		{
			trGetN.xaxis.Enable = true;
			trGetN.yaxis.Enable = true;
			
		}
		*/
		///end DISABLE_ALL_OPTIONS_FOR_BUILDIN_TYPES
	}
	
	return true;

}

int layadd_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 layadd_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	//------ Folger 12/21/07 IMPROVE_LAYADD
	//_update_settings_by_type_change(trGetN);	
	//
	//_construct_linkto_list(trGetN);
	if ( nGetNDialog >= 0 )
		_prepare_gui(trGetN);
	//------
}
//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 layadd_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
