/*
 * (c) Copyright: Artenum SARL, 101-103 Boulevard Mac Donald,
 *                75019, Paris, France 2005.
 *                http://www.artenum.com
 *
 * License:
 *
 *  This program is free software; you can redistribute it
 *  and/or modify it under the terms of the Q Public License;
 *  either version 1 of the License.
 *
 *  This program is distributed in the hope that it will be
 *  useful, but WITHOUT ANY WARRANTY; without even the implied
 *  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE. See the Q Public License for more details.
 *
 *  You should have received a copy of the Q Public License
 *  License along with this program;
 *  if not, write to:
 *    Artenum SARL, 101-103 Boulevard Mac Donald,
 *    75019, PARIS, FRANCE, e-mail: contact@artenum.com
 */
package com.artenum.cassandra.plugin.wrap.scalar;

import com.artenum.cassandra.pipeline.PipeLineManager;
import com.artenum.cassandra.pipeline.CassandraObject;
import com.artenum.cassandra.pipeline.VtkObjectListModel;
import com.artenum.cassandra.plugin.PlugInControlUI;

import vtk.vtkDataSet;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListDataListener;

/**
 * <pre>
 *   &lt;b&gt;Project ref           :&lt;/b&gt; CASSANDRA project
 *   &lt;b&gt;Copyright and license :&lt;/b&gt; See relevant sections
 *   &lt;b&gt;Status                :&lt;/b&gt; under development
 *   &lt;b&gt;Creation              :&lt;/b&gt; 04/03/2005
 *   &lt;b&gt;Modification          :&lt;/b&gt;
 *
 *   &lt;b&gt;Description  :&lt;/b&gt; Control panel for the plugin.
 *
 * </pre>
 *
 * <table cellpadding="3" cellspacing="0" border="1" width="100%">
 * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
 * <td><b>Version number</b></td>
 * <td><b>Author (name, e-mail)</b></td>
 * <td><b>Corrections/Modifications</b></td>
 * </tr>
 * <tr>
 * <td>0.1</td>
 * <td>Sebastien Jourdain, jourdain@artenum.com</td>
 * <td>Creation</td>
 * </tr>
 * </table>
 *
 * @author Sebastien Jourdain, ARTENUM SARL 
 * @author Julien Forest, ARTENUM SARL
 * 
 * @version 1.2
 */
public class WarpScalarControlUI extends PlugInControlUI {
    private PipeLineManager pipeLineManager;
    private JFormattedTextField normalX;
    private JFormattedTextField normalY;
    private JFormattedTextField normalZ;
    private JFormattedTextField scale;
    private JComboBox input;
    private JSlider slider;

    //
    private WarpScalarPlugin plugin;

