package eu.jonahbauer.raytracing.scene;

import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.render.Color;
import eu.jonahbauer.raytracing.scene.util.HittableCollection;
import eu.jonahbauer.raytracing.scene.util.HittableList;
import eu.jonahbauer.raytracing.scene.util.HittableOctree;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

public final class Scene extends HittableCollection {
    private final @NotNull HittableOctree octree;
    private final @NotNull HittableList list;
    private final @NotNull SkyBox background;

    public Scene(@NotNull List<? extends @NotNull Hittable> objects) {
        this(Color.BLACK, objects);
    }

    public Scene(@NotNull Color background, @NotNull List<? extends @NotNull Hittable> objects) {
        this(SkyBox.solid(background), objects);
    }

    public Scene(@NotNull SkyBox background, @NotNull List<? extends @NotNull Hittable> objects) {
        var bounded = new ArrayList<Hittable>();
        var unbounded = new ArrayList<Hittable>();

        objects.forEach(object -> {
            if (object.getBoundingBox().isPresent()) {
                bounded.add(object);
            } else {
                unbounded.add(object);
            }
        });

        this.octree = new HittableOctree(bounded);
        this.list = new HittableList(unbounded);
        this.background = background;
    }

    public Scene(@NotNull Hittable @NotNull... objects) {
        this(List.of(objects));
    }

    public Scene(@NotNull Color background, @NotNull Hittable @NotNull... objects) {
        this(background, List.of(objects));
    }

    public Scene(@NotNull SkyBox background, @NotNull Hittable @NotNull... objects) {
        this(background, List.of(objects));
    }

    @Override
    public void hit(@NotNull Ray ray, @NotNull State state) {
        octree.hit(ray, state);
        list.hit(ray, state);
    }

    public @NotNull Color getBackgroundColor(@NotNull Ray ray) {
        return background.getColor(ray);
    }
}
