// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_

#include "flutter/fml/memory/ref_counted.h"

#include <wrl/client.h>
#include "directmanipulation.h"

namespace flutter {

class FlutterWindow;
class WindowBindingHandlerDelegate;

class DirectManipulationEventHandler;

// Owner for a DirectManipulation event handler, contains the link between
// DirectManipulation and WindowBindingHandlerDelegate.
class DirectManipulationOwner {
 public:
  explicit DirectManipulationOwner(FlutterWindow* window);
  virtual ~DirectManipulationOwner() = default;
  // Initialize a DirectManipulation viewport with specified width and height.
  // These should match the width and height of the application window.
  int Init(unsigned int width, unsigned int height);
  // Resize the DirectManipulation viewport. Should be called when the
  // application window is resized.
  void ResizeViewport(unsigned int width, unsigned int height);
  // Set the WindowBindingHandlerDelegate which will receive callbacks based on
  // DirectManipulation updates.
  void SetBindingHandlerDelegate(
      WindowBindingHandlerDelegate* binding_handler_delegate);
  // Called when DM_POINTERHITTEST occurs with an acceptable pointer type. Will
  // start DirectManipulation for that interaction.
  virtual void SetContact(UINT contactId);
  // Called to get updates from DirectManipulation. Should be called frequently
  // to provide smooth updates.
  void Update();
  // Release child event handler and OS resources.
  void Destroy();
  // The target that should be updated when DirectManipulation provides a new
  // pan/zoom transformation.
  WindowBindingHandlerDelegate* binding_handler_delegate;

 private:
  // The window gesture input is occuring on.
  FlutterWindow* window_;
  // Cookie needed to register child event handler with viewport.
  DWORD viewportHandlerCookie_;
  // Object needed for operation of the DirectManipulation API.
  Microsoft::WRL::ComPtr<IDirectManipulationManager> manager_;
  // Object needed for operation of the DirectManipulation API.
  Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> updateManager_;
  // Object needed for operation of the DirectManipulation API.
  Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport_;
  // Child needed for operation of the DirectManipulation API.
  fml::RefPtr<DirectManipulationEventHandler> handler_;

  FML_DISALLOW_COPY_AND_ASSIGN(DirectManipulationOwner);
};

// Implements DirectManipulation event handling interfaces, receives calls from
// system when gesture events occur.
class DirectManipulationEventHandler
    : public fml::RefCountedThreadSafe<DirectManipulationEventHandler>,
      public IDirectManipulationViewportEventHandler,
      public IDirectManipulationInteractionEventHandler {
  friend class DirectManipulationOwner;
  FML_FRIEND_REF_COUNTED_THREAD_SAFE(DirectManipulationEventHandler);
  FML_FRIEND_MAKE_REF_COUNTED(DirectManipulationEventHandler);

 public:
  explicit DirectManipulationEventHandler(DirectManipulationOwner* owner)
      : owner_(owner) {}

  // |IUnknown|
  STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override;

  // |IUnknown|
  ULONG STDMETHODCALLTYPE AddRef() override;

  // |IUnknown|
  ULONG STDMETHODCALLTYPE Release() override;

  // |IDirectManipulationViewportEventHandler|
  HRESULT STDMETHODCALLTYPE
  OnViewportStatusChanged(IDirectManipulationViewport* viewport,
                          DIRECTMANIPULATION_STATUS current,
                          DIRECTMANIPULATION_STATUS previous) override;

  // |IDirectManipulationViewportEventHandler|
  HRESULT STDMETHODCALLTYPE
  OnViewportUpdated(IDirectManipulationViewport* viewport) override;

  // |IDirectManipulationViewportEventHandler|
  HRESULT STDMETHODCALLTYPE
  OnContentUpdated(IDirectManipulationViewport* viewport,
                   IDirectManipulationContent* content) override;

  // |IDirectManipulationInteractionEventHandler|
  HRESULT STDMETHODCALLTYPE
  OnInteraction(IDirectManipulationViewport2* viewport,
                DIRECTMANIPULATION_INTERACTION_TYPE interaction) override;

 private:
  struct GestureData {
    float scale;
    float pan_x;
    float pan_y;
  };
  // Convert transform array to Flutter-usable values.
  GestureData ConvertToGestureData(float transform[6]);
  // Unique identifier to associate with all gesture event updates.
  int32_t GetDeviceId();
  // Parent object, used to store the target for gesture event updates.
  DirectManipulationOwner* owner_;
  // We need to reset some parts of DirectManipulation after each gesture
  // A flag is needed to ensure that false events created as the reset occurs
  // are not sent to the flutter framework.
  bool during_synthesized_reset_ = false;
  // Store whether current events are from synthetic inertia rather than user
  // input.
  bool during_inertia_ = false;
  // The transform might not be able to be reset before the next gesture, so
  // the initial state needs to be stored for reference.
  GestureData initial_gesture_data_ = {
      1,  // scale
      0,  // pan_x
      0,  // pan_y
  };
  // Store the difference between the last pan offsets to determine if inertia
  // has been cancelled in the middle of an animation.
  float last_pan_x_ = 0.0;
  float last_pan_y_ = 0.0;
  float last_pan_delta_x_ = 0.0;
  float last_pan_delta_y_ = 0.0;
};

}  // namespace flutter

#endif  // FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_
