/*
 * (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.Filter;
import com.artenum.cassandra.pipeline.FilterImpl;
import com.artenum.cassandra.pipeline.PipeLineManager;
import com.artenum.cassandra.pipeline.RemoveListener;
import com.artenum.cassandra.pipeline.CassandraObject;
import com.artenum.cassandra.plugin.CassandraPlugInProperty;
import com.artenum.cassandra.plugin.CassandraPlugin;
import com.artenum.cassandra.plugin.PlugInControlUI;
import com.artenum.cassandra.plugin.PluginManager;

import vtk.vtkActor;
import vtk.vtkDataSet;
import vtk.vtkDataSetMapper;
import vtk.vtkPointSet;
import vtk.vtkWarpScalar;

import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;

/**
 * <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;
 *               This class defines the VTK processing pipeline itself
 *               and the initialisation of the contextuel GUI of 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, Julien Forest, Benoit Thiebault, Jeremie Turbet, ARTENUM SARL
 * @version 1.2
 */
public class WarpScalarPlugin implements CassandraPlugin, RemoveListener {
    // Cassandra elements
    private String name;
    private PipeLineManager pipelineManager;
    private PluginManager pluginManager;
    private JPopupMenu contextualMenu;
    private int nbUpdate = 0;

    // Contextual control GUI of the plugin
    private WarpScalarControlUI controlUI;

    // Vtk data
    private vtkWarpScalar warp;
    private vtkDataSet lastDataSet;
    private vtkDataSetMapper warpMapper;
    private vtkActor warpActor;
    private Filter filterImpl;

    // Pipeline VtkObjects
    private CassandraObject actor;
    private CassandraObject mapper;
    private CassandraObject dataset;
    private CassandraObject filter;

    /**
     * Main contructor and VTK pipeline definition.
     *
     * @param pipelineManager
     *            is the central pipeline manager of Cassandra.
     * @param pluginManager
     *            is the central list of plugin instance, where a contextual
     *            menu access is given.
     */
    public WarpScalarPlugin(PipeLineManager pipelineManager, PluginManager pluginManager, Frame owner) {
        // Init default variable
        this.name = "Cutting plane";
        this.pipelineManager = pipelineManager;
        this.pluginManager = pluginManager;
        this.filterImpl = new FilterImpl();
        filterImpl.addRemoveListener(this);

        // Init all the control UI
        controlUI = new WarpScalarControlUI(pipelineManager, this, owner);

        // Init contextual menu
        contextualMenu = new JPopupMenu("Warp Scalar menu");
        JMenuItem showControl = new JMenuItem("Show control");
        showControl.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    controlUI.setVisible(true);
                }
            });
        contextualMenu.add(showControl);
        contextualMenu.addSeparator();
        JMenuItem remove = new JMenuItem("Remove");
        remove.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    remove();
                }
            });
        contextualMenu.add(remove);

        // Define and init the VTK pipeline
        warp = new vtkWarpScalar();
        
        
        
        warpMapper = new vtkDataSetMapper();
        // warpMapper.SetInput(warp.GetOutput());

        // we recover the common lookup table
        warpActor = new vtkActor();
        warpActor.SetMapper(warpMapper);

        // Load the result data in the Cassandra pipeline
        String localName = "Warp";
        actor = pipelineManager.addActor(warpActor, localName);
        mapper = pipelineManager.addMapper(warpMapper, localName);
        //dataset = pipelineManager.addDataSet(warp.GetOutput(), "Warp");
        filter = pipelineManager.addFilter(filterImpl, localName);
        
        //
        filter.getMetaData().put(CassandraObject.POPUP_MENU, getContextualMenu());

        // end of the VTK pipeline
    }

    /**
     * Update the data in the defined pipeline
     *
     * @param scale
     * @param nx
     * @param ny
     * @param nz
     *
     * @param vtkDataSet
     */
    public void updateWarpScalar(double scale, double nx, double ny, double nz, vtkDataSet vtkDataSet) {
        if (vtkDataSet == null) {
        	JOptionPane.showMessageDialog(new JFrame(),
        		    "Please select a valid input dataset.",
        		    "Input Filter Selection Error",
        		    JOptionPane.ERROR_MESSAGE);
            return;
        }

        warp.SetNormal(nx, ny, nz);
        warp.SetScaleFactor(scale);
        warp.SetInput((vtkPointSet) vtkDataSet);
        warpMapper.SetInput(warp.GetOutput());
        //
        actor.setValide(true);
        if (dataset == null) {
            dataset = pipelineManager.addDataSet(warp.GetOutput(), "Warp");
        }

        // Set the default actor visible by default
        if ((nbUpdate++ == 0) && pipelineManager.getActorList().getData().contains(actor)) {
            pipelineManager.setActorVisible(actor, true);
        }
        // and we hide the actor corresponding to the source
        pipelineManager.hideInputActor(actor, vtkDataSet);

        // Graph
        filterImpl.getInputDataSet().clear();
        filterImpl.getInputDataSet().add(vtkDataSet);
        filterImpl.getOutputDataSet().clear();
        filterImpl.getOutputDataSet().add(warp.GetOutput());
        pipelineManager.notifyConnectivityChange(filter);
        pipelineManager.notifyConnectivityChange(dataset);
    }

    /**
     * Default plugin interface
     */
    public String getName() {
        return name;
    }

    public JPopupMenu getContextualMenu() {
        return contextualMenu;
    }

    public void remove() {
        pluginManager.removePlugin(this);
        pipelineManager.removeVtkObject(actor);
        pipelineManager.removeVtkObject(mapper);
        pipelineManager.removeVtkObject(dataset);
        pipelineManager.removeVtkObject(filter);
    }

    /**
     * String printed in the plugin manager list
     */
    public String toString() {
        return getName();
    }
    
    public Filter getInternalFilter() {
        return filterImpl;
    }

    public PlugInControlUI getControlUI() {
        return controlUI;
    }

    @Override
    public CassandraPlugInProperty getPlugInProperty() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void initAndUpdate(CassandraPlugInProperty prop) {
        // TODO Auto-generated method stub
        
    }

}
