// RcMouseToolExample.h : Declaration of the CRcMouseToolExample
/**
Mouse tool example.

Example shows how to create commands which serve as mouse tools by implementing IRsToolEx interface. Example uses simplified version (IRsTool) for message 
processing but for compatibility with other system tools it implements IRsToolEx::GetToolPriority to handle only events it requires.

Example handles click and drag and changes field of view of picked view camera.

To test this example, type ToolMng.ActivateTool('{17D544A3-3F58-436B-83E7-F8B4D7D4E7C5}','{3BB562B4-A1CC-4f86-BC0C-1A79E41B459C}') to command prompt.


{17D544A3-3F58-436B-83E7-F8B4D7D4E7C5} is View3d window uuid
{3BB562B4-A1CC-4f86-BC0C-1A79E41B459C} is IRcMouseToolExample uuid, 

*/

#pragma once
#include "resource.h"


// IRcMouseToolExample
[
	object,
	uuid("3BB562B4-A1CC-4f86-BC0C-1A79E41B459C"),
	helpstring("IRcMouseToolExample Interface"),
	pointer_default(unique)
]
__interface IRcMouseToolExample : IUnknown
{
};


// CRcMouseToolExample

class ATL_NO_VTABLE CRcMouseToolExample : 
    public CComObjectRootEx<CComMultiThreadModel>,
    public IRsUnknownNode,
    public IRsCommand,
	public IRsToolEx,
	public IRcMouseToolExample
{
public:
    CRcMouseToolExample()
    {
    }

    BEGIN_COM_MAP(CRcMouseToolExample)
        COM_INTERFACE_ENTRY(IRcMouseToolExample)
        COM_INTERFACE_ENTRY(IRsUnknownNode)
        COM_INTERFACE_ENTRY(IRsCommand)
        COM_INTERFACE_ENTRY(IRsTool)
		COM_INTERFACE_ENTRY(IRsToolEx)
        COM_INTERFACE_ENTRY2(IUnknown, IRsUnknownNode)
        COM_INTERFACE_ENTRY2(IRsObject, IRsUnknownNode)
        COM_INTERFACE_ENTRY_AGGREGATE(DEF_GUIDNAME(IRsBaseNode), m_pUnkAgg.p)
        COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_pUnkAgg.p)    // Just for safety, used only for unknown interfaces
    END_COM_MAP()

    DECLARE_GET_CONTROLLING_UNKNOWN()
    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct();

    void FinalRelease() 
    {
        m_pUnkAgg.Release();
    }

public:
    // IRsObject
    RS_DECLARE_IRS_OBJECT(IRcMouseToolExample, L"Mouse tool example")

    // IRsUnknownNode
    STDMETHOD(OnGetValue)(CONID conID, IRsDataCache* pDataCache, VARIANT* pVtData, RtBool* pHandled);
    STDMETHOD(OnSetValue)(CONID conID, IRsDataCache* pDataCache, VARIANT* pvtData, RtBool* pHandled);
    STDMETHOD(OnDefaultValue)(CONID conID, VARIANT* pVtData, RtBool* pHandled);
    STDMETHOD(OnInvalidate)(CONID conID, RtBool* pHandled);
    STDMETHOD(OnInitialize)(void);
    STDMETHOD(OnLoadDefault)(void);
    STDMETHOD(OnDestroy)(void);

    // IRsCommand
    STDMETHOD(Execute)(void);
    STDMETHOD(Undo)(void);
    STDMETHOD(Redo)(void);
    STDMETHOD(HasUndo)(RtBool* isUndoable);
    
    // IRsTool
    STDMETHOD(OnPress)(RtMouseEvent* pEvent, IRsNode* pViewNode);
    STDMETHOD(OnDrag)(RtMouseEvent* pEvent);
    STDMETHOD(OnRelease)(RtMouseEvent* pEvent);

	// IRsToolEx
	STDMETHOD(GetToolPriority)(RtMouseEvent *pMouseEvent,IRsNode *pViewNode,RtUlong *pPriority);
	STDMETHOD(OnToolRemove)();
	STDMETHOD(OnFocusLost)();
	STDMETHOD(OnFocus)();
	STDMETHOD(ProcessMouseEvent)(RtMouseEvent *pMouseEvent,IRsNode *pViewNode);
	STDMETHOD(IsToolLocked)(RtBool *pbLocked);

 
private:

    CComPtr<IUnknown> m_pUnkAgg;
	CComPtr<IRsNode>  m_spCameraNode;
	int				  m_yStartPos;
	CComVariant		  m_vOldFov;

};
