package cz.fidentis.analyst.symmetry;

import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.core.ControlPanelAction;
import cz.fidentis.analyst.scene.DrawablePlane;

import java.awt.event.ActionEvent;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;

/**
 * Action listener for the manipulation with the symmetry plane.
 * 
 * @author Radek Oslejsek
 */
public class SymmetryAction extends ControlPanelAction {

    private final SymmetryPanel controlPanel;
    private final JTabbedPane topControlPanel;

    /**
     * Constructor.
     * 
     * @param canvas OpenGL canvas
     * @param topControlPanel Top component for placing control panels
     */
    public SymmetryAction(Canvas canvas, JTabbedPane topControlPanel) {
        super(canvas, topControlPanel);
        this.topControlPanel = topControlPanel;
        this.controlPanel = new SymmetryPanel(this);

        // Place control panel to the topControlPanel
        this.topControlPanel.addTab(controlPanel.getName(), controlPanel.getIcon(), controlPanel);
        this.topControlPanel.addChangeListener(e -> {
            // If the symmetry panel is focused...
            if (((JTabbedPane) e.getSource()).getSelectedComponent() instanceof SymmetryPanel) {
                getCanvas().getScene().setDefaultColors();

                if (controlPanel.isShowPlaneChecked()) {
                    getCanvas().getScene().showSymmetryPlanes();
                }
            } else {
                getCanvas().getScene().hideSymmetryPlanes();
            }
        });

        recomputeSymmetryPlane();
    }
    
    @Override
    public void actionPerformed(ActionEvent ae) {
        String action = ae.getActionCommand();
        
        switch (action) {
            case SymmetryPanel.ACTION_COMMAND_SHOW_HIDE_PANEL:
                hideShowPanelActionPerformed(ae, this.controlPanel);   
                break;
            case SymmetryPanel.ACTION_COMMAND_SHOW_HIDE_PLANE:
                if (((JToggleButton) ae.getSource()).isSelected()) {
                    getScene().showSymmetryPlanes();
                } else {
                    getScene().hideSymmetryPlanes();
                }
                break;
            case SymmetryPanel.ACTION_COMMAND_RECOMPUTE: 
                recomputeSymmetryPlane();
                break;  
            default:
                // do nothing
        }
        renderScene();
    }
    
    private void recomputeSymmetryPlane() {
        SymmetryEstimator primaryEstimator = new SymmetryEstimator(controlPanel.getSymmetryConfig());
        getPrimaryDrawableFace().getModel().compute(primaryEstimator);

        getCanvas().getScene().setDrawableSymmetryPlane(0,
                new DrawablePlane(primaryEstimator.getSymmetryPlaneMesh(), primaryEstimator.getSymmetryPlane()));
        getCanvas().getScene().setDrawableCuttingPlane(0,
                new DrawablePlane(primaryEstimator.getSymmetryPlaneMesh(), primaryEstimator.getSymmetryPlane()));
        getCanvas().getScene().setDrawableMirrorPlane(0,
                new DrawablePlane(primaryEstimator.getSymmetryPlaneMesh(), primaryEstimator.getSymmetryPlane()));

        if (getSecondaryDrawableFace() != null) {
            SymmetryEstimator secondaryEstimator = new SymmetryEstimator(controlPanel.getSymmetryConfig());
            getSecondaryDrawableFace().getModel().compute(secondaryEstimator);

            getCanvas().getScene().setDrawableSymmetryPlane(1,
                    new DrawablePlane(secondaryEstimator.getSymmetryPlaneMesh(), secondaryEstimator.getSymmetryPlane()));
            getCanvas().getScene().setDrawableCuttingPlane(1,
                    new DrawablePlane(secondaryEstimator.getSymmetryPlaneMesh(), secondaryEstimator.getSymmetryPlane()));
            getCanvas().getScene().setDrawableMirrorPlane(1,
                    new DrawablePlane(secondaryEstimator.getSymmetryPlaneMesh(), secondaryEstimator.getSymmetryPlane()));
        }

        getCanvas().getScene().hideSymmetryPlanes();
    }
    
}