// Copyright 2017 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.

#ifndef GARNET_LIB_UI_GFX_ENGINE_HIT_TESTER_H_
#define GARNET_LIB_UI_GFX_ENGINE_HIT_TESTER_H_

#include <vector>

#include "garnet/lib/ui/gfx/engine/hit.h"

namespace scenic_impl {
namespace gfx {

class Node;
class Session;

// Performs a hit test on the contents of a node.
class HitTester {
 public:
  HitTester() = default;
  virtual ~HitTester() = default;

  // Performs a hit test along the specified ray.  Returns a list of hits
  // sorted by increasing distance, then by increasing tree depth.
  //
  // The specific hit collection behavior depends on should_participate()
  // behavior, implemented by each subclass.
  std::vector<Hit> HitTest(Node* node, const escher::ray4& ray);

 protected:
  // Describes a possible hit within an enclosing tag node.
  struct TagInfo {
    static constexpr float kNoHit = std::numeric_limits<float>::infinity();

    // The distance to the intersection as defined by |Hit.distance|.
    float distance = kNoHit;

    bool is_hit() const { return distance < kNoHit; }

    void ReportIntersection(float d) {
      if (d < distance)
        distance = d;
    }
  };

  // Describes a ray and its accumulated transform.
  struct RayInfo {
    // The ray to test in the object's coordinate system.
    escher::ray4 ray;

    // The accumulated inverse transformation matrix which maps the coordinate
    // system of the node at which the hit test was initiated into the
    // coordinate system of the object.
    escher::mat4 inverse_transform;
  };

  // Used to determine hit collection behavior.
  // In a session-based hit test, nodes must have a compatible tag and session.
  // In a global hit test, all nodes participate, regardless of tag or session.
  virtual bool should_participate(Node* node) = 0;

  // Accumulates hit test results from the node, as seen by its parent.
  // Applies the node's transform to the ray stack.
  // |ray_info_| must be in the parent's local coordinate system.
  void AccumulateHitsOuter(Node* node);

  // Accumulates hit test results from the node, as seen by the node itself.
  // Applies the node's tag to the tag stack.
  // |ray_info_| must be in the node's local coordinate system.
  void AccumulateHitsLocal(Node* node);

  // Accumulates hit test results from the node's content and children.
  // |ray_info_| must be in the node's local coordinate system.
  void AccumulateHitsInner(Node* node);

  // Returns true if the ray passes through the node's parts.
  // |ray| must be in the node's local coordinate system.
  static bool IsRayWithinPartsInner(Node* node, const escher::ray4& ray);

  // Returns true if the ray passes through the node's clipped content.
  // |ray| must be in the parent's local coordinate system.
  //
  // TODO(MZ-207): The way this works only makes geometric sense if the ray
  // is parallel to the camera projection at the point being sampled.
  static bool IsRayWithinClippedContentOuter(Node* node,
                                             const escher::ray4& ray);

  // Returns true if the ray passes through the node's clipped content.
  // |ray| must be in the node's local coordinate system.
  static bool IsRayWithinClippedContentInner(Node* node,
                                             const escher::ray4& ray);

  // The vector which accumulates hits.
  std::vector<Hit> hits_;

  // The current tag information.
  // Null if there is no enclosing tagged node.
  // TODO(SCN-909): Refactor out.
  TagInfo* tag_info_ = nullptr;

  // The current ray information.
  // Null if there is no hit test currently in progress.
  // TODO(SCN-909): Refactor out.
  RayInfo* ray_info_ = nullptr;
};

class SessionHitTester : public HitTester {
 public:
  explicit SessionHitTester(Session* session);
  virtual ~SessionHitTester() = default;

 private:
  // Node seen in hit testing only if non-zero tag and compatible session.
  bool should_participate(Node* node) override;

  Session* session_;
};

class GlobalHitTester : public HitTester {
 public:
  GlobalHitTester() = default;
  virtual ~GlobalHitTester() = default;

 private:
  // A node always participates in the hit test, regardless of tag and session.
  bool should_participate(Node* node) override { return true; }
};

}  // namespace gfx
}  // namespace scenic_impl

#endif  // GARNET_LIB_UI_GFX_ENGINE_HIT_TESTER_H_
