/*
 * Copyright (C) 2014 Laboratoire ThéMA - UMR 6049 - CNRS / Université de Franche-Comté
 * http://thema.univ-fcomte.fr
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


package org.thema.graphab.pointset;

import au.com.bytecode.opencsv.CSVReader;
import org.locationtech.jts.geom.Geometry;
import java.awt.HeadlessException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.opengis.feature.type.AttributeType;

/**
 * Dialog for importing point set from a shapefile or a CSV file
 * @author Gilles Vuidel
 */
public class PointImportDialog extends javax.swing.JDialog {

    /** User has clicked OK ? */
    public boolean isOk = false;

    /** The file to import */
    public File file;
    /** Is a shapefile or a CSV file ? */
    public boolean shpFile;
    /** The id field name */
    public String idAttr;
    /** The x and y attribute, for CSV file only */
    public String xAttr, yAttr;
    /** Other attributes to import */
    public List<String> zAttrs;

    /** Creates new form PointImportDialog */
    public PointImportDialog(java.awt.Frame parent) {
        super(parent, true);
        initComponents();
        setLocationRelativeTo(parent);
        getRootPane().setDefaultButton(okButton);
        
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        okButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        selectFilePanel = new org.thema.common.swing.SelectFilePanel();
        idComboBox = new javax.swing.JComboBox();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        yComboBox = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        xComboBox = new javax.swing.JComboBox();
        multipleSelectionPanel = new org.thema.common.swing.MultipleSelectionPanel();
        importAttrCheckBox = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/thema/graphab/Bundle"); // NOI18N
        setTitle(bundle.getString("PointImportDialog.title")); // NOI18N

        java.util.ResourceBundle bundle1 = java.util.ResourceBundle.getBundle("org/thema/graphab/pointset/Bundle"); // NOI18N
        okButton.setText(bundle1.getString("PointImportDialog.okButton.text")); // NOI18N
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        cancelButton.setText(bundle1.getString("PointImportDialog.cancelButton.text")); // NOI18N
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        selectFilePanel.setDescription(bundle1.getString("PointImportDialog.selectFilePanel.description")); // NOI18N
        selectFilePanel.setFileDesc(bundle1.getString("PointImportDialog.selectFilePanel.fileDesc")); // NOI18N
        selectFilePanel.setFileExts(bundle1.getString("PointImportDialog.selectFilePanel.fileExts")); // NOI18N
        selectFilePanel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectFilePanelActionPerformed(evt);
            }
        });

        jLabel1.setText(bundle1.getString("PointImportDialog.jLabel1.text")); // NOI18N

        jLabel2.setText(bundle1.getString("PointImportDialog.jLabel2.text")); // NOI18N

        jLabel3.setText(bundle1.getString("PointImportDialog.jLabel3.text")); // NOI18N

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, importAttrCheckBox, org.jdesktop.beansbinding.ELProperty.create("${selected}"), multipleSelectionPanel, org.jdesktop.beansbinding.BeanProperty.create("enabled"));
        bindingGroup.addBinding(binding);

        importAttrCheckBox.setText(bundle1.getString("PointImportDialog.importAttrCheckBox.text")); // NOI18N

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(0, 0, Short.MAX_VALUE)
                        .add(okButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 67, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(cancelButton))
                    .add(selectFilePanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 492, Short.MAX_VALUE)
                    .add(layout.createSequentialGroup()
                        .add(jLabel1)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(idComboBox, 0, 131, Short.MAX_VALUE)
                        .add(18, 18, 18)
                        .add(jLabel3)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(xComboBox, 0, 131, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jLabel2)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(yComboBox, 0, 133, Short.MAX_VALUE))
                    .add(layout.createSequentialGroup()
                        .add(importAttrCheckBox)
                        .add(0, 0, Short.MAX_VALUE))
                    .add(layout.createSequentialGroup()
                        .add(12, 12, 12)
                        .add(multipleSelectionPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );

        layout.linkSize(new java.awt.Component[] {cancelButton, okButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(selectFilePanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(idComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel3)
                    .add(xComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel2)
                    .add(yComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(18, 18, 18)
                .add(importAttrCheckBox)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(multipleSelectionPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE)
                .add(18, 18, 18)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(cancelButton)
                    .add(okButton))
                .addContainerGap())
        );

        bindingGroup.bind();

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
        file = selectFilePanel.getSelectedFile();
        idAttr = idComboBox.getSelectedItem().toString();
        if(!shpFile) {
            xAttr = xComboBox.getSelectedItem().toString();
            yAttr = yComboBox.getSelectedItem().toString();
        }
        zAttrs = multipleSelectionPanel.getSelectedItems();

        isOk = true;
        setVisible(false);
        dispose();
    }//GEN-LAST:event_okButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        setVisible(false);
        dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    private void selectFilePanelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectFilePanelActionPerformed
        File f = selectFilePanel.getSelectedFile();
        shpFile = !f.getName().toLowerCase().endsWith(".csv");

        xComboBox.setEnabled(!shpFile);
        yComboBox.setEnabled(!shpFile);

        List<String> attrs = new ArrayList<>();
        try {
            if(shpFile) {
                FileDataStore datastore = FileDataStoreFinder.getDataStore(f.toURI().toURL());
                List<AttributeType> types = datastore.getSchema().getTypes();
                DefaultComboBoxModel model = new DefaultComboBoxModel();
                for(AttributeType type : types) {
                    if (Geometry.class.isAssignableFrom(type.getBinding())) {
                        if(!type.getBinding().getName().endsWith("Point")) {
                            selectFilePanel.setSelectedFile(null);
                            JOptionPane.showMessageDialog(this, "Geometry type must be Point or MultiPoint.");
                            return;
                        }
                    } else {
                        model.addElement(type.getName().getLocalPart());
                        if (Number.class.isAssignableFrom(type.getBinding())) {
                            attrs.add(type.getName().getLocalPart());
                        }
                    }
                }

                idComboBox.setModel(model);
                datastore.dispose();
            } else {
                String[] header;
                try (CSVReader r = new CSVReader(new FileReader(f))) {
                    header = r.readNext();
                }
                idComboBox.setModel(new DefaultComboBoxModel(header));
                xComboBox.setModel(new DefaultComboBoxModel(header));
                yComboBox.setModel(new DefaultComboBoxModel(header));
                attrs = Arrays.asList(header);
            }

            multipleSelectionPanel.setItems(attrs.toArray());
        } catch(IOException | HeadlessException ex) {
            Logger.getLogger(PointImportDialog.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this, "An error occured !\n" + ex.getLocalizedMessage());
        }

}//GEN-LAST:event_selectFilePanelActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cancelButton;
    private javax.swing.JComboBox idComboBox;
    private javax.swing.JCheckBox importAttrCheckBox;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private org.thema.common.swing.MultipleSelectionPanel multipleSelectionPanel;
    private javax.swing.JButton okButton;
    private org.thema.common.swing.SelectFilePanel selectFilePanel;
    private javax.swing.JComboBox xComboBox;
    private javax.swing.JComboBox yComboBox;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

}
