// Copyright (c) 2023 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once
#include "scene/SceneItemComponent.hpp"
#include "physics/3d/Ray3D.hpp"

namespace Dawn {
  struct Collider3DRayResult {
    glm::vec3 point;
    float_t distance;
    glm::vec3 normal;
    Collider3D *collider;
  };

  struct Collider3DAABBSweepResult {
  };

  enum Collider3DType {
    COLLIDER3D_TYPE_CUBE,
    COLLIDER3D_TYPE_CAPSULE,
    COLLIDER3D_TYPE_SPHERE
  };

  class Collider3D : public SceneItemComponent {
    protected:
      /**
       * Internal per-collider raycast implementation. Same arguments as 
       * Collider3D::raycast()
       */
      virtual bool_t performRaycast(
        struct Collider3DRayResult *result,
        struct Ray3D ray
      ) = 0;

    public:
      Collider3D(std::weak_ptr<SceneItem> item);

      /**
       * Perform a raycast against this collider.
       * 
       * @param result Where to store the result of the raycast collision 
       * @param ray The ray to cast against.
       * @return True if the ray intercepts this collider, otherwise false.
       */
      bool_t raycast(struct Collider3DRayResult *result, struct Ray3D ray);

      /**
       * Returns which type of collider this is. Useful for performing dynamic
       * casting in your event listeners.
       * 
       * @return The collider type this is.
       */
      virtual enum Collider3DType getColliderType() = 0;
  };
}