package org.mbari.seepsearch.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import org.mbari.seepsearch.core.RovAltitudeFilter;
import org.mbari.seepsearch.grid.AsciiNullGridReader;
import org.mbari.seepsearch.grid.AsciiRasterGridWriter;
import org.mbari.seepsearch.grid.GridException;
import org.mbari.seepsearch.grid.GridUtil;
import org.mbari.seepsearch.grid.RasterGrid;
import org.mbari.swing.FileProgressFrame;

/**
 * <p>Self contained frame that contains everythign needed to create a RasterGrid
 * populated by edited ROV data.</p>
 *
 * <p>The Seep Search project is a sub-project of the Continental
 * Margin Fluids and Gases project (200010). It involves the analysis of
 * archived ROV data to obtain understanding of seep distritution in Monterey
 * Bay.</p>
 *
 * <p>The Purpose of this Java package is to intercompare ROV Navigation files,
 * VIMS data on seep community observations and the EM-300 bathymetry. We are
 * looking for locations where the ROV navigation files and the EM-300 data
 * have similar depths between the 2 data sets, which implies that the ROV is
 * observing the sea floor.</p><hr><br>
 *
 * <p>MBARI provides this documentation and code &quot;as is&quot;, with no
 * warranty, express or implied, of its quality or consistency. It is provided
 * without support and without obligation on the part of the Monterey Bay
 * Aquarium Research Institute to assist in its use, correction, modification,
 * or enhancement. This information should not be published or distributed to
 * third parties without specific written permission from MBARI.</p><br>
 *
 * Copyright 2002 MBARI.<br>
 * MBARI Proprietary Information. All rights reserved.<br><hr><br>
 *
 * $Log: RovGridGeneratorFrame.java,v $
 * Revision 1.4  2002/07/02 21:08:34  brian
 * Minor modifications
 *
 * Revision 1.3  2002/04/17 21:48:50  brian
 * Adding Vars Database support. Moving to IRovNavigationIterator as the common interface between disparate datasets
 *
 * Revision 1.2  2002/02/06 00:39:07  brian
 * no message
 *
 * Revision 1.1  2002/01/30 00:23:56  brian
 * Added comments to all classes and methods. Tested the accuracy of AsciiRasterGridReader and AsciiRasterGridWriter. Also checked the the GridUtil was populating the spatial grids correctly and accurately. The data files generated matched up perfectly with the orginal text files. Also implemented an RovAltitudeFilter class to encapsulate different filtering methods.
 *<br><hr><br>
 *
 * @author  : $Author: brian $
 * @version : $Revision: 1.4 $
 */
public class RovGridGeneratorFrame extends JFrame {
    final JTabbedPane tabbedPane = new JTabbedPane();
    final FileManagerPanel1 fileManagerPanel = new FileManagerPanel1();
    final RovAltitudeFilterPanel filterPanel = new RovAltitudeFilterPanel();
    final JButton btnCreate = new JButton();
    final JButton btnCancel = new JButton();
    final JPanel panelExit = new JPanel();
    final ButtonGroup buttonGroup1 = new ButtonGroup();
    JRadioButton rbUtm = new JRadioButton();
    JPanel utmPanel = new JPanel();
    JRadioButton rbGeo = new JRadioButton();
    JTextField tfZone = new JTextField();
    JLabel utmLabel3 = new JLabel();
    JLabel utmLabel2 = new JLabel();
    JLabel utmLabel1 = new JLabel();

