// 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_FUCHSIA_POINTER_DELEGATE_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_POINTER_DELEGATE_H_

#include <fuchsia/ui/pointer/cpp/fidl.h>

#include <array>
#include <functional>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "flutter/lib/ui/window/pointer_data.h"

namespace flutter_runner {

// Helper class for keying into a map.
struct IxnHasher {
  std::size_t operator()(
      const fuchsia::ui::pointer::TouchInteractionId& ixn) const {
    return std::hash<uint32_t>()(ixn.device_id) ^
           std::hash<uint32_t>()(ixn.pointer_id) ^
           std::hash<uint32_t>()(ixn.interaction_id);
  }
};

// Channel processors for fuchsia.ui.pointer.TouchSource and MouseSource
// protocols. It manages the channel state, collects touch and mouse events, and
// surfaces them to PlatformView as flutter::PointerData events for further
// processing and dispatch.
class PointerDelegate {
 public:
  PointerDelegate(fuchsia::ui::pointer::TouchSourceHandle touch_source,
                  fuchsia::ui::pointer::MouseSourceHandle mouse_source)
      : touch_source_(touch_source.Bind()),
        mouse_source_(mouse_source.Bind()) {}

  // This function collects Fuchsia's TouchPointerSample and MousePointerSample
  // data and transforms them into flutter::PointerData structs. It then calls
  // the supplied callback with a vector of flutter::PointerData, which (1) does
  // last processing (applies metrics), and (2) packs these flutter::PointerData
  // in a flutter::PointerDataPacket for transport to the Engine.
  void WatchLoop(
      std::function<void(std::vector<flutter::PointerData>)> callback);

 private:
  /***** TOUCH STATE *****/

  // Channel for touch events from Scenic.
  fuchsia::ui::pointer::TouchSourcePtr touch_source_;

  // Receive touch events from Scenic. Must be copyable.
  std::function<void(std::vector<fuchsia::ui::pointer::TouchEvent>)>
      touch_responder_;

  // Per-interaction buffer of touch events from Scenic. When an interaction
  // starts with event.pointer_sample.phase == ADD, we allocate a buffer and
  // store samples. When interaction ownership becomes
  // event.interaction_result.status == GRANTED, we flush the buffer to client,
  // delete the buffer, and all future events in this interaction are flushed
  // direct to client. When interaction ownership becomes DENIED, we delete the
  // buffer, and the client does not get any previous or future events in this
  // interaction.
  //
  // There are three basic interaction forms that we need to handle, and the API
  // guarantees we see only these three forms. S=sample, R(g)=result-granted,
  // R(d)=result-denied, and + means packaged in the same table. Time flows from
  // left to right. Samples start with ADD, and end in REMOVE or CANCEL. Each
  // interaction receives just one ownership result.
  //   (1) Late grant. S S S R(g) S S S
  //   (1-a) Combo.    S S S+R(g) S S S
  //   (2) Early grant. S+R(g) S S S S S
  //   (3) Late deny. S S S R(d)
  //   (3-a) Combo.   S S S+R(d)
  //
  // This results in the following high-level algorithm to correctly deal with
  // buffer allocation and deletion, and event flushing or event dropping based
  // on ownership.
  //   if event.sample.phase == ADD && !event.result
  //     allocate buffer[event.sample.interaction]
  //   if buffer[event.sample.interaction]
  //     buffer[event.sample.interaction].push(event.sample)
  //   else
  //     flush_to_client(event.sample)
  //   if event.result
  //     if event.result == GRANTED
  //       flush_to_client(buffer[event.result.interaction])
  //     delete buffer[event.result.interaction]
  std::unordered_map<fuchsia::ui::pointer::TouchInteractionId,
                     std::vector<flutter::PointerData>,
                     IxnHasher>
      touch_buffer_;

  // The fuchsia.ui.pointer.TouchSource protocol allows one in-flight
  // hanging-get Watch() call to gather touch events, and the client is expected
  // to respond with consumption intent on the following hanging-get Watch()
  // call. Store responses here for the next call.
  std::vector<fuchsia::ui::pointer::TouchResponse> touch_responses_;

  // The fuchsia.ui.pointer.TouchSource protocol issues channel-global view
  // parameters on connection and on change. Events must apply these view
  // parameters to correctly map to logical view coordinates. The "nullopt"
  // state represents the absence of view parameters, early in the protocol
  // lifecycle.
  std::optional<fuchsia::ui::pointer::ViewParameters> touch_view_parameters_;

  /***** MOUSE STATE *****/

  // Channel for mouse events from Scenic.
  fuchsia::ui::pointer::MouseSourcePtr mouse_source_;

  // Receive mouse events from Scenic. Must be copyable.
  std::function<void(std::vector<fuchsia::ui::pointer::MouseEvent>)>
      mouse_responder_;

  // The set of mouse devices that are currently interacting with the UI.
  // A mouse is considered flutter::PointerData::Change::kDown if any button is
  // pressed. This set is used to correctly set the phase in
  // flutter::PointerData.change, with this high-level algorithm:
  //   if !mouse_down[id] && !button then: change = kHover
  //   if !mouse_down[id] &&  button then: change = kDown; mouse_down.add(id)
  //   if  mouse_down[id] &&  button then: change = kMove
  //   if  mouse_down[id] && !button then: change = kUp; mouse_down.remove(id)
  std::unordered_set</*mouse device ID*/ uint32_t> mouse_down_;

  // For each mouse device, its device-specific information, such as mouse
  // button priority order.
  std::unordered_map</*mouse device ID*/ uint32_t,
                     fuchsia::ui::pointer::MouseDeviceInfo>
      mouse_device_info_;

  // The fuchsia.ui.pointer.MouseSource protocol issues channel-global view
  // parameters on connection and on change. Events must apply these view
  // parameters to correctly map to logical view coordinates. The "nullopt"
  // state represents the absence of view parameters, early in the protocol
  // lifecycle.
  std::optional<fuchsia::ui::pointer::ViewParameters> mouse_view_parameters_;
};

}  // namespace flutter_runner
#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_POINTER_DELEGATE_H_
