package cz.fidentis.analyst.curvature;

import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.core.ControlPanelAction;
import cz.fidentis.analyst.core.OutputWindow;
import cz.fidentis.analyst.visitors.mesh.Curvature;
import java.awt.event.ActionEvent;
import javax.swing.JComboBox;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;

/**
 * Action listener for the curvature computation.
 * 
 * @author Radek Oslejsek
 */
public class CurvatureAction extends ControlPanelAction {
    
    /*
     * Attributes handling the state
     */
    private Curvature visitor = null;
    private String curvatureType = CurvaturePanel.GAUSSIAN_CURVATURE;
    
    private final CurvaturePanel controlPanel;
    
    /**
     * Constructor.
     * 
     * @param canvas OpenGL canvas
     * @param topControlPanel Top component for placing control panels
     */
    public CurvatureAction(Canvas canvas, JTabbedPane topControlPanel) {
        super(canvas, topControlPanel);
        this.controlPanel = new CurvaturePanel(this);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        String action = ae.getActionCommand();
        
        switch (action) {
            case CurvaturePanel.ACTION_COMMAND_SHOW_HIDE_PANEL:
                hideShowPanelActionPerformed(ae, this.controlPanel);
                break;
            case CurvaturePanel.ACTION_COMMAND_SHOW_HIDE_HEATMAP:
                if (((JToggleButton) ae.getSource()).isSelected()) {
                    setHeatmap();
                    getPrimaryDrawableFace().setRenderHeatmap(true);
                } else {
                    getPrimaryDrawableFace().setRenderHeatmap(false);
                }
                break;
            case CurvaturePanel.ACTION_COMMAND_SET_CURVATURE_TYPE:
                this.curvatureType = (String) ((JComboBox) ae.getSource()).getSelectedItem();
                setHeatmap();
                break;
            default:
                // to nothing
        }
        
        renderScene();
    }
    
    protected void setHeatmap() {
        if (visitor == null) { // compute missing curvature
            OutputWindow out = OutputWindow.measureTime();
            this.visitor = new Curvature();
            getPrimaryDrawableFace().getModel().compute(visitor);
            out.printDuration("Computation of curvature for a model with " 
                    + getPrimaryDrawableFace().getHumanFace().getMeshModel().getNumVertices()
                    + " vertices"
            );
        }
        
        switch (this.curvatureType) {
            case CurvaturePanel.GAUSSIAN_CURVATURE:
                    getPrimaryDrawableFace().setHeatMap(visitor.getGaussianCurvatures());
                break;
            case CurvaturePanel.MEAN_CURVATURE:
                    getPrimaryDrawableFace().setHeatMap(visitor.getMeanCurvatures());
                break;
            case CurvaturePanel.MIN_CURVATURE:
                    getPrimaryDrawableFace().setHeatMap(visitor.getMinPrincipalCurvatures());
                break;
            case CurvaturePanel.MAX_CURVATURE:
                    getPrimaryDrawableFace().setHeatMap(visitor.getMaxPrincipalCurvatures());
                break;
            default:
                throw new UnsupportedOperationException(curvatureType);
        }
        
    }
}
