
#ifndef _MANIPULATION_EVENTS_
#define _MANIPULATION_EVENTS_

#include <ole2.h>
#include <Manipulations.h>

#include "Utils.h"
#include "OleUtils.h"


class ViewContainer;

class ManipulationEventSink : public IUnknownImpl<_IManipulationEvents>
{
private:
    ManipulationEventSink(const ManipulationEventSink&);
    ManipulationEventSink& operator=(const ManipulationEventSink&);
public:
    ManipulationEventSink(IManipulationProcessor *manip,
                          ViewContainer *window, HWND hwnd);
    ManipulationEventSink(IInertiaProcessor *inertia,
                          ViewContainer *window, HWND hwnd);
    ~ManipulationEventSink();

    virtual HRESULT STDMETHODCALLTYPE ManipulationStarted(
        FLOAT x, FLOAT y);

    virtual HRESULT STDMETHODCALLTYPE ManipulationDelta(
        FLOAT x, FLOAT y,
        FLOAT translationDeltaX, FLOAT translationDeltaY,
        FLOAT scaleDelta, FLOAT expansionDelta, FLOAT rotationDelta,
        FLOAT cumulativeTranslationX, FLOAT cumulativeTranslationY,
        FLOAT cumulativeScale, FLOAT cumulativeExpansion, FLOAT cumulativeRotation);

    virtual HRESULT STDMETHODCALLTYPE ManipulationCompleted(
        FLOAT x, FLOAT y,
        FLOAT cumulativeTranslationX, FLOAT cumulativeTranslationY,
        FLOAT cumulativeScale, FLOAT cumulativeExpansion, FLOAT cumulativeRotation);

protected:
    ViewContainer *m_window;
    const HWND m_hwnd;
    const bool m_isInertia;
};




class ManipulationEventSinkWithInertia : public ManipulationEventSink
{    
public:
    ManipulationEventSinkWithInertia(IManipulationProcessor *manip, 
                                     IInertiaProcessor *inertia,
                                     ViewContainer *window, HWND hwnd)
        : ManipulationEventSink(manip, window, hwnd)
    {
        m_inertiaSink = new ManipulationEventSink(inertia, window, hwnd);
    }
    
    virtual ~ManipulationEventSinkWithInertia()
    {
        if (m_inertiaSink) {
            m_inertiaSink->Release();
        }
    }

    virtual HRESULT STDMETHODCALLTYPE ManipulationStarted(
        FLOAT x, FLOAT y);

    virtual HRESULT STDMETHODCALLTYPE ManipulationCompleted(
        FLOAT x, FLOAT y,
        FLOAT cumulativeTranslationX, FLOAT cumulativeTranslationY,
        FLOAT cumulativeScale, FLOAT cumulativeExpansion, FLOAT cumulativeRotation);

private:
    _IManipulationEvents* m_inertiaSink;
};


#endif // _MANIPULATION_EVENTS_