    /**
     * Defines the graphical interface of the control panel for the warp scalar
     * plugin. This method just defines the components and attach the action
     * listener.
     *
     * @param pipeLineManager
     * @param plugin
     */
    public WarpScalarControlUI(PipeLineManager pipeLineManager, WarpScalarPlugin plugin, Frame owner) {
        super(owner, "Warp scalar configuration panel");

        //
        this.pipeLineManager = pipeLineManager;
        this.plugin = plugin;

        //
        input = new JComboBox(new DataSetListModel(pipeLineManager.getDataSetList()));

        //
        scale = new JFormattedTextField("100");
        scale.setValue(new Double(100));
        normalX = new JFormattedTextField("0");
        normalX.setValue(new Double(0));
        normalY = new JFormattedTextField("0");
        normalY.setValue(new Double(0));
        normalZ = new JFormattedTextField("0");
        normalZ.setValue(new Double(1));
        //
        slider = new JSlider(1, 10, 1);
        slider.addChangeListener(this);
        slider.setToolTipText("Scale Factor x slide");

        JPanel grid = new JPanel(new GridLayout(2, 4));
        grid.add(new JLabel());
        grid.add(new JLabel("X"));
        grid.add(new JLabel("Y"));
        grid.add(new JLabel("Z"));
        grid.add(new JLabel("Normal"));
        grid.add(normalX);
        grid.add(normalY);
        grid.add(normalZ);

        JPanel grid2 = new JPanel(new GridLayout(3, 0));
        grid2.add(new JLabel("Scale factor"));
        grid2.add(scale);
        grid2.add(slider);

        // define the "Update" buton. The corresponding action name
        // is "UPDATE". The action istself is performed in the
        // actionPerformed method.
        JButton exec = new JButton("Update");
        exec.setActionCommand("UPDATE");
        exec.addActionListener(this);

        JButton cancel = new JButton("Cancel");
        cancel.setActionCommand("CANCEL");
        cancel.addActionListener(this);

        //
        JPanel line1 = new JPanel();
        line1.setLayout(new BoxLayout(line1, BoxLayout.LINE_AXIS));
        line1.add(new JLabel("Input Dataset"));
        line1.add(input);

        //
        JPanel cmdLine = new JPanel();
        cmdLine.setLayout(new BoxLayout(cmdLine, BoxLayout.LINE_AXIS));
        cmdLine.add(Box.createHorizontalGlue());
        cmdLine.add(exec);
        cmdLine.add(cancel);

        //
        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
        getContentPane().add(line1);
        getContentPane().add(grid);
        getContentPane().add(grid2);
        getContentPane().add(cmdLine);

        // getContentPane().setBorder(BorderFactory.createEmptyBorder(5, 5, 5,
        // 5));
        pack();
        Dimension size = getSize();
        size.setSize(size.getWidth() + 100, size.getHeight());
        setSize(size);
        setLocationRelativeTo(null);
    }

    /**
     * Performe the actions requested by the components (buttons, etc...) of the
     * control GUI of the plugin. The actions are filtered on the keywords
     * previously defined. If needed and depending on the action, this method
     * the relevant update method of the plugin.
     */
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if (command.equals("UPDATE")) {
            if (input.getSelectedItem() == null) {
                return;
            }

            double scale_ = ((Number) scale.getValue()).doubleValue();
            double nx = ((Number) normalX.getValue()).doubleValue();
            double ny = ((Number) normalY.getValue()).doubleValue();
            double nz = ((Number) normalZ.getValue()).doubleValue();

            // here update the cutting plan input data of the cutting plane
            // plugin
            plugin.updateWarpScalar(scale_, nx, ny, nz, (vtkDataSet) ((CassandraObject) input.getSelectedItem()).getVtkObject());
            pipeLineManager.validateViewAndGo();
        }

        if (command.equals("CANCEL")) {
            this.dispose();
        }
    }

    /**
     * slide bar listener. The update of the pipeline is directly performed when
     * the slide bar is changed.
     */
    public void stateChanged(ChangeEvent e) {
        double value = ((double) slider.getValue()) * ((Number) scale.getValue()).doubleValue();
        double nx = ((Number) normalX.getValue()).doubleValue();
        double ny = ((Number) normalY.getValue()).doubleValue();
        double nz = ((Number) normalZ.getValue()).doubleValue();
        if (input.getSelectedItem() != null) {
            plugin.updateWarpScalar(value, nx, ny, nz, (vtkDataSet) ((CassandraObject) input.getSelectedItem()).getVtkObject());
            pipeLineManager.validateViewAndGo();
        }
    }

    /**
     * Define the data model for the input combobox.
     */
    class DataSetListModel implements ComboBoxModel {
        private VtkObjectListModel datasetModel;
        private Object selectedItem;

        public DataSetListModel(VtkObjectListModel datasetModel) {
            this.datasetModel = datasetModel;
        }

        public Object getElementAt(int index) {
            return datasetModel.getElementAt(index);
        }

        public Object getSelectedItem() {
            return selectedItem;
        }

        public int getSize() {
            return datasetModel.getSize();
        }

        public void setSelectedItem(Object anItem) {
            selectedItem = anItem;
        }

        public void addListDataListener(ListDataListener l) {
            datasetModel.addListDataListener(l);
        }

        public void removeListDataListener(ListDataListener l) {
            datasetModel.removeListDataListener(l);
        }
    }

    public void itemStateChanged(ItemEvent arg0) {
        // TODO Auto-generated method stub
        
    }
}
