/*------------------------------------------------------------------------------*
 * File Name:XFMenu.h															*
 * Creation: CPY 5/8/2005														*
 * Purpose: OriginC Header for base menu class X-Function menus					*
 * Copyright (c) Originlab Corp. 	2005				 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP					*
 *------------------------------------------------------------------------------*/

#ifndef _ID_MENU_H_ 
#define _ID_MENU_H_
#include <Control.h>

enum {
	IDM_XF_CANCEL = -100,
	IDM_XF_ANCHOR_MOVED,
};

enum {
	IDM_OUTPUT_SCRIPTWIN = 3050,
	IDM_OUTPUT_RESULTSLOG,
	IDM_OUTPUT_APPEND_WKS,
	
	
	IDM_RECT_SPAN_NONE = 3060,
	IDM_RECT_SPAN_DATA,
	IDM_RECT_SPAN_LAYER,
	
	IDM_UPDATE_ACTIVE_DATA = 3080,
	
	IDM_UPDATE_ON_MOVE,
	
	IDM_OP_THEME_BEGIN = 3100,
	IDM_OP_OPEN_DLG  = 3200,
	
};

class	XFMenu	:	public	Menu
{
public:
	XFMenu(ButtonInfo& biMenu)
	{
		TreeNode tr = biMenu.GetUserData();
		CheckSettings(tr);
		m_tr = tr; // save the tree node
		
		/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
		//biMenu.GetParent(m_grTool);
		biMenu.GetParent(m_ooTool);
		m_grTool = m_ooTool;// OriginObject, may not be gr
		/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
	}
	XFMenu(TreeNode& tr)
	{
		CheckSettings(tr);
		m_tr = tr; // save the tree node
	}
	//---Jasmine 12/12/08 v8.0986 QA80-12715 need overload this in CurveTranslateMenu
	virtual bool ProcessEvents(const EventInfo& ei, const ButtonInfo& biMenu, DataRange& dr, int& nMenuCmd, int nMinPts = 1, LineInfo& ln = NULL, TextInfo& tx = NULL, LPCSTR lpcszInitText = NULL)
	//---
	{
		nMenuCmd = 0;
		switch(ei.GetEvent())
		{
		case OE_INIT_ANCHORS:
			biMenu.Init(OTCIC_COMBOBOX);
			if(ln)
				ln.Init(LN_FREE, LNPOS_CENTER);
			if(tx)
				tx.Init(lpcszInitText, 12);
			
			/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
			//shape_tool_init(m_grTool);
			if( m_grTool )
				shape_tool_init(m_grTool);
			/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
			
			// fall through
		case OE_RESIZE:
			arrange_buttons(biMenu);
			break;
		case OE_MOVE:
			//out_int("sender = ", ei.GetSenderId());
			Selection.Reset(TRUE);
			if(ei.GetSenderId() > 0)
			{
				nMenuCmd = IDM_XF_ANCHOR_MOVED;
				return false;
			}
				
			if(m_tr.Settings.UpdateOnMoveSize)
			{
				if(m_tr.Settings.UpdateOnMoveSize.nVal == 0)
					return false;
			}
			break;
		case OE_BUTTONCLICK:
			if(biMenu.GetID() == ei.GetSenderId())
			{
				nMenuCmd = TrackPopupMenu(GetWindow());
				if(nMenuCmd <= 0)
				{
					nMenuCmd = IDM_XF_CANCEL;
					return false;
				}
			}
			break;
		case OE_XF_MSG:// message received from outside
			processMessage(ei.GetSenderId(), ei.GetSenderParam());
			nMenuCmd = IDM_XF_CANCEL;
			return false;
		default:
			//printf("not processed: %d\n", ei.GetEvent());
			break;
		}
		bool bUpdateTool = nMenuCmd < IDM_OUTPUT_SCRIPTWIN?true:false;
		//bool bActionButton = (OE_BUTTONCLICK == nEvent && bi.GetID() == ei.GetSenderId())? true:false;
		
		/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
		//return find_data_inside_tool(m_grTool, bUpdateTool, dr, biMenu, nMinPts, tx);
		if( !m_grTool )
			return false;
		return find_data_inside_tool(m_grTool, bUpdateTool, dr, biMenu, nMinPts, tx);
		/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
	}
	
