/*
Copyright 2004 Persistent Systems Private Limited.

Software developed as a part of the Virtual Observatory - India
initiative by Persistent Systems, India (website - http://www.persistent.co.in)
and the Inter-University Centre for Astronomy and Astrophysics
(website - http://www.iucaa.ernet.in).

Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for educational and research purpose,
provided that this copyright notice and the following paragraph
appears in all copies of this software.

DISCLAIMER OF WARRANTY.
-----------------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
IN NO EVENT SHALL THE RIGHTHOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

*/

package com.jvt.ext;

// java imports
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

// java swing related imports
import javax.swing.JFrame;
import javax.swing.JPanel;

// VOPlot related imports
import com.jvt.applets.PlotVOApplet;
import com.jvt.ext.ColumnException;
import com.jvt.ext.ColumnMetaData;
import com.jvt.ext.DataNotFoundException;
import com.jvt.ext.FilterException;
import com.jvt.ext.PlotException;
import com.jvt.ext.VOPlotExternalApp;
import com.jvt.ext.VOTableParseException;

/**
 * <p>VOPlot Launcher </p> <br>
 * <p>Class to demonstrate the usage of the external interface to VOPlot.</p>
 * <p>Copyright: Copyright (c) 2004 Persistent Systems </p>
 * <p>Software developed under Virtual Observatory India initiative
 * by Persistent Systems, Pune and IUCAA. For feedback and comments
 * please contact voindia@vo.iucaa.ernet.in </p>
 * @version 1.0
 */
