package cz.fidentis.analyst.scene;

import com.jogamp.opengl.GL2;
import cz.fidentis.analyst.face.HumanFace;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import java.awt.Color;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Drawable human face.
 * 
 * @author Radek Oslejsek
 * @author Daniel Schramm
 */
public class DrawableFace extends DrawableMesh {
    
    public static final Color SKIN_COLOR_PRIMARY = new Color(224, 172, 105);
    public static final Color SKIN_COLOR_SECONDARY = new Color(236, 188, 180);
    
    private final HumanFace humanFace;
    private boolean renderHeatMap = false;
    
    /**
     * Values at mesh vertices that are to be transferred to colors.
     */
    private Map<MeshFacet, List<Double>> heatmap = new HashMap<>();
    /**
     * Values at mesh vertices that determine the saturation level of heatmap colors.
     */
    private Map<MeshFacet, List<Double>> heatmapSaturation = new HashMap<>();
    
    /**
     * Constructor.
     * 
     * @param face Drawable human face
     * @throws IllegalArgumentException if the mesh model
     *         of the human face is {@code null}
     */
    public DrawableFace(HumanFace face) {
        super(face.getMeshModel());
        humanFace = face;
        setColor(SKIN_COLOR_PRIMARY);
    }
    
    /**
     * Sets new heatmap.
     * 
     * @param heatmap New heatmap
     */
    public void setHeatMap(Map<MeshFacet, List<Double>> heatmap) {
        this.heatmap = heatmap;
    }
    
    /**
     * Removes the heatmap from the face.
     */
    public void clearHeatMap() {
        heatmap = new HashMap<>();
    }
    
    /**
     * Returns heatmap of the face
     * (values at mesh vertices that are to be transferred to colors).
     * 
     * @return Heatmap of the face
     */
    public Map<MeshFacet, List<Double>> getHeatMap() {
        return Collections.unmodifiableMap(heatmap);
    }

    /**
     * Sets new map of heatmap colors saturation.
     * 
     * @param heatmapSaturation New map of heatmap colors saturation
     */
    public void setHeatMapSaturation(Map<MeshFacet, List<Double>> heatmapSaturation) {
        this.heatmapSaturation = heatmapSaturation;
    }
    
    /**
     * Removes the map of heatmap colors saturation from the face.
     */
    public void clearHeatMapSaturation() {
        heatmapSaturation = new HashMap<>();
    }

    /**
     * Returns map of heatmap colors saturation
     * (values at mesh vertices that determine the saturation level of heatmap colors).
     * 
     * @return Map of heatmap colors saturation
     */
    public Map<MeshFacet, List<Double>> getHeatMapSaturation() {
        return Collections.unmodifiableMap(heatmapSaturation);
    }

    /**
     * Returns the human face.
     * 
     * @return {@link HumanFace}
     */
    public HumanFace getHumanFace() {
        return humanFace;
    }
    
    /**
     * Sets if the heatmap should be rendered or not.
     * 
     * @param render The switch
     */
    public void setRenderHeatmap(boolean render) {
        this.renderHeatMap = render;
    }
    
    /**
     * Determines whether the heatmap is set to be rendered.
     * 
     * @return id the heatmap will be rendered
     */
    public boolean isHeatmapRendered() {
        return this.renderHeatMap;
    }
    
    @Override
    protected void renderObject(GL2 gl) {
        if (isHeatmapRendered()) {
            new HeatmapRenderer().drawMeshModel(gl, getModel(), heatmap, heatmapSaturation);
        } else {
            super.renderObject(gl);
        }
    }
    
}
