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

#include "src/lib/ui/input/gesture.h"

namespace input {

Gesture::Delta& Gesture::Delta::operator+=(const Delta& other) {
  translation += other.translation;
  rotation += other.rotation;
  scale *= other.scale;
  return *this;
}

bool Gesture::Delta::operator==(const Delta& other) const {
  return translation == other.translation && rotation == other.rotation && scale == other.scale;
}

void Gesture::AddPointer(PointerId pointer_id, const glm::vec2& position) {
  // TODO(SCN-1404): This is sometimes violated.
  // FX_DCHECK(pointers_.find(pointer_id) == pointers_.end());

  pointers_[pointer_id] = {.absolute = position, .relative = {}, .distance = 0};
  UpdateCentroid();
  UpdateRelative();
}

Gesture::Delta Gesture::UpdatePointer(PointerId pointer_id, const glm::vec2& position) {
  // TODO(SCN-1404): This is sometimes violated.
  // FX_DCHECK(pointers_.find(pointer_id) != pointers_.end());
  auto it = pointers_.find(pointer_id);
  if (it == pointers_.end()) {
    AddPointer(pointer_id, position);
    return {.translation = {}, .rotation = 0, .scale = 1};
  }

  it->second.absolute = position;

  Delta delta;

  {
    glm::vec2 old_centroid = centroid_;
    UpdateCentroid();
    delta.translation = centroid_ - old_centroid;
  }

  if (pointers_.size() > 1) {
    float moment_sum = 0;
    // Use an arithmetic mean as a decent approximation of a geometric mean.
    float scale_sum = 0;

    for (auto& entry : pointers_) {
      PointerInfo& p = entry.second;

      glm::vec2 old_relative = p.relative;
      float old_distance = p.distance;
      p.relative = p.absolute - centroid_;
      p.distance = glm::length(p.relative);

      // TODO(rosswang): The following has singular behavior when pointers have the same
      // coordinates, which can in particular happen during testing. In such cases while it makes
      // mathematical sense for rotation and scale to be NaN/infinite, perhaps we should default
      // them to identity values.

      // For small displacements, this approximates radians.
      delta.rotation +=
          (old_relative.x * p.relative.y - old_relative.y * p.relative.x) / old_distance;
      moment_sum += old_distance;
      scale_sum += p.distance / old_distance;
    }

    delta.rotation /= moment_sum;
    delta.scale *= scale_sum / pointers_.size();
  }

  return delta;
}

void Gesture::RemovePointer(PointerId pointer_id) {
  pointers_.erase(pointer_id);

  if (!pointers_.empty()) {
    UpdateCentroid();
    UpdateRelative();
  }
}

void Gesture::UpdateCentroid() {
  // It would be more efficient to do this incrementally at the possible cost of precision. Gestures
  // tend to be both short and with a small number of pointers, so neither the efficiency nor
  // precision is particularly important. However, edge cases like new pointers are easier to deal
  // with if we always recalculate, especially with SCN-1404.
  centroid_ = {0, 0};
  for (const auto& entry : pointers_) {
    centroid_ += entry.second.absolute;
  }
  centroid_ /= pointers_.size();
}

void Gesture::UpdateRelative() {
  for (auto& entry : pointers_) {
    PointerInfo& p = entry.second;
    p.relative = p.absolute - centroid_;
    p.distance = glm::length(p.relative);
  }
}

}  // namespace input
