package eu.jonahbauer.raytracing.scene.transform;

import eu.jonahbauer.raytracing.math.Range;
import eu.jonahbauer.raytracing.math.Ray;
import eu.jonahbauer.raytracing.scene.HitResult;
import eu.jonahbauer.raytracing.scene.Hittable;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;
import java.util.Optional;

public abstract class Transform implements Hittable {
    protected final @NotNull Hittable object;

    protected Transform(@NotNull Hittable object) {
        this.object = Objects.requireNonNull(object);
    }

    protected abstract @NotNull Ray transform(@NotNull Ray ray);

    protected abstract @NotNull HitResult transform(@NotNull HitResult result);

    @Override
    public final @NotNull Optional<HitResult> hit(@NotNull Ray ray, @NotNull Range range) {
        return object.hit(transform(ray), range).map(this::transform);
    }
}
