#ifndef FRUSTUM_H
#define FRUSTUM_H

#include <glm/glm.hpp>

struct Plane {
    glm::vec3 normal = { 0.0f, 1.0f, 0.0f };
    float distance = 0.0f;

    // Distance from point to plane (positive = in front, negative = behind)
    float distanceToPoint(const glm::vec3& point) const {
        return glm::dot(normal, point) + distance;
    }
};

struct AABB {
    glm::vec3 min;
    glm::vec3 max;

    // Get center point
    glm::vec3 getCenter() const {
        return (min + max) * 0.5f;
    }

    // Get positive extents (half-size)
    glm::vec3 getExtents() const {
        return (max - min) * 0.5f;
    }
};

struct Frustum {
    Plane topFace;
    Plane bottomFace;
    Plane rightFace;
    Plane leftFace;
    Plane farFace;
    Plane nearFace;

    // Test if AABB is in frustum (returns true if visible)
    bool isAABBVisible(const AABB& aabb) const {
        // For each plane, check if the AABB is completely behind it
        // If it's behind any plane, it's outside the frustum
        return isOnOrForwardPlane(topFace, aabb) &&
               isOnOrForwardPlane(bottomFace, aabb) &&
               isOnOrForwardPlane(rightFace, aabb) &&
               isOnOrForwardPlane(leftFace, aabb) &&
               isOnOrForwardPlane(farFace, aabb) &&
               isOnOrForwardPlane(nearFace, aabb);
    }

private:
    // Check if AABB is on or in front of plane
    bool isOnOrForwardPlane(const Plane& plane, const AABB& aabb) const {
        // Get the positive vertex (furthest point in direction of normal)
        const glm::vec3 center = aabb.getCenter();
        const glm::vec3 extents = aabb.getExtents();

        // Project extents onto plane normal to get the effective radius
        const float radius = extents.x * std::abs(plane.normal.x) +
                            extents.y * std::abs(plane.normal.y) +
                            extents.z * std::abs(plane.normal.z);

        // Distance from center to plane
        const float dist = plane.distanceToPoint(center);

        // AABB is visible if center is within radius distance from plane
        return dist >= -radius;
    }
};

#endif