public class VOPlotLauncher
{
    /**
     * Default Constructor
     *
     */
    public VOPlotLauncher()
    {
        try
        {
            _panel = null;
            _voExtApp = null;

            // Load a VOTable from a File
            InputStream votableStream =
                new java.io.ByteArrayInputStream(_VOTable.getBytes());
            _panel = new JPanel();
            _panel.setLayout(new BorderLayout());

            // Call the static method addVOPlot(Panel) of PlotVOApplet
            // to create a new VOPlot object and add it to the panel
            // passed as argument to the function.
            _voExtApp = PlotVOApplet.addVOPlot(_panel);

            // Load the VOTable from the InputStream object.
            try
            {
                _voExtApp.loadVOTable(votableStream, true);
                System.out.println("Info: Loaded VOtable in VOPlot.");
            } catch (DataNotFoundException ex)
            {
                System.out.println("Error: DataNotFoundException : " + ex);
            } catch (VOTableParseException ex)
            {
                System.out.println("Error: VOTableParseException : " + ex);
            } catch (PlotException ex)
            {
                System.out.println("Error: PlotException : " + ex);
            }

            // Select points on the plot.
            selectPoints();

            // Highlight points on the plot.
            highlightPoints();

            // Add new columns.
            addNewColumns();

            // Overlay plots on top of the current one.
            overlay();

            // Add a filter for the data.
            addFilter();

            // Set filter for the data.
            setFilter();

            // Write data in VOTable format to a file.
            writeVOTable();

            // Load Data into VOPlot which is not in VOTable format.
            loadDataIntoVOPlot();

            // Create a frame to add the panel and a listener for closing
            // the application.
            createFrame();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    /**
     * Select points on the plot.
     * This method has been written to demonstrate the use of selecting
     * various points on the plot.
     */
    private void selectPoints()
    {
        _voExtApp.selectPoints(new int[] { 0 });
        System.out.println("Info: Selected point at 0");

    }

    /**
     * Highlight points on the plot.
     * This method has been written to demonstrate the use of highlighting
     * various points on the plot.
     */
    private void highlightPoints()
    {
        _voExtApp.highlightPoints(new int[] { 0, 1 });
        System.out.println("Info: Highlighted point at 0, 1");
    }

    /**
     * Add new columns.
     * This method has been written to demonstrate the use of adding new
     * columns to the plot.
     */
    private void addNewColumns()
    {
        try
        {
            _voExtApp.addColumn("$1 + $2", "deg", "$1 + $2");
            System.out.println("Info: added new column '$1 + $2'");

            _voExtApp.addColumn("$1 - $2", "deg", "$1 - $2");
            System.out.println("Info: added new column '$1 - $2'");

        } catch (ColumnException ex)
        {
            System.out.println(ex);
        }
    }

    /**
     * Overlay plots on top of the current one.
     * This method has been written to demonstrate the use of overlaying
     * of different plots.
     */
    private void overlay()
    {
        try
        {
            _voExtApp.plotColumns(3, true, 4, true, true);
            _voExtApp.plotColumns(5, false, 6, false, true);

        } catch (PlotException ex)
        {
            System.out.println(ex);
        }

        // Show full range in case the data from new dataset is out of current
        // plot area.
        _voExtApp.showFullRange();
    }

    /**
     * Add a filter for the data.
     * This method has been written to demonstrate the use of adding filters
     * for the data.
     */
    private void addFilter()
    {
        try
        {
            _voExtApp.addFilter("($1 > 0.0)", "($1 > 0.0)");
            System.out.println("Info: added new filter '$1 > 0.0'");
        } catch (FilterException ex)
        {
            System.out.println("Error: " + ex);
        }
    }

    /**
     * Set filter for the data.
     * This method has been written to demonstrate the use of setting a
     * particular filter for the data.
     */
    private void setFilter()
    {
        try
        {
            _voExtApp.setFilter("($1 > 0.0)");
        } catch (FilterException ex)
        {
            System.out.println("Error: " + ex);
        }
    }

    /**
     * Write data in VOTable format to a file.
     * This method has been written to demonstrate the use of writing
     * the data in VOTable format.
     */
    private void writeVOTable()
    {
        try
        {
            String savedVOTable = "c:/votable.xml";
            _voExtApp.writeVOTable(new FileOutputStream(savedVOTable));
            System.out.println("Info: Writing VOTable to " + savedVOTable);
        } catch (IOException ex)
        {
            System.out.println("Error: IOException : " + ex);
        }
    }

    /**
     * Load Data into VOPlot which is not in VOTable format.
     *
     */
    private void loadDataIntoVOPlot()
    {
        // The sample data which we load is the following :
        // RecNum  VMag   BMag   RA_Degrees   DEC_Degrees    RA         DEC
        // '1.0'  '15.0'  '16.0' '07.8688'    '77.5388'     '03 10 57.65' '+66 34 02.6'
        // '2.0'  '21.0'  '14.0' '21.0974'    '68.3253'     '20 17 32.50' '+06 23 51.7'

        // Create a vector for MetaData
        Vector metaData = new Vector();

        // Create com.jvt.ext.ColumnMetaData Objects for storing information
        // about columns.
        ColumnMetaData column1Info =
            new ColumnMetaData("RecNum", ColumnMetaData.DATATYPE_DOUBLE, "mag", " ");
        ColumnMetaData column2Info =
            new ColumnMetaData("VMag", ColumnMetaData.DATATYPE_DOUBLE, "deg", " ");
        ColumnMetaData column3Info =
            new ColumnMetaData("BMag", ColumnMetaData.DATATYPE_DOUBLE, "mag", " ");
        ColumnMetaData column4Info =
            new ColumnMetaData("RA_Degrees", ColumnMetaData.DATATYPE_DOUBLE, "deg", "POS_EQ_RA_MAIN");
        ColumnMetaData column5Info =
            new ColumnMetaData("DEC_Degrees", ColumnMetaData.DATATYPE_DOUBLE, "deg", "POS_EQ_DEC_MAIN");

        // Loading RA and DEC in sexagecimal.
        ColumnMetaData column6Info =
            new ColumnMetaData("RA", ColumnMetaData.DATATYPE_CHAR, "h:m:s", "POS_EQ_RA_MAIN");
        ColumnMetaData column7Info =
            new ColumnMetaData("DEC", ColumnMetaData.DATATYPE_CHAR, "d:m:s", "POS_EQ_DEC_MAIN");


        // Add ColumnMetaData objects to MetaData.
        metaData.add(column1Info);
        metaData.add(column2Info);
        metaData.add(column3Info);
        metaData.add(column4Info);
        metaData.add(column5Info);
        metaData.add(column6Info);
        metaData.add(column7Info);

        // Create a Vector of Vectors for the Data.
        Vector data = new Vector();
        Vector row1 = new Vector();
        Vector row2 = new Vector();

        // add row 1
        row1.add("1.0");
        row1.add("15.0");
        row1.add("16.0");
        row1.add("7.8688");
        row1.add("77.5366");
        row1.add("03 10 57.65");
        row1.add("+66 34 02.6");
        data.add(row1);

        // add row 2
        row2.add("2.0");
        row2.add("21.0");
        row2.add("14.0");
        row2.add("21.0974");
        row2.add("68.3253");
        row2.add("20 17 32.50");
        row2.add("+06 23 51.7");
        data.add(row2);

        // Load the Data so created without erasing previous plot.
        try
        {
            _voExtApp.loadData(metaData, data, true, true);
            System.out.println("Info: loaded more data in VOPlot.");
        } catch (PlotException ex)
        {
            System.out.println("Error while loading data in VOPlot: " + ex);
        }

    }

    /**
     * Create a frame to add the panel and a listener for closing the
     * application.
     */
    private void createFrame()
    {
        // Create a Frame and add VOPLot to it.
        final JFrame frame = new JFrame("VOPlot frame");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        frame.addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                System.out.println("Info: Frame closed. ");
                frame.dispose();
                System.exit(0);
            }
        });

