
/*
 * AggregateUrisDialog.java
 *
 * Created on Nov 4, 2010, 1:02:38 PM
 */

package org.autoplot;

import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import org.autoplot.dom.Application;
import org.autoplot.dom.DataSourceFilter;
import org.autoplot.dom.DomOps;
import org.autoplot.datasource.DataSetSelector;
import org.autoplot.datasource.ThreadManager;
import org.das2.util.LoggerManager;

/**
 * Dialog assisting the scientists in creating aggregations for file
 * URIS.  This uses org.autoplot.datasource.DataSourceUtil.makeAggregation
 * to look for parts of filenames that look like dates, for example 20150516
 * would be replaced with $Y$m$d.
 * 
 * @author jbf
 */
public class AggregateUrisDialog extends javax.swing.JPanel {

    private final Application dom;
    private final DataSetSelector dataSetSelector;

    private static final Logger logger= LoggerManager.getLogger( "autoplot.gui" );
    /** 
     * Creates new form AggregateUrisDialog
     * @param dom the application
     * @param sel it's dataset selector
     */
    public AggregateUrisDialog( Application dom, DataSetSelector sel ) {
        initComponents();
        this.dom= dom;
        this.dataSetSelector= sel;

        previewDataSetSelector.setHidePlayButton(true);
        String s = dataSetSelector.getValue();
        String agg = org.autoplot.datasource.DataSourceUtil.makeAggregation(s);
        if (agg != null) {
            previewDataSetSelector.setValue(agg);
        } else {
            this.jLabel5.setText( this.jLabel5.getText()+"  (Unable to create aggregation spec, couldn't find yyyymmdd.)");
            previewDataSetSelector.setValue(s);
        }

        Application dom2= (Application)dom.copy();
        DomOps.aggregateAll(dom2);
        allUrisTA.setText("");
        for ( DataSourceFilter dsf: dom2.getDataSourceFilters() ) {
            if ( !dsf.getUri().startsWith("vap+internal:") ) {
                allUrisTA.insert( dsf.getUri() + "\n", allUrisTA.getCaretPosition() );
            }
        }
        allUrisTA.setEditable(false);

        addressBarUriButton.setIcon( new ImageIcon( this.getClass().getResource("/org/autoplot/datasource/go.png") ) );
        allUrisButton.setIcon( new ImageIcon( this.getClass().getResource("/org/autoplot/datasource/go.png") ) );
    }

