text: #ifndef TOUCHMIND_TOUCH_ABSTRACTMANIPULATIONHELPER_H_
  #define TOUCHMIND_TOUCH_ABSTRACTMANIPULATIONHELPER_H_
  
  namespace touchmind {
    namespace touch {
  
      enum DRAGGING_STATUS { DRAGGING_STATUS_NOT_DRAGGING, DRAGGING_STATUS_PREPARE, DRAGGING_STATUS_DRAGGING };
  
      enum MOUSE_CURSOR_TYPE {
        MOUSE_CURSOR_TYPE_DEFAULT,
        MOUSE_CURSOR_TYPE_ARROW,
        MOUSE_CURSOR_TYPE_SIZENWSE,
        MOUSE_CURSOR_TYPE_SIZENESW,
        MOUSE_CURSOR_TYPE_SIZEWE,
        MOUSE_CURSOR_TYPE_SIZENS,
        MOUSE_CURSOR_TYPE_SIZEALL,
        MOUSE_CURSOR_TYPE_NO,
        MOUSE_CURSOR_TYPE_HAND
      };
  
      class ManipulationResult {
      public:
        ManipulationResult()
            : WasHandled(false)
            , IsNeedInvalidateRect(false) {
        }
        ManipulationResult(bool _WasHandled, bool _IsNeedInvalidateRect)
            : WasHandled(_WasHandled)
            , IsNeedInvalidateRect(_IsNeedInvalidateRect) {
        }
        bool WasHandled;
        bool IsNeedInvalidateRect;
      };
  
      class AbstractManipulationHelper {
      private:
        static UINT_PTR m_masterTimerId;
        POINT m_lastPoint;
        DRAGGING_STATUS m_draggingStatus;
        RECT m_dragRect;
        POINT m_lBtnUpPoint;
        UINT_PTR m_timerIdForDoubleClick;
        DWORD m_gestureArgument;
        HCURSOR m_hCursor;
        HCURSOR m_hCursor_Arrow;
        HCURSOR m_hCursor_SizeNWSE;
        HCURSOR m_hCursor_SizeNESW;
        HCURSOR m_hCursor_SizeWE;
        HCURSOR m_hCursor_SizeNS;
        HCURSOR m_hCursor_SizeALL;
        HCURSOR m_hCursor_No;
        HCURSOR m_hCursor_Hand;
  
      public:
        AbstractManipulationHelper(void);
        virtual ~AbstractManipulationHelper(void);
  
        void SetMouseCursor(MOUSE_CURSOR_TYPE mouseCursorType);
  
        virtual ULONGLONG GetCurrentTimestampInMilliSeconds();
  
        virtual ManipulationResult OnLeftMouseDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnMouseMove(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnLeftMouseUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnLeftMouseDoubleClick(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnRightMouseDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnTimer(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnTouch(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
        virtual ManipulationResult OnSetCursor(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
  
        virtual bool IsDragging();
  
        virtual ManipulationResult OnLeftMouseDownExt(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                      ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnSingleClick(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                 ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnDoubleClick(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                 ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnDraggingStart(HWND hWnd, WPARAM wParam, LPARAM lParam, RECT windowDragRect, LONG dx,
                                                   LONG dy, ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnDragging(HWND hWnd, WPARAM wParam, LPARAM lParam, RECT windowDragRect, LONG dx,
                                              LONG dy, ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnDraggingEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, RECT windowDragRect, LONG dx,
                                                 LONG dy, ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnHovering(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint, LONG dx,
                                              LONG dy, ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnRightSingleClick(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                      ULONGLONG timestampInMilliSeconds)
            = 0;
        virtual ManipulationResult OnGestureBegin(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                  ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo)
            = 0;
        virtual ManipulationResult OnGestureEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo)
            = 0;
        virtual ManipulationResult OnZoom(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                          ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo,
                                          POINT zoomCenterPoint, FLOAT zoomFactor)
            = 0;
        virtual ManipulationResult OnPan(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                         ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo, LONG dx, LONG dy)
            = 0;
        virtual ManipulationResult OnRotate(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                            ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo,
                                            POINT rotateCenterPoint, FLOAT rotateAngle)
            = 0;
        virtual ManipulationResult OnTwoFingerTap(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                  ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo)
            = 0;
        virtual ManipulationResult OnPressAndTap(HWND hWnd, WPARAM wParam, LPARAM lParam, POINT windowPoint,
                                                 ULONGLONG timestampInMilliSeconds, PGESTUREINFO pGestureInfo)
            = 0;
      };
  
    } // touch
  } // touchmind
  
  std::wostream &operator<<(std::wostream &strm, const GESTUREINFO &gi);
  std::wostream &operator<<(std::wostream &strm, const GESTURECONFIG &gi);
  
  #endif // TOUCHMIND_TOUCH_ABSTRACTMANIPULATIONHELPER_H_