package org.sunflow.raytracer;

import org.sunflow.image.Color;
import org.sunflow.math.Vector3;

/**
 * Represents a sample taken from a light source that faces a point being shaded.
 */
public class LightSample {
    private Vertex v; // position on the light
    private Vector3 ldir; // direction from point being shaded to light
    private Ray shadowRay; // ray to be used to evaluate if the point is in shadow
    private Color le; // radiance that reaches shaded point (without occluders)
    private boolean isValid; // is the sample pointing away from the point to be shaded?

    /**
     * Creates an empty sample, set to be invalid by default.
     */
    public LightSample() {
        v = new Vertex();
        ldir = new Vector3();
        le = new Color();
        shadowRay = null;
        isValid = false;
    }

    void set(LightSample sample) {
        v.set(sample.v);
        ldir.set(sample.ldir);
        le.set(sample.le);
        shadowRay = sample.shadowRay;
        isValid = sample.isValid;
    }

    /**
     * Sets the valid flag of the sample. This flag is used when a partially visible light source has been sampled and
     * an invisible location was chosen on the light.
     *
     * @param isValid value to set the valid flag to
     */
    public void setValid(boolean isValid) {
        this.isValid = isValid;
    }

    /**
     * Sets the shadow ray which should be used to determine if the point is in shadow.
     * @param shadowRay a ray that points from the point being shaded to the light sample
     */
    public void setShadowRay(Ray shadowRay) {
        this.shadowRay = shadowRay;
    }

    /**
     * Gets the current value of the valid flag. An invalid sample should not be used when integrating the contribution
     * from light samples.
     * @return current value of the valid flag
     */
    public boolean isValid() {
        return isValid;
    }

    /**
     * Gets the sample position on the associated light source.
     * @return position of the sample on the light source
     */
    public Vertex getVertex() {
        return v;
    }

    /**
     * Gets the direction from the point being shaded to the position of the sample on the light source.
     * @return direction from point being shaded to the light sample
     */
    public Vector3 getDirection() {
        return ldir;
    }

    /**
     * Gets the radiance of the light source that reaches the shaded point through this light sample.
     * @return radiance emitted by the light sample
     */
    public Color getRadiance() {
        return le;
    }

    /**
     * Gets the shadow ray to be used to determine if the light sample is occluded at the point being shaded.
     *
     * @return shadow ray from point being shaded to light sample
     */
    public Ray getShadowRay() {
        return shadowRay;
    }
}