// RcPhysShotCmd.h : Declaration of the CRcPhysShotCmd
/**
Shot example demonstrates how to use a functionality of physics to create own active behavior of objects. Example also demonstrates
passing object's interface (VARIANT) to command using connectors in scripts. 

Shot command creates ten small spheres with phys properties around the given point (vPosition) and gives to each sphere a speed (fPower) direct from the given point
When physics is not running, command starts it. When physics is running, spheres are added directly to simulation.
Command could be used for achieving an effects of bomb, speedy spheres added to simulation interact with other objects and push them, for example.

Execute example typing ExamplesPlugin.Shot(20.0, 0) in a command prompt - 10 spehres will be added around the point (0,0,3) with speed of 20.0

In jscript, you could used example in this way:

var point = System.CreateDO('Math Package/Point Data'); ... create point data object
point.x = 1.0; 
point.y = 1.0;
point.z = 3.4;											... init point object						

ExamplesPlugin.Shot(15.0, point);						... execute command

*/

#pragma once

#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif


//declare ID of a local command node connectors. 
// {25A64F9D-6F51-4393-B20F-F41832E7AA4E}
RS_DEFINE_GUID(CON_SHOT_CENTER,
			   0xb5da0b3c, 0x667d, 0x4fc8, 0xb3, 0xa1, 0xb9, 0xc, 0xfb, 0xd3, 0x99, 0x37);

// {B5DA0B3C-667D-4fc8-B3A1-B90CFBD39937}
RS_DEFINE_GUID(CON_SHOT_POWER,
			   0x25a64f9d, 0x6f51, 0x4393, 0xb2, 0xf, 0xf4, 0x18, 0x32, 0xe7, 0xaa, 0x4e);




// IRcPhysShotCmd
MIDL_INTERFACE("7A0424D7-2A84-4445-B6C6-DE4A9B7E7315")
IRcPhysShotCmd :IUnknown
{
};



// CRcPhysShotCmd
class ATL_NO_VTABLE CRcPhysShotCmd : 
    public CComObjectRootEx<CComGlobalsThreadModel>,
    public IRsUnknownNode,
    public IRsCommand,
	public IRcPhysShotCmd
{
private:
    CComPtr<IUnknown> m_spUnkAgg;

public:
    CRcPhysShotCmd()
	{
	}

	HRESULT FinalConstruct();
	
	void FinalRelease() 
	{
        m_spUnkAgg.Release();
	}

	STDMETHOD(Execute)(void);
    STDMETHOD(Undo)(void);
    STDMETHOD(Redo)(void);
    STDMETHOD(HasUndo)(RtBool* isUndoable);
    STDMETHOD(OnGetValue)(CONID con_id, IRsDataCache* pDataCache, VARIANT* pVtData, RtBool* pHandled);
    STDMETHOD(OnSetValue)(CONID con_id, IRsDataCache* pDataCache, VARIANT* pvtData, RtBool* pHandled);
    STDMETHOD(OnDefaultValue)(CONID con_id, VARIANT* pVtData, RtBool* pHandled);
    STDMETHOD(OnInvalidate)(CONID con_id, RtBool* pHandled);
    STDMETHOD(OnInitialize)(void);
    STDMETHOD(OnLoadDefault)(void);
    STDMETHOD(OnDestroy)(void);

    // IRsObject
    RS_DECLARE_IRS_OBJECT(IRcPhysShotCmd, L"PhysShot")

    BEGIN_COM_MAP(CRcPhysShotCmd)
        COM_INTERFACE_ENTRY(IRcPhysShotCmd)
        COM_INTERFACE_ENTRY(IRsUnknownNode)
        COM_INTERFACE_ENTRY(IRsCommand)
        COM_INTERFACE_ENTRY2(IUnknown, IRsUnknownNode)
        COM_INTERFACE_ENTRY2(IRsObject, IRsUnknownNode)
        COM_INTERFACE_ENTRY_AGGREGATE(DEF_GUIDNAME(IRsBaseNode), m_spUnkAgg.p)
        COM_INTERFACE_ENTRY_AGGREGATE_BLIND(m_spUnkAgg.p)    // Just for safety, the speed is slower only for unknown interfaces
    END_COM_MAP()

    DECLARE_GET_CONTROLLING_UNKNOWN()
    DECLARE_PROTECT_FINAL_CONSTRUCT()


private:

	CComPtr<IRpKernel> m_spKernel;

	HRESULT CreateSphere(IRsBaseNode **ppNode);
};