    /**
     *  show this in a modal dialog, without the Okay button.
     */
    public void showDialog() {
        Window window = SwingUtilities.getWindowAncestor(this.dataSetSelector);
        final JDialog dialog;
        if (window instanceof Frame) {
            dialog = new JDialog((Frame)window, "Aggregate URIs", true);
        } else {
            dialog = new JDialog((Dialog)window, "Aggregate URIs", true);
        }
        dialog.getContentPane().setLayout( new BorderLayout() );
        dialog.add(this);

        JPanel buttons= new JPanel();
        buttons.setLayout( new FlowLayout( FlowLayout.RIGHT ) );
        JButton cancel= new JButton("Cancel");
        cancel.setAction( new AbstractAction("Cancel") {
            @Override
            public void actionPerformed(ActionEvent e) {
                dialog.setVisible(false);
                dialog.dispose();
            }
        } );
        cancel.setIcon(AutoplotUtil.cancelIcon());
        
        dialog.getRootPane().registerKeyboardAction( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                org.das2.util.LoggerManager.logGuiEvent(e);        
                dialog.setVisible(false);
                dialog.dispose();
            }
        }, KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), JComponent.WHEN_IN_FOCUSED_WINDOW );       

        JButton help= new JButton("Help");
        help.setAction( new AbstractAction("Help") {
            @Override
            public void actionPerformed(ActionEvent e) {
                AutoplotUtil.openBrowser( "https://autoplot.org/help#Aggregation" );
            }
        } );

        buttons.add( help );
        buttons.add( cancel );
        buttons.add( new JLabel("   ") );

        dialog.add( this, BorderLayout.CENTER );
        dialog.add( buttons, BorderLayout.SOUTH );

        dialog.pack();
        dialog.setLocationRelativeTo(window);
        dialog.setVisible(true);
    }

    /** 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() {

        jPanel1 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        addressBarUriButton = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        allUrisButton = new javax.swing.JButton();
        jLabel6 = new javax.swing.JLabel();
        previewDataSetSelector = new org.autoplot.datasource.DataSetSelector();
        jScrollPane1 = new javax.swing.JScrollPane();
        allUrisTA = new javax.swing.JTextArea();
        showWildcardsButton = new javax.swing.JButton();

        jLabel4.setText("<html>Autoplot has two ways of turning URIs of single files into aggregations that will combine data when the first dimension is time.  \nAn aggregation URI is one with wildcards (like $Y for year) that allows Autoplot to fetch multiple files to cover a time range.</html> ");
        jLabel4.setVerticalAlignment(javax.swing.SwingConstants.TOP);

        addressBarUriButton.setText("Focus URI");
        addressBarUriButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addressBarUriButtonActionPerformed(evt);
            }
        });

        jLabel5.setText("<html>Autoplot has attempted to make an aggregated URI from the focus URI.  Pressing the \"Focus URI\" button will accept the new URI:</html>");
        jLabel5.setVerticalAlignment(javax.swing.SwingConstants.TOP);

        allUrisButton.setText("All URIs");
        allUrisButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                allUrisButtonActionPerformed(evt);
            }
        });

        jLabel6.setText("<html>Autoplot has attempted to form aggregations for all the URIs on the canvas.  Pressing the \"All URIs\" button will accept these changes.  Here you can review the replacement URIs:</html>");
        jLabel6.setVerticalAlignment(javax.swing.SwingConstants.TOP);

        allUrisTA.setColumns(20);
        allUrisTA.setRows(5);
        allUrisTA.setText("vap+dat:http://autoplot.org/data/autoplot.dat\n");
        jScrollPane1.setViewportView(allUrisTA);

        org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 821, Short.MAX_VALUE)
            .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel2Layout.createSequentialGroup()
                    .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                        .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel2Layout.createSequentialGroup()
                            .add(24, 24, 24)
                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 776, Short.MAX_VALUE))
                        .add(jPanel2Layout.createSequentialGroup()
                            .addContainerGap()
                            .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                                .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel2Layout.createSequentialGroup()
                                    .add(allUrisButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 120, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                    .add(jLabel6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 584, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel2Layout.createSequentialGroup()
                                    .add(12, 12, 12)
                                    .add(previewDataSetSelector, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 776, Short.MAX_VALUE))
                                .add(org.jdesktop.layout.GroupLayout.LEADING, jPanel2Layout.createSequentialGroup()
                                    .add(addressBarUriButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 123, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                    .add(jLabel5, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 580, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))))
                    .addContainerGap()))
        );

        jPanel2Layout.linkSize(new java.awt.Component[] {jLabel5, jLabel6}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        jPanel2Layout.linkSize(new java.awt.Component[] {addressBarUriButton, allUrisButton}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(0, 514, Short.MAX_VALUE)
            .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(jPanel2Layout.createSequentialGroup()
                    .addContainerGap()
                    .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(addressBarUriButton)
                        .add(jLabel5, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(previewDataSetSelector, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 39, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                    .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(allUrisButton)
                        .add(jLabel6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 367, Short.MAX_VALUE)
                    .addContainerGap()))
        );

        showWildcardsButton.setText("Show Wildcards");
        showWildcardsButton.setToolTipText("Show wildcards in browser");
        showWildcardsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showWildcardsButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(690, Short.MAX_VALUE)
                .add(showWildcardsButton)
                .addContainerGap())
            .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .add(jLabel4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 664, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(136, Short.MAX_VALUE)))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .add(showWildcardsButton)
                .add(37, 37, 37)
                .add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .add(jLabel4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 77, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(501, Short.MAX_VALUE)))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    private void addressBarUriButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addressBarUriButtonActionPerformed
        final Application dom2= (Application)dom.copy();
        DataSourceFilter dsf= dom.getController().getDataSourceFilter();
        //String newUri= previewDataSetSelector.getEditor().getText();
        String newUri= previewDataSetSelector.getValue();
        int f= -1;
        DataSourceFilter[] dsfs= dom.getDataSourceFilters();
        for ( int i=0; i<dsfs.length; i++ ){
            if ( dsfs[i]==dsf ) {
                f= i;
            }
        }
        if ( f==-1 ) throw new IllegalArgumentException("bad state ..");
        dom2.getDataSourceFilters(f).setUri(newUri);
        dataSetSelector.setValue(newUri);
        Runnable run= new Runnable() {
            @Override
            public void run() {
                dom.syncTo(dom2);
                DataSourceFilter[] dsfs= dom.getDataSourceFilters();
                for ( DataSourceFilter dsf: dsfs ) {
                    dsf.getController().update();
                    dom.getController().getApplicationModel().addRecent( dsf.getUri() );
                }
            }
        };
        if ( ! ThreadManager.getInstance().run( run, "aggregateUris" ) ) {
            JOptionPane.showMessageDialog( this, "Operation is currently busy.");
        }
        SwingUtilities.invokeLater( new Runnable() {
            @Override
            public void run() {
                SwingUtilities.getWindowAncestor(AggregateUrisDialog.this).setVisible(false);
            }
        });

    }//GEN-LAST:event_addressBarUriButtonActionPerformed

    private void allUrisButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allUrisButtonActionPerformed
        final Application dom2= (Application)dom.copy();
        DomOps.aggregateAll(dom2);
        Runnable run= new Runnable() {
            @Override
            public void run() {
                dom.syncTo(dom2);
                DataSourceFilter[] dsfs= dom.getDataSourceFilters();
                for ( DataSourceFilter dsf: dsfs ) {
                    if ( dsf.getUri().equals("vap+internal:") ) {
                        logger.fine("skipping vap+internal:");
                    } else {
                        dsf.getController().update();
                        dom.getController().getApplicationModel().addRecent( dsf.getUri() );
                    }
                }
                DataSourceFilter dsf= dom.getController().getDataSourceFilter();
                if ( dsf!=null ) {
                    String newUri= dsf.getUri();
                    dataSetSelector.setValue(newUri);
                }
                
            }
        };
        
        if ( ! ThreadManager.getInstance().run( run, "aggregateUris" ) ) {
            JOptionPane.showConfirmDialog( this, "Operation is currently busy.");
        }
        SwingUtilities.invokeLater( new Runnable() {
            @Override
            public void run() {
                SwingUtilities.getWindowAncestor(AggregateUrisDialog.this).setVisible(false);
            }
        });

    }//GEN-LAST:event_allUrisButtonActionPerformed

    private void showWildcardsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showWildcardsButtonActionPerformed
        AutoplotUtil.openBrowser("https://github.com/autoplot/documentation/blob/main/md/help.md#wildcard-codes");
    }//GEN-LAST:event_showWildcardsButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addressBarUriButton;
    private javax.swing.JButton allUrisButton;
    private javax.swing.JTextArea allUrisTA;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private org.autoplot.datasource.DataSetSelector previewDataSetSelector;
    private javax.swing.JButton showWildcardsButton;
    // End of variables declaration//GEN-END:variables

}
