
package org.mbari.vdm;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import org.exolab.castor.jdo.PersistenceException;
import org.mbari.seepsearch.grid.GridException;
import org.mbari.vars.dao.DAOException;
import org.mbari.vars.knowledgebase.model.Concept;
import org.mbari.vars.knowledgebase.model.dao.ConceptDAO;
import org.mbari.vars.knowledgebase.model.dao.KnowledgeBaseCache;
import org.mbari.vdm.expd.NetCdfCreator;
import org.mbari.vdm.knowledgebase.ConceptTree;
import org.mbari.vdm.knowledgebase.ConceptTreeReadOnly;
import org.mbari.vdm.knowledgebase.SearchableConceptTreePanel;

import ucar.ma2.InvalidRangeException;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import foxtrot.Job;
import foxtrot.Worker;

public class MinimalUI extends JPanel implements UiFeedback {

    private SearchableConceptTreePanel treePanel;
    private List conceptNames = new ArrayList();
    final JTextArea conceptNameArea = new JTextArea(5, 20);
    final JTextField gridName = new JTextField(20);
    private String earliestDate = "1996-01-01 00:00:00.0";
    

    public MinimalUI() {
        super();
        conceptNameArea.setWrapStyleWord(true);
        conceptNameArea.setLineWrap(true);
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                buildTreePanel();
            }
        });
    }

    public void reportError(String message, Exception e) {
        System.out.println(message);
        e.printStackTrace();
    }

    public void reportStatus(String statusMessage) {
        System.out.println(statusMessage);
    }

    private JPanel buildControlPanel() {
        // Rows: 1 Separator(header) - 3 Textarea for concept names - 5 gridName
        // 7 Go Button - 9 Config panel
        FormLayout layout = new FormLayout("default:grow",
            "pref, 5dlu, max(20dlu;pref), 5dlu, pref, 3dlu, pref, 3dlu, pref");
        CellConstraints cc = new CellConstraints();
        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
        builder.setDefaultDialogBorder();
        builder.addSeparator("Concepts", cc.xy(1, 1));
        builder.add(conceptNameArea, cc.xy(1, 3));
        JPanel gridNamePanel = new JPanel(new BorderLayout());
        JLabel gridNameLabel = new JLabel("Grid Name");
        gridNameLabel.setToolTipText("The name of file that the grid will be saved to");
        gridNamePanel.add(gridNameLabel, BorderLayout.WEST);
        gridName.setToolTipText("The name of file that the grid will be saved to");
        gridNamePanel.add(gridName);
        builder.add(gridNamePanel, cc.xy(1, 5));
        builder.add(buildGoButton(), cc.xy(1, 9, "center, center"));
        JPanel datePanel = new JPanel(new BorderLayout());
        JLabel dateLabel = new JLabel("Earliest Date");
        datePanel.add(dateLabel, BorderLayout.WEST);
        final JTextField dateField = new JTextField(earliestDate);
        dateField.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                earliestDate = dateField.getText();
            }
        });
        dateField.addFocusListener(new FocusAdapter(){
            public void focusLost(FocusEvent e) {
                earliestDate = dateField.getText();
            }
        });
        datePanel.add(dateField);
        builder.add(datePanel, cc.xy(1, 7));
        return builder.getPanel();
    }

    private JButton buildGoButton() {
        final JButton button = new JButton("Do It");
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String concepts = conceptNameArea.getText();
                final String[] conceptNames = concepts.split(", ");
                Worker.post(new Job() {

                    public Object run() {
                        button.setText("Busy...");
                        button.setEnabled(false);
                        VarsQueryer queryer = new VarsQueryer();
                        try {
                            String name = gridName.getText();
                            if (name == null || name.length() < 1) {
                                reportError("No grid name given, bailing out", null);
                                return null;
                            }
                            // if the name doesn't have an extension, give it
                            // one
                            if (!name.contains(".")) {
                                name = name + ".csv";
                                gridName.setText(name);
                            }
                            File csvFile = queryer.queryVars(conceptNames, gridName.getText(), MinimalUI.this, earliestDate);
                            if(csvFile != null){
                                try{
                                    VdmLine[] lines = (VdmLine[])CsvHelper.readLines(new BufferedReader(new FileReader(csvFile)), "VarsLine");
                                    NetCdfCreator.createNetcdfFromVarsCsv(csvFile, MinimalUI.this, lines);
                                }catch(InvalidRangeException e){
                                    MinimalUI.this.reportError("Error creating nc file for vars", e);
                                    return null;
                                }
                            }
                        } catch (PersistenceException e1) {
                            e1.printStackTrace();
                            System.exit(1);
                        } catch (SQLException e1) {
                            e1.printStackTrace();
                            System.exit(1);
                        } catch (IOException e1) {
                            e1.printStackTrace();
                            System.exit(1);
                        } catch (GridException e1) {
                            e1.printStackTrace();
                            System.exit(1);
                        }
                        reportStatus("Grid file created.");
                        return null;
                    }
                });
                button.setText("Do It");
                button.setEnabled(true);
            }
        });

        return button;
    }

    private void buildTreePanel() {
        FormLayout layout = new FormLayout("default:grow", "pref, 8dlu, pref");
        JPanel panel = new JPanel();
        panel.setLayout(layout);
        CellConstraints cc = new CellConstraints();

        JPanel controlPanel = buildControlPanel();
        panel.add(controlPanel, cc.xy(1, 1));

        JPanel temporaryPanel = new JPanel(new FormLayout("fill:pref:grow", "fill:pref:grow"));
        CellConstraints ccTemp = new CellConstraints();
        final JTextArea patience = new JTextArea();
        patience.setEditable(false);
        patience.setWrapStyleWord(true);
        patience.setLineWrap(true);
        patience.setText("Loading Knowledge Base, your patience is appreciated ;-)");
        temporaryPanel.add(patience, cc.xy(1, 1));
        final JScrollPane scrollPane = new JScrollPane(temporaryPanel);
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel, scrollPane);
        splitPane.setDividerLocation(.8);
        splitPane.setDividerSize(2);
        splitPane.setResizeWeight(.5);

        this.setLayout(new BorderLayout());
        this.add(splitPane);
        this.repaint();
        this.revalidate();
        Thread kbThread = new Thread() {

            public void run() {
                System.out.println("Loading concept tree");
                treePanel = new SearchableConceptTreePanel();
                Concept rootConcept = null;

                try {
                    rootConcept = KnowledgeBaseCache.getInstance().findRootConcept();
                } catch (DAOException e1) {
                    e1.printStackTrace();
                    SwingUtilities.invokeLater(new Runnable() {

                        public void run() {
                            patience.setText("Error loading knowledge base.");
                            patience.repaint();
                        }
                    });
                    return;
                }
                final ConceptTree conceptTree = new ConceptTreeReadOnly(rootConcept);
                treePanel.setJTree(conceptTree);
                conceptTree.addMouseListener(new MouseAdapter() {

                    public void mouseClicked(MouseEvent e) {
                        String name = conceptTree.getSelectedName();
                        try {
                            Concept concept = ConceptDAO.getInstance().findByName(name);
                            conceptNames.clear();
                            conceptNames.addAll(concept.getDescendentPrimaryNamesAsStrings());
                            conceptNameArea.setText("");
                            for (Iterator iter = conceptNames.iterator(); iter.hasNext();) {
                                String conceptString = (String) iter.next();
                                conceptNameArea.append(conceptString);
                                if (iter.hasNext()) {
                                    conceptNameArea.append(", ");
                                }
                            }
                            gridName.setText(name + ".csv");
                        } catch (DAOException e1) {
                            e1.printStackTrace();
                        }

                    }
                });
                SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        scrollPane.getViewport().removeAll();
                        scrollPane.getViewport().add(treePanel);
                        scrollPane.repaint();
                        treePanel.repaint();
                        MinimalUI.this.revalidate();
                    }
                });
            }
        };
        kbThread.start();

    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Minimal UI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(50, 50, 700, 700);
        frame.getContentPane().add(new MinimalUI());
        frame.setVisible(true);
    }
}
