const vec = @import("./vec.zig");
const ray = @import("./ray.zig");

const Material = @import("./material.zig").Material;

const Sphere = @import("./sphere.zig").Sphere;
const HittableList = @import("./hittable_list.zig").HittableList;

const Vec3 = vec.Vec3;
const Point3 = vec.Point3;
const Ray = ray.Ray;

pub const Hittable = union(enum) {
    sphere: Sphere,
    hittable_list: HittableList,

    pub fn hit(hittable: Hittable, r: Ray, t_min: f32, t_max: f32) ?HitRecord {
        return switch (hittable) {
            .sphere => |sphere| sphere.hit(r, t_min, t_max),
            .hittable_list => |hittable_list| hittable_list.hit(r, t_min, t_max),
        };
    }
};

pub const HitRecord = struct {
    p: Point3,
    normal: Vec3,
    t: f32,
    front_face: bool,
    material: Material,

    pub fn set_face_normal(hr: *HitRecord, r: Ray, outward_normal: Vec3) void {
        hr.front_face = r.direction().dot(outward_normal) < 0;
        hr.normal = if (hr.front_face)
            outward_normal
        else
            outward_normal.scale(-1);
    }
};