	virtual void Construct()
	{
		ConstructDataSelRectOptions();
	}
	// return true if command already processed by handler, no need to pass on
	virtual int TrackPopupMenu(HWND hWndParent, int nx = -1, int ny = -1)
	{
		Construct();// no need to create until we do the TrackPopupMenu
		if(nx < 0)
		{
			POINT pt;
			GetCursorPos(&pt);
			nx = pt.x;
			ny = pt.y;
		}
		int nCmdID = -1;
		Menu::TrackPopupMenu(0, nx, ny, hWndParent, &nCmdID);
		//int nCmdID = Menu::TrackPopupResMenu(0, nx, ny, hWndParent); CPY this didn't work for ID < 3050, so better stick with TrackPopupMenu
		if(nCmdID > 0)
		{
			if(DoCommand(nCmdID))
				return 0; // already processed
			
			return nCmdID; // not yet processed, or still need further processing
		}
		return -1;				
	}
	void Add(LPCSTR lpcszStr, int nMenuID = 0, UINT nFlags = MF_STRING)
	{
		Menu::Add(lpcszStr, DoMenuItem, nFlags, nMenuID);
		//Menu::Add(lpcszStr, nMenuID, nFlags);
	}
	void QuickOutput(int nMenuCmd, const TreeNode& trResults, LPCSTR lpcszWksName = NULL)
	{
		switch(nMenuCmd)
		{
		case IDM_OUTPUT_SCRIPTWIN:
			LT_execute("type -a");//make sure script window is shown
			out_tree(trResults);
			break;
		case IDM_OUTPUT_RESULTSLOG:
			out_str("not yet supported");
			break;
		case IDM_OUTPUT_APPEND_WKS: // to report wks
			out_tree_to_wks(trResults, lpcszWksName);
			break;
		}
	}
protected:
	// this does nothing, but version of Add without handler seems not working with ID < 3050
	void DoMenuItem(UINT nPos)
	{
		// really need to do nothing here
		//out_int("DoMenu = ", nPos);
	}
	void ConstructQuickOutputCommands()
	{
		Add("Output to Script Window", IDM_OUTPUT_SCRIPTWIN);
		Add("Output to Results Log", IDM_OUTPUT_RESULTSLOG);
		Add("Output to Worksheet", IDM_OUTPUT_APPEND_WKS);
	}
	void ConstructOperationCommands()
	{
		Add("Open Dialog...", IDM_OP_OPEN_DLG);
	}
	void ConstructOnMoveOptions()
	{
		int nFlags;		
		nFlags = m_tr.Settings.UpdateOnMoveSize.nVal == 1? MF_CHECKED : MF_UNCHECKED;
		Add("Update On Move", IDM_UPDATE_ON_MOVE, nFlags);
	}
	void ConstructDataSelRectOptions()
	{
		int nFlags;
		int nn;
		BeginPopup("Tool Control");
		nn = m_tr.Settings.RectSpan.nVal;
		nFlags = nn == 0? MF_CHECKED : MF_UNCHECKED;
		Add("Do not Stretch Object", IDM_RECT_SPAN_NONE, nFlags);
		nFlags = nn == 1? MF_CHECKED : MF_UNCHECKED;
		Add("Stretch Object to Show Data", IDM_RECT_SPAN_DATA, nFlags);
		nFlags = nn == 2? MF_CHECKED : MF_UNCHECKED;
		Add("Stretch Object to Layer", IDM_RECT_SPAN_LAYER, nFlags);
		
		AddSeparator();
		
		nFlags = m_tr.Settings.UpdateActiveData.nVal? MF_CHECKED : MF_UNCHECKED;
		Add("Auto Switch Active Dataset", IDM_UPDATE_ACTIVE_DATA, nFlags);
		
		EndPopup();
	}
	void AddSeparator()
	{
		Add(NULL);//--------------- separator
	}
	virtual string GetOperationClassName() {return "";}
	
	virtual bool DoCommand(int nCmdID)
	{
		int nn;
		bool bExit = true;
		switch(nCmdID)
		{
		case IDM_OUTPUT_SCRIPTWIN:
		case IDM_OUTPUT_RESULTSLOG:
		case IDM_OUTPUT_APPEND_WKS:
			return false;// indicate the need for further processing
		case IDM_RECT_SPAN_NONE:
		case IDM_RECT_SPAN_DATA:
		case IDM_RECT_SPAN_LAYER:
			nn = nCmdID - IDM_RECT_SPAN_NONE;
			m_tr.Settings.RectSpan.nVal = nn;
			bExit = false;// still need to process futher to update rect
			break;
		case IDM_UPDATE_ACTIVE_DATA:
			m_tr.Settings.UpdateActiveData.nVal = m_tr.Settings.UpdateActiveData.nVal? 0:1;
			break;
		case IDM_UPDATE_ON_MOVE:
			m_tr.Settings.UpdateOnMoveSize.nVal = m_tr.Settings.UpdateOnMoveSize.nVal? 0:1;
			break;
		case IDM_OP_OPEN_DLG:
			//runOperation();
			/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
			//m_grTool.PostMessage(OE_ON_ATTACHED_XF_MSG, IDM_OP_OPEN_DLG);
			m_ooTool.PostMessage(OE_ON_ATTACHED_XF_MSG, IDM_OP_OPEN_DLG);
			/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
			break;
		}
		return bExit;
	}
	virtual bool CheckSettings(TreeNode& tr)
	{
		if(tr.Settings.RectSpan)
		  return true;// tree already setup
		
		//otherwise we need to construct it
		InitDefaults(tr);
  		return true;
	}
	virtual void InitDefaults(TreeNode& tr)
	{
		tr.Settings.RectSpan.nVal = 1; // data
		tr.Settings.UpdateActiveData.nVal = 1;
  		tr.Settings.UpdateOnMoveSize.nVal = 1;
	}		
protected:
	TreeNode	m_tr;
private:
	GraphObject	m_grTool;
	/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
	OriginObject	m_ooTool;
	/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
	
private:
	void runOperation(int nCmdID = 0)
	{
		string strOPClass = GetOperationClassName();
		if(strOPClass.IsEmpty())
			return;
		bool bOpenGUI = 0==nCmdID? true:false;
		DataPlot dp;
		int i1,i2;
		
		/// RVD 1/16/2009 qa70-12981 MARKER_INFO_SNAP_TO_DATA_CLEANUP
		//if(find_intersect_dataplot(m_grTool, dp, i1, i2, false))
		if( !m_grTool )
			return;
		if(find_intersect_dataplot(m_grTool, dp, i1, i2, false))
		/// end MARKER_INFO_SNAP_TO_DATA_CLEANUP
		{
			DataRange dr;
			dp.GetDataRange(dr, i1, i2);
			do_AU_command(strOPClass, bOpenGUI, NULL, 0, dr);
		}
	}
	void processMessage(int nCmd, DWORD dwParam)
	{
		switch(nCmd)
		{
		case IDM_OP_OPEN_DLG:
			runOperation();
			break;
		}
	}
};


#endif //_ID_MENU_H_

