/**
 * Copyright (c) Artenum SARL 2004-2005
 * @author Julien Forest / Sebastien Jourdain
 *
 * All rights reserved. This software can
 * not be used or copy or diffused without
 * an explicit license of Artenum SARL, Paris-France
 */
package com.artenum.cassandra.plugin.defaults;

import com.artenum.cassandra.action.PluginActionListener;
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 com.artenum.cassandra.util.VtkObjectComboBoxModel;

import vtk.vtkActor;
import vtk.vtkCamera;
import vtk.vtkCubeAxesActor2D;
import vtk.vtkDataSet;
import vtk.vtkOutlineFilter;
import vtk.vtkPolyDataMapper;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

/**
 * @author Sebastien Jourdain, ARTENUM SARL
 * @author Julien Forest, ARTENUM SARL
 * 
 * @version 1.2
 * 
 */
public class CubeAxis implements ActionListener, CassandraPlugin, RemoveListener {
    private vtkOutlineFilter outlineDataset;
    private vtkPolyDataMapper outlineMapper;
    private vtkActor outlineActor;
    private vtkCubeAxesActor2D axis;
    private PipeLineManager pipelineManager;
    private CassandraObject axisObject;
    private CassandraObject outlineObject;
    private CassandraObject filter;
    private Filter filterImpl;
    private JDialog controlPanel;
    private JComboBox inputDataset;
    private VtkObjectComboBoxModel datasetModel;
    private JPopupMenu contextualMenu;

    public CubeAxis(PipeLineManager pipelineManager, PluginManager pluginManager, Frame owner) {
        this.pipelineManager = pipelineManager;

        // init control panel
        controlPanel = new JDialog(owner, "Axis outline");
        datasetModel = new VtkObjectComboBoxModel(pipelineManager.getDataSetList(), null);

        // Dialog box
        controlPanel.getContentPane().setLayout(new BoxLayout(controlPanel.getContentPane(), BoxLayout.PAGE_AXIS));

        // Input dataset
        JPanel line = new JPanel(new BorderLayout());
        line.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK, 1), "Input dataset"));
        inputDataset = new JComboBox(datasetModel);
        inputDataset.addActionListener(this);
        line.add(inputDataset, BorderLayout.CENTER);
        line.setMaximumSize(new Dimension(10000, inputDataset.getHeight()));
        controlPanel.getContentPane().add(line);

        // Vertical glue
        line = new JPanel(new BorderLayout());
        line.add(Box.createRigidArea(new Dimension(10, 10)), BorderLayout.NORTH);
        controlPanel.getContentPane().add(line);

        // cmd line
        line = new JPanel();
        JButton update = new JButton("Update");
        update.setActionCommand("UPDATE");
        update.addActionListener(this);
        JButton cancel = new JButton("Cancel");
        cancel.setActionCommand("CANCEL");
        cancel.addActionListener(this);
        line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
        line.add(Box.createHorizontalGlue());
        line.add(update);
        line.add(cancel);
        controlPanel.getContentPane().add(line);

        controlPanel.pack();
        Dimension d = controlPanel.getSize();
        controlPanel.setSize(300, d.height);
        controlPanel.setLocationRelativeTo(null);

        // Init contextual menu
        contextualMenu = new JPopupMenu("Outline Axis menu");
        JMenuItem showControl = new JMenuItem("Show control");
        showControl.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    controlPanel.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);

        // VTK pipeline
        initVtkPipeline(pipelineManager.getCassandraView().GetRenderer().GetActiveCamera());
    }

    public void initVtkPipeline(vtkCamera activeCamera) {
        outlineDataset = new vtkOutlineFilter();
        outlineMapper = new vtkPolyDataMapper();
        outlineMapper.SetInput(outlineDataset.GetOutput());
        outlineActor = new vtkActor();
        outlineActor.SetMapper(outlineMapper);

        axis = new vtkCubeAxesActor2D();
        axis.SetLabelFormat("%6.4g");
        axis.SetFlyModeToOuterEdges();
        axis.SetFontFactor(0.8);
        axis.ScalingOff();
        axis.SetCamera(activeCamera);

        filterImpl = new FilterImpl();
        filterImpl.getOutputActor().add(outlineActor);
        filterImpl.getOutputActor().add(axis);
        filterImpl.addRemoveListener(this);

        outlineObject = pipelineManager.addActor(outlineActor, "Box");
        axisObject = pipelineManager.addActor(axis, "Axis");
        filter = pipelineManager.addFilter(filterImpl, "Axis");

        //
        filter.getMetaData().put(CassandraObject.POPUP_MENU, getContextualMenu());
    }

    public void setInput(CassandraObject dataset) {
        outlineDataset.SetInput((vtkDataSet) dataset.getVtkObject());
        axis.SetInput((vtkDataSet) dataset.getVtkObject());
        pipelineManager.setActorVisible(axisObject, true);
        pipelineManager.setActorVisible(outlineObject, true);

        //
        filterImpl.getInputDataSet().clear();
        filterImpl.getInputDataSet().add((vtkDataSet) dataset.getVtkObject());
        pipelineManager.notifyConnectivityChange(dataset);
    }

    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if (command.equals("UPDATE")) {
            if (inputDataset.getSelectedItem() != null) {
                setInput(((CassandraObject) inputDataset.getSelectedItem()));
            }
        } else if (command.equals("CANCEL")) {
            controlPanel.setVisible(false);
        }
    }

    public String getName() {
        return "Outline Axis";
    }

    public String toString() {
        return getName();
    }

    public JPopupMenu getContextualMenu() {
        return contextualMenu;
    }

    public void remove() {
        pipelineManager.removeVtkObject(axisObject);
        pipelineManager.removeVtkObject(outlineObject);
        pipelineManager.removeVtkObject(filter);
    }
    
    public Filter getInternalFilter() {
        return filterImpl;
    }

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


    /**
     * return null, because no GUI defined. 
     */
    public PlugInControlUI getControlUI() {        
        return null;
    }

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

}
