package com.srbenoit.render;

import java.awt.Color;
import com.srbenoit.geom.Vector3;

/**
 * A triangular face in view coordinates. This class extends <code>Tuple3</code>, where the
 * superclass fields represent the normal vector to the face.
 */
public class ViewFace extends Vector3 {

    /** the index of this face in the scene where it is contained */
    private int indexInScene;

    /** the first vertex in the face */
    private ViewVertex vertex0;

    /** the second vertex in the face */
    private ViewVertex vertex1;

    /** the third vertex in the face */
    private ViewVertex vertex2;

    /** the light color of the face */
    private Color color;

    /** flag indicating face has been culled */
    private boolean culled;

    /**
     * Constructs a new <code>ViewFace</code>.
     */
    public ViewFace() {

        super();
    }

    /**
     * Gets the index of this face in the scene.
     *
     * @return  the index
     */
    public int getIndexInScene() {

        return this.indexInScene;
    }

    /**
     * Gets the first vertex in the face.
     *
     * @return  the vertex
     */
    public ViewVertex getVertex0() {

        return this.vertex0;
    }

    /**
     * Gets the second vertex in the face.
     *
     * @return  the vertex
     */
    public ViewVertex getVertex1() {

        return this.vertex1;
    }

    /**
     * Gets the third vertex in the face.
     *
     * @return  the vertex
     */
    public ViewVertex getVertex2() {

        return this.vertex2;
    }

    /**
     * Copies a world-coordinate face object into a view-coordinate face object. This sets the
     * vertex references in the view-space object to the view-space vertex objects that correspond
     * to the world-space vertices that the world-space face references.
     *
     * @param  camera    the camera to use to transform points and vectors
     * @param  vertices  the view-space vertices
     * @param  world     the world-space face from which to copy
     */
    public void transformFrom(final Camera camera, final ViewVertex[] vertices,
        final WorldFace world) {

        // Get the view vertices that correspond to the correct world vertices
        this.vertex0 = vertices[world.getVertex0().getIndexInScene()];
        this.vertex1 = vertices[world.getVertex1().getIndexInScene()];
        this.vertex2 = vertices[world.getVertex2().getIndexInScene()];

        this.indexInScene = world.getIndexInScene();

        // Transform the face normal vector
        camera.transformVec(world, this);
    }

    /**
     * Sets the face color based on lighting (not yet on material).
     *
     * @param  red  the red component (0-1, unclamped)
     * @param  grn  the green component (0-1, unclamped)
     * @param  blu  the blue component (0-1, unclamped)
     */
    public void setColor(final double red, final double grn, final double blu) {

        double colR;
        double colG;
        double colB;

        colR = (red > 1.0) ? 1.0 : ((red < 0.0) ? 0.0 : red);
        colG = (grn > 1.0) ? 1.0 : ((grn < 0.0) ? 0.0 : grn);
        colB = (blu > 1.0) ? 1.0 : ((blu < 0.0) ? 0.0 : blu);

        this.color = new Color((int) (colR * 255), (int) (colG * 255), (int) (colB * 255), 128);
    }

    /**
     * Gets the face color.
     *
     * @return  the color
     */
    public Color getColor() {

        return this.color;
    }

    /**
     * Sets the flag indicating whether this face has been culled.
     *
     * @param  isCulled  <code>true</code> if the face is to be culled, <code>false if not
     */
    public void setCulled(final boolean isCulled) {

        this.culled = isCulled;
    }

    /**
     * Tests whether this face has been culled.
     *
     * @return  <code>true</code> if the face is to be culled, <code>false if not
     */
    public boolean isCulled() {

        return this.culled;
    }
}
