/**
 * Project : Cassandra-Penelope Plugin
 * Copyright : (c) Artenum SARL, 24 rue Louis Blanc
 * 75010, Paris, France 2009-2010
 * http://www.artenum.com
 * All copyright and trademarks reserved.
 * Email : contact@artenum.com
 * Licence : cf. LICENSE.txt
 * Developed By : Artenum SARL
 * Authors : Sebastien Jourdain (jourdain@artenum.com)
 * Benoit thiebault (thiebault@artenum.com)
 * Jeremie Turbet (JeT) (turbet@artenum.com)
 * Julien Forest (j.forest@artenum.com)
 * Created : (JFreeMesh) 2009
 * Modified : 08 apr. 2011
 */
package com.artenum.cassandra.plugin.penelope;

import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.logging.Logger;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import vtk.vtkActor;
import vtk.vtkDataSet;
import vtk.vtkDataSetMapper;

import com.artenum.cassandra.pipeline.PipeLineManager;
import com.artenum.cassandra.plugin.PluginManager;
import com.artenum.penelope.mesh.MeshType;
import com.artenum.penelope.mesh.interfaces.Mesh;
import com.artenum.penelope.mesh.io.FileFormatException;
import com.artenum.penelope.plugin.gmsh.mesh.GMSHFilePart22;
import com.artenum.penelope.plugin.gmsh.mesh.GmshMeshBuilder10;
import com.artenum.penelope.plugin.gmsh.mesh.GmshMeshBuilder22;
import com.artenum.penelope.plugin.vtk.VtkGridBuilder;

//import com.artenum.cassandra.pipeline.CassandraObject;

/**
 * Define a plug-in for the Cassandra 3D viewer (see http://www.artenum.com/FR/Produits-Cassandra.html). See the
 * Cassandra's documentation for further information.
 * 
 * @author S. Jourdain, Artenum SARL.
 * @author J. Forest, Artenum SARL.
 */
public class LoadMsh implements ActionListener {
    private final PipeLineManager pipelineManager;
    private final Frame owner;

    /**
     * 
     * @param pipeLineManager
     * @param pluginManager
     * @param owner
     */
    public LoadMsh(final PipeLineManager pipeLineManager, final PluginManager pluginManager, final Frame owner) {
        this.pipelineManager = pipeLineManager;

        System.out.println("Loede pipeline manager ------> " + this.pipelineManager.toString());

        this.owner = owner;
        Logger.getLogger("Memory").setUseParentHandlers(false);
    }

    @Override
    public void actionPerformed(final ActionEvent e) {
        final JFileChooser chooser = new JFileChooser();
        chooser.setMultiSelectionEnabled(true);
        // chooser.setFileFilter(new FileFilter() {
        // public boolean accept(File f) {
        // return f.isDirectory() || f.getName().endsWith(".msh");
        // }
        //
        // public String getDescription() {
        // return "Msh files";
        // }
        // });
        if (chooser.showOpenDialog(this.owner) == JFileChooser.APPROVE_OPTION) {
            final File[] mshFiles = chooser.getSelectedFiles();
            for (final File mshFile : mshFiles) {
                if (mshFile.isFile()) {
                    Mesh mesh = null;
                    try {
                        // mesh.load( new GmshLoader10( mshFile.getAbsolutePath() ) );

                        // //////////////////////////////////////////////////////////
                        // Gmsh file loading...
                        // //////////////////////////////////////////////////////////
                        System.out.println("Loading " + mshFile.getAbsolutePath() + "... ");

                        // detection of the version
                        String currentLine;
                        int versionNumber = 1;
                        FileReader fileReader = null;
                        LineNumberReader lineReader = null;
                        try {
                            fileReader = new FileReader(mshFile.getAbsolutePath());
                            lineReader = new LineNumberReader(fileReader);
                            while ((currentLine = lineReader.readLine()) != null) {
                                if (GMSHFilePart22.HEADER_SECTION.getStartTag().compareToIgnoreCase(currentLine) == 0) {
                                    System.out.println("Header found, version higher than 1");
                                    versionNumber = 2;
                                }
                            }
                        } catch (final FileNotFoundException e1) {
                            e1.printStackTrace();
                        } catch (final IOException loadingException) {
                            loadingException.printStackTrace();
                        } finally {

                            if (fileReader != null) {
                                fileReader.close();
                            }
                            if (lineReader != null) {
                                lineReader.close();
                            }

                        }

                        // Gmsh's mesh file reading
                        try {
                            if (versionNumber == 1) {
                                final GmshMeshBuilder10 builder = new GmshMeshBuilder10(mshFile);
                                mesh = builder.buildMeshAndIdReset();
                            } else {
                                final GmshMeshBuilder22 builder = new GmshMeshBuilder22(mshFile);
                                mesh = builder.buildMeshAndIdReset();
                            }
                        } catch (final FileFormatException loadingException) {
                            loadingException.printStackTrace();
                            System.out.println("File format error.");
                        } catch (final IOException loadingException) {
                            loadingException.printStackTrace();
                        }
                        System.out.println("DONE");

                        VtkGridBuilder gridBuilder = null;
                        Object result = JOptionPane.showInputDialog(this.owner, "Choose the type of object to import:",
                                "Gmsh importer", JOptionPane.QUESTION_MESSAGE, null, new Object[] { "Node", "Edge",
                                        "Face", "Cell" }, "Edge");

                        if (result == null) {
                            result = "Edge";
                        }

                        if (result.equals("Node")) {
                            gridBuilder = new VtkGridBuilder(mesh, MeshType.VERTEX);
                        }

                        if (result.equals("Edge")) {
                            gridBuilder = new VtkGridBuilder(mesh, MeshType.EDGE);
                        }

                        if (result.equals("Face")) {
                            gridBuilder = new VtkGridBuilder(mesh, MeshType.FACE);
                        }

                        if (result.equals("Cell")) {
                            gridBuilder = new VtkGridBuilder(mesh, MeshType.POLYHEDRON);
                        }

                        this.buildDefaultPipeLine(gridBuilder.buildVtkUnstructuredGrid(), mshFile.getName());
                    } catch (final Exception ex) {
                        ex.printStackTrace();
                        JOptionPane.showMessageDialog(this.owner, ex.getMessage());
                    }
                }
            }
        }
    }

    /**
     * Build-up the default end-part pipeline for the given vtkDataSet. In practice, this will create a mapper, an
     * actor, a lookUpTable and a color table for the dataSet.
     * 
     * @param dataset
     *            - input dataSet
     * @param fileName
     *            - Name given to the dataSet.
     */
    private void buildDefaultPipeLine(final vtkDataSet dataset, final String fileName) {
        final vtkDataSetMapper mapper = new vtkDataSetMapper();
        mapper.SetInput(dataset);
        mapper.Update();
        final vtkActor actor = new vtkActor();
        actor.SetMapper(mapper);
        // Register in cassandra
        // this.pipelineManager.addDataSet( dataset, fileName );
        // pipelineManager.addDataSet(null, "nullName");
        // this.pipelineManager.addMapper( mapper, fileName );

        // Show actors
        // this.pipelineManager.setActorVisible( this.pipelineManager.addActor( actor, fileName ), true );

        System.out.println(this.pipelineManager.getDataSetList().getElementAt(0).toString());
        // (Class) this.pipelineManager.getDataSetList().getElementAt(0);
    }
}