        frame.getContentPane().add(_panel, BorderLayout.CENTER);
        frame.setSize(800, 600);
        frame.setVisible(true);
    }

    /**
     * Main method
     * @param args Arguments to the VOPlotLauncher application
     */
    public static void main(String[] args)
    {
        new VOPlotLauncher();
    }

    /**
     * Member variables
     *
     */

    /**
     * The external application interface.
     *
     */
    private VOPlotExternalApp _voExtApp = null;

    /**
     * The panel for displaying the VOPlot.
     *
     */
    private JPanel _panel = null;

    /**
    * Sample VOTable used in VOPlot.
    * This VOTable was downloaded from VizieR Catalogue Service.
    */
    static final String _VOTable =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\" \n" +
        "<VOTABLE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n"+
        "xsi:noNamespaceSchemaLocation=\"http://vizier.u-strasbg.fr/xml/VOTable.xsd\"> \n" +
        "<DESCRIPTION>\n" +
        "VizieR Astronomical Server: urania.iucaa.ernet.in    2004-04-16T14:53:13" +
        "</DESCRIPTION> \n" +
        "<DEFINITIONS>" +
        "<COOSYS ID=\"J2000\" system=\"eq_FK5\" equinox=\"J2000\"/> \n" +
        "</DEFINITIONS> \n" +
        "<INFO ID=\"Ref\" name=\"-ref\" value=\"VOTx28295\" /> \n" +
        "<RESOURCE ID=\"yCat_41450111\" name=\"J/A+AS/145/111\"> \n" +
        "<DESCRIPTION>HDF-South catalogue of galaxies (Volonteri+, 2000)</DESCRIPTION> \n" +
        "<TABLE ID=\"J_A_AS_145_111_colour\" name=\"J/A+AS/145/111/colour\"> \n" +
        "<DESCRIPTION>UBVI colours catalogue</DESCRIPTION> \n" +
        "<FIELD name=\"_RAJ2000\" ucd=\"POS_EQ_RA_MAIN\" ref=\"J2000\" datatype=\"char\" arraysize=\"11\" unit=\"&quot;h:m:s&quot;\"> \n" +
        "<DESCRIPTION>Right ascension (FK5) Equinox=J2000. (computed by VizieR, not part of the original data)</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<FIELD name=\"_DEJ2000\" ucd=\"POS_EQ_DEC_MAIN\" ref=\"J2000\" datatype=\"char\" arraysize=\"11\" unit=\"&quot;d:m:s&quot;\"> \n" +
        "<DESCRIPTION>Declination (FK5) Equinox=J2000. (computed by VizieR, not part of the original data)</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<FIELD name=\"B-V\" ucd=\"PHOT_CI_B-V\" datatype=\"float\" width=\"6\" precision=\"3\" unit=\"mag\"> \n" +
        "<DESCRIPTION>? B(450nm)-V(606nm) colour</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<FIELD name=\"V-I\" ucd=\"PHOT_HST_CI_V-I\" datatype=\"float\" width=\"6\" precision=\"3\" unit=\"mag\"> \n" +
        "<DESCRIPTION>? V(606nm)-I(814nm) colour</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<FIELD name=\"B-I\" ucd=\"PHOT_JHN_B-I\" datatype=\"float\" width=\"6\" precision=\"3\" unit=\"mag\"> \n" +
        "<DESCRIPTION>? B(450nm)-I(814nm) colour</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<FIELD name=\"U-B\" ucd=\"PHOT_CI_U-B\" datatype=\"float\" width=\"6\" precision=\"3\" unit=\"mag\"> \n" +
        "<DESCRIPTION>? U(300nm)-B(450nm) colour</DESCRIPTION> \n" +
        "</FIELD> \n" +
        "<DATA><TABLEDATA> \n" +
        "<TR><TD>22 33 03.57</TD><TD>-60 33 41.7</TD><TD>1.143</TD><TD>0.733</TD><TD>1.876</TD><TD>1.140</TD></TR> \n" +
        "<TR><TD>22 33 02.76</TD><TD>-60 33 22.1</TD><TD>1.514</TD><TD>1.037</TD><TD>2.552</TD><TD>1.416</TD></TR> \n" +
        "<TR><TD>22 32 57.54</TD><TD>-60 33 06.1</TD><TD>0.781</TD><TD>0.748</TD><TD>1.529</TD><TD>0.716</TD></TR> \n" +
        "<TR><TD>22 32 50.90</TD><TD>-60 32 43.0</TD><TD>1.439</TD><TD>1.200</TD><TD>2.638</TD><TD>1.058</TD></TR> \n" +
        "<TR><TD>22 32 53.92</TD><TD>-60 33 13.5</TD><TD>1.445</TD><TD>0.823</TD><TD>2.268</TD><TD>1.746</TD></TR> \n" +
        "<TR><TD>22 32 53.64</TD><TD>-60 32 36.0</TD><TD>0.975</TD><TD>0.573</TD><TD>1.548</TD><TD>0.972</TD></TR> \n" +
        "<TR><TD>22 32 52.31</TD><TD>-60 33 08.4</TD><TD>0.911</TD><TD>0.723</TD><TD>1.634</TD><TD>0.656</TD></TR> \n" +
        "<TR><TD>22 32 46.90</TD><TD>-60 33 54.9</TD><TD>1.802</TD><TD>1.298</TD><TD>3.099</TD><TD>1.399</TD></TR> \n" +
        "<TR><TD>22 32 56.07</TD><TD>-60 31 48.9</TD><TD>0.810</TD><TD>0.603</TD><TD>1.414</TD><TD>0.461</TD></TR> \n" +
        "<TR><TD>22 32 54.69</TD><TD>-60 33 33.2</TD><TD>0.783</TD><TD>0.483</TD><TD>1.266</TD><TD>1.389</TD></TR> \n" +
        "<TR><TD>22 32 47.58</TD><TD>-60 34 08.6</TD><TD>0.813</TD><TD>0.753</TD><TD>1.567</TD><TD>0.339</TD></TR> \n" +
        "<TR><TD>22 32 55.71</TD><TD>-60 32 11.5</TD><TD>1.898</TD><TD>1.472</TD><TD>3.370</TD><TD>1.191</TD></TR> \n" +
        "<TR><TD>22 32 53.74</TD><TD>-60 33 37.6</TD><TD>0.714</TD><TD>0.595</TD><TD>1.309</TD><TD>0.538</TD></TR> \n" +
        "<TR><TD>22 32 54.78</TD><TD>-60 32 15.5</TD><TD>1.686</TD><TD>1.291</TD><TD>2.977</TD><TD>1.570</TD></TR> \n" +
        "<TR><TD>22 33 01.89</TD><TD>-60 33 16.4</TD><TD>0.944</TD><TD>0.631</TD><TD>1.575</TD><TD>0.910</TD></TR> \n" +
        "</TABLEDATA></DATA> \n" +
        "</TABLE> \n" +
        "</RESOURCE> \n" +
        "</VOTABLE> \n";
}