package cz.fidentis.analyst.toolbar;

import com.jogamp.opengl.GL2;
import cz.fidentis.analyst.canvas.Canvas;
import static cz.fidentis.analyst.toolbar.RenderingToolBar.REFLECTIONS_COLOR;
import cz.fidentis.analyst.scene.Drawable;
import cz.fidentis.analyst.scene.DrawableFeaturePoints;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JToggleButton;

/**
 * Action listener for changing OpenGL canvas rendering modes.
 * 
 * @author Radek Oslejsek
 */
public class RenderingModeAction extends AbstractAction {
    
    public static final String ACTION_COMMAND_SMOOTH_MODE = "smooth";
    public static final String ACTION_COMMAND_WIREFRAME_MODE = "wireframe";
    public static final String ACTION_COMMAND_POINT_CLOUD_MODE = "point cloud";
    public static final String ACTION_COMMAND_BACKGROUND_CHANGE = "background";
    public static final String ACTION_COMMAND_REFLECTIONS_ON_OFF = "reflections";
    public static final String ACTION_COMMAND_SHOW_HIDE_PRIMARY_FACE = "primary face";
    public static final String ACTION_COMMAND_SHOW_HIDE_SECONDARY_FACES = "secondary faces";
    public static final String ACTION_COMMAND_SHOW_HIDE_FEATURE_POINTS = "feature points";
    
    
    private final Canvas canvas;
    private boolean showFPs = true;
    
    /**
     * Constructor.
     * @param canvas OpenGL canvas
     */
    public RenderingModeAction(Canvas canvas) {
        this.canvas = canvas;
    }
    
    @Override
    public void actionPerformed(ActionEvent ae) {
        String action = ae.getActionCommand();
        switch (action) {
            case ACTION_COMMAND_SMOOTH_MODE:
                for (int i = 0; i < canvas.getScene().getNumFaces(); i++){
                   canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_FILL);
                }
                break;
            case ACTION_COMMAND_WIREFRAME_MODE:
                for (int i = 0; i < canvas.getScene().getNumFaces(); i++){
                   canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_LINE);
                }
                break;
            case ACTION_COMMAND_POINT_CLOUD_MODE:
                for (int i = 0; i < canvas.getScene().getNumFaces(); i++){
                   canvas.getScene().getDrawableFace(i).setRenderMode(GL2.GL_POINT);
                }
                break;
            case ACTION_COMMAND_BACKGROUND_CHANGE:
                canvas.setDarkBackground(! ((JToggleButton) ae.getSource()).isSelected());
               break;
            case ACTION_COMMAND_REFLECTIONS_ON_OFF:
                for (Drawable dm: canvas.getScene().getAllDrawables()) {
                    if (((JToggleButton) ae.getSource()).isSelected()) {
                        dm.setHighlights(REFLECTIONS_COLOR);
                    } else {
                        dm.setHighlights(Color.BLACK);
                    }
                }
                break;
            case ACTION_COMMAND_SHOW_HIDE_PRIMARY_FACE:
                showHideFace(0, ((JToggleButton) ae.getSource()).isSelected());
                break;
            case ACTION_COMMAND_SHOW_HIDE_SECONDARY_FACES:
                for (int i = 1; i < canvas.getScene().getNumFaces(); i++) {
                    showHideFace(i, ((JToggleButton) ae.getSource()).isSelected());
                }
                break;
            case ACTION_COMMAND_SHOW_HIDE_FEATURE_POINTS:
                for (int i = 0; i < canvas.getScene().getNumFaces(); i++) {
                    DrawableFeaturePoints fp = canvas.getScene().getDrawableFeaturePoints(i);
                    if (((JToggleButton) ae.getSource()).isSelected()) { // show
                        if (canvas.getScene().getDrawableFace(i).isShown() && fp != null) {
                            fp.show();
                        }
                    } else if (fp != null) { // hide
                        fp.hide();
                    }
                }
                break;
            default:
                throw new UnsupportedOperationException(action);
        }
        canvas.renderScene();
    }
    
    private void showHideFace(int i, boolean show) {
        DrawableFeaturePoints fp = canvas.getScene().getDrawableFeaturePoints(i);
        if (show) {
            canvas.getScene().getDrawableFace(i).show();
            if (showFPs) {
                fp.show();
            }
        } else { //hide
            canvas.getScene().getDrawableFace(i).hide();
            if (fp != null) {
                fp.hide();
            }
        }
    }
}
