/*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.autoupdate;

import java.awt.Font;
import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Iterator;

import javax.swing.JFileChooser;
import javax.swing.DefaultListModel;
import javax.swing.DefaultListSelectionModel;

import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
import org.openide.windows.WindowManager;

class SelectModulesPanel extends javax.swing.JPanel {

    private static final javax.swing.filechooser.FileFilter NBM_FILE_FILTER = new NbmFileFilter();

    /** The list model */
    private DefaultListModel modulesModel;

    /** Stores the last selected directory */
    static File defaultDir = null;

    private Wizard.Validator validator;

    static final long serialVersionUID = 8279789280479374665L;
    
    /** Creates new form SelectModulesPanel */
    public SelectModulesPanel(Wizard.Validator validator) {
        putClientProperty("WizardPanel_contentSelectedIndex", new Integer(1)); // NOI18N
        setName(getBundle("LAB_Select"));
        initComponents();
        
        this.validator = validator;

        getAccessibleContext().setAccessibleName(getBundle("LAB_Select"));
        getAccessibleContext().setAccessibleDescription(getBundle("LAB_21") + getBundle("LAB_22"));
        jTextArea.getAccessibleContext().setAccessibleDescription(getBundle("ACS_21"));
        addButton.getAccessibleContext().setAccessibleDescription(getBundle("ACS_Add"));
        removeButton.getAccessibleContext().setAccessibleDescription(getBundle("ACS_Remove"));
        jList.getAccessibleContext().setAccessibleDescription(getBundle("ACS_InstallList"));
        
        reset();
    }

    /** Overload getPreffered size to get a bit bigger dialog */
    public java.awt.Dimension getPreferredSize() {
        return new java.awt.Dimension( 350, super.getPreferredSize().height );
    }
    
    /** 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.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jTextArea = new javax.swing.JTextArea();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList = new javax.swing.JList();
        addButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        nextLabel = new javax.swing.JLabel();
        listLabel = new javax.swing.JLabel();

        setLayout(new java.awt.GridBagLayout());

        setNextFocusableComponent(addButton);
        jTextArea.setBackground(nextLabel.getBackground());
        jTextArea.setFont(new Font("Dialog", Font.PLAIN, jTextArea.getFont().getSize()));
        jTextArea.setLineWrap(true);
        jTextArea.setText(getBundle("LAB_21"));
        jTextArea.setWrapStyleWord(true);
        jTextArea.setDisabledTextColor(java.awt.Color.black);
        jTextArea.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
        add(jTextArea, gridBagConstraints);

        jList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListValueChanged(evt);
            }
        });

        jScrollPane1.setViewportView(jList);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jScrollPane1, gridBagConstraints);

        org.openide.awt.Mnemonics.setLocalizedText(addButton, getBundle("BTN_Add"));
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
        add(addButton, gridBagConstraints);

        org.openide.awt.Mnemonics.setLocalizedText(removeButton, getBundle("BTN_Remove"));
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
        add(removeButton, gridBagConstraints);

        nextLabel.setLabelFor(this);
        org.openide.awt.Mnemonics.setLocalizedText(nextLabel, getBundle("LAB_22"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
        add(nextLabel, gridBagConstraints);

        listLabel.setLabelFor(jList);
        org.openide.awt.Mnemonics.setLocalizedText(listLabel, getBundle("LAB_ModulesList"));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
        add(listLabel, gridBagConstraints);

    }
    // </editor-fold>//GEN-END:initComponents

    private void jListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListValueChanged
        buttonsCheck();
    }//GEN-LAST:event_jListValueChanged

    private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
        Object[] sel = jList.getSelectedValues();
        for (int i=0;i<sel.length;i++)
            modulesModel.removeElement(sel[i]);
        // to remove selection BUG #14750
        // workaround, bug reported to BugParade
        jList.setSelectionModel(new DefaultListSelectionModel());
        
        if ( modulesModel.getSize() == 0 )
            validator.setValid( false );        
        buttonsCheck();
    }//GEN-LAST:event_removeButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        List files = selectNbmFiles();
        
        if ( files != null ) {
            Iterator it = files.iterator();
            for ( int i = 0; it.hasNext(); i++ ) {
                if ( i == 0 )
                    validator.setValid( true );

                File fn = (File)it.next();
                if ( !selectedFile( fn ) ) {
                    modulesModel.addElement( fn );
                }
            }
        }

        buttonsCheck();
    }//GEN-LAST:event_addButtonActionPerformed
        
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JList jList;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea;
    private javax.swing.JLabel listLabel;
    private javax.swing.JLabel nextLabel;
    private javax.swing.JButton removeButton;
    // End of variables declaration//GEN-END:variables

    private boolean selectedFile( File file ) {
        for ( int i = 0; i < modulesModel.size(); i++ ) {
            if ( ((File)modulesModel.elementAt(i)).compareTo( file ) == 0 )
                return true;
        }

        return false;
    }
    
    File[] getFiles() {
        File[] files = new File[ modulesModel.size() ];

        for ( int i = 0; i < modulesModel.size(); i ++ ) {
            files[i] = (File)modulesModel.elementAt( i );
        }

        return files;
    }

    /** Clears all modules in listbox, ceates new model,
     * if the model does not exist yet
     */
    void reset() {
        if ( modulesModel == null ) {
            modulesModel = new DefaultListModel();
            jList.setModel( modulesModel );
        }
        else {
            modulesModel.removeAllElements();
        }
        buttonsCheck();
    }
    
    private void buttonsCheck() {
        if ( modulesModel.getSize() > 0 && jList.getSelectedIndex() != -1 )
            removeButton.setEnabled(true);
        else
            removeButton.setEnabled(false);
    }

    private static class NbmFileFilter extends javax.swing.filechooser.FileFilter {
        public boolean accept( File f ) {
            return f.isDirectory() || f.getName().toLowerCase().endsWith( ".nbm" ); // NOI18N
        }

        public String getDescription() {
            return getBundle( "CTL_FileFilterDescription" );
        }
    }
    
    static File getDefaultDir() {
        File defDir = new File( System.getProperty("user.home") );  // NOI18N
        try {
            if ( Utilities.isUnix() )
                return defDir;
            else if ( Utilities.isWindows() ) {
                do {
                    defDir = defDir.getParentFile();
                } while ( defDir != null && defDir.getParentFile() != null );
            }
        }
        catch (Exception ex) {
            defDir = null;
        }
        return defDir;
    }

    static List selectNbmFiles() {
        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
        chooser.addChoosableFileFilter( NBM_FILE_FILTER );
        chooser.setFileFilter(NBM_FILE_FILTER);
        chooser.setMultiSelectionEnabled( true );
        chooser.setFileHidingEnabled( false );
        chooser.setDialogTitle(getBundle("CTL_FileChooser_Title"));
        
        if (defaultDir == null)
            defaultDir = getDefaultDir();

        if ( defaultDir != null) {
            chooser.setCurrentDirectory( defaultDir );
        }

        List files = null;
        
        Window focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager ().getActiveWindow ();

        if (chooser.showDialog (KeyboardFocusManager.getCurrentKeyboardFocusManager ().getActiveWindow (), 
                               getBundle("CTL_FileChooser_Approve_Button"))
                != JFileChooser.APPROVE_OPTION)
            return null;

        defaultDir = chooser.getCurrentDirectory();
        
        // #46353, recover focus after close the JFileChooser
        if (focusOwner != null) {
            focusOwner.toFront ();
        }

        return Arrays.asList(chooser.getSelectedFiles());        
    }
    
    private static String getBundle( String key ) {
        return NbBundle.getMessage( SelectModulesPanel.class, key );
    }
}