    public RovGridGeneratorFrame() {
        try {
            jbInit();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        RovGridGeneratorFrame frameFromNav = new RovGridGeneratorFrame();
    }

    private void jbInit() throws Exception {

        btnCreate.setToolTipText("");
        btnCreate.setText("OK");
        btnCreate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnCreate_actionPerformed(e);
            }
        });
        btnCancel.setText("Cancel");
        btnCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnCancel_actionPerformed(e);
            }
        });

        rbUtm.setText("utm");
        rbUtm.setToolTipText("");
        rbGeo.setText("geographic");
        rbGeo.setToolTipText("");
        rbGeo.setSelected(true);
        tfZone.setText("10");
        utmLabel3.setText(")");
        utmLabel2.setText("(zone");
        utmLabel1.setText("Bathymetry Grid is");
        this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
        this.getContentPane().add(panelExit, BorderLayout.SOUTH);
        panelExit.add(btnCreate, null);
        panelExit.add(btnCancel, null);
        tabbedPane.add(fileManagerPanel,    "Select Files");
        fileManagerPanel.add(utmPanel, null);
        utmPanel.add(utmLabel1, null);
        utmPanel.add(rbGeo, null);
        utmPanel.add(rbUtm, null);
        buttonGroup1.add(rbGeo);
        buttonGroup1.add(rbUtm);
        rbGeo.setSelected(true);
        utmPanel.add(utmLabel2, null);
        utmPanel.add(tfZone, null);
        utmPanel.add(utmLabel3, null);
        tabbedPane.add(filterPanel,    "Filter ROV data");
    }

    void btnCreate_actionPerformed(ActionEvent evt) {
        try {
            this.setVisible(false);
            this.repaint();
            createGrid();
            this.dispose();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this,
                    "Error: " + e.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE);
            //e.printStackTrace();
        } catch (GridException e) {
            JOptionPane.showMessageDialog(this,
                    "Error: " + e.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE);
            //e.printStackTrace();
        }
    }

    void btnCancel_actionPerformed(ActionEvent e) {
        this.dispose();
    }

    void createGrid() throws IOException, GridException {

        final boolean isUtm = rbUtm.isSelected();

        // Get the input and output files
        final File input = fileManagerPanel.getInputFile();
        final File output = fileManagerPanel.getOutputFile();
        if (input == null) {
            JOptionPane.showMessageDialog(this,
                    "You forgot to select a Grid " +
                    "file to read", "ERROR", JOptionPane.ERROR_MESSAGE);
        } else if (output == null) {
            JOptionPane.showMessageDialog(this,
                    "You forgot to select a Grid " +
                    "file to write the data to", "ERROR", JOptionPane.ERROR_MESSAGE);
        }

        final AsciiNullGridReader reader = new AsciiNullGridReader(input);
        reader.read();
        final RasterGrid grid = reader.getGrid();
        final File[] navFiles = fileManagerPanel.getSelectedFiles();

        RovAltitudeFilter filter = filterPanel.getAltitudeFilter();

        this.setVisible(false);
        FileProgressFrame pf = new FileProgressFrame();
        JProgressBar pb = pf.getJProgressBar();
        pb.setStringPainted(true);
        pb.setMinimum(0);
        pb.setMaximum(navFiles.length + 1);
        pb.setValue(0);
        pf.pack();
        pf.setLocation(this.getLocation());
        pf.setVisible(true);
        Dimension d;
        Rectangle rect;
        int zoneNumber = -1;
        if (rbUtm.isSelected()) {
            zoneNumber = Integer.parseInt(tfZone.getText());
        }

        for (int i = 0; i < navFiles.length; i++) {
            pb.setValue(i);
            pb.setString(navFiles[i].getName());
            d = pb.getSize();
            rect = new Rectangle(0, 0, d.width, d.height);
            pb.paintImmediately(rect);
            GridUtil.populateGeoGridWithGeoNavData(grid, navFiles[i], filter,
                zoneNumber);
        }

        pb.setValue(navFiles.length);
        pb.setString("Writing " + output.getName());
        d = pb.getSize();
        rect = new Rectangle(0, 0, d.width, d.height);
        pb.paintImmediately(rect);
        /** @todo GridUtil does a great job of populating a grid. However some
         *  accuray is lost when writing out the header in AsciiGridWriter. Need
         *   to improve this */
        AsciiRasterGridWriter writer = new AsciiRasterGridWriter(output);
        writer.write(grid, 0, 7);
        pb = null;
        pf.dispose();
        pf = null;

    }
}