/*
 * Copyright (c) 2000, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.messaging.visualvm.ui;

import java.util.ArrayList;
import java.util.Collections;
import javax.swing.AbstractListModel;


@SuppressWarnings("serial")
public class ConfigureDisplayListDialog extends BasicDialog {

    MQResourceListModel attrsNotDisplayedListModel = null, attrsDisplayedListModel = null;
    String backupNotDisplayedList[] = null, backupDisplayedList[] = null;
	private String attrAlwaysDisplayed;
    

    /** Creates new form ConfigureListDialog */
    public ConfigureDisplayListDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);

        attrsNotDisplayedListModel = new MQResourceListModel(null);
        attrsDisplayedListModel = new MQResourceListModel(null);

        initComponents();
    }

    @Override
    public void setVisible(boolean b)  {
       if (b)  {
           // need to do this before we call setVisible() for some reason
           createBackup();
       }
       super.setVisible(b);
    }
    public void setNotDisplayedList(String s[]) {
        attrsNotDisplayedListModel.setList(s);
    }
    
    public void setDisplayedList(String s[])  {
        attrsDisplayedListModel.setList(s);
        
        for (int i = 0; i < s.length; ++i)  {
            attrsNotDisplayedListModel.remove(s[i]);
        }
    }
    
    /**
     * Designate an attribute that will always be displayed
     * @param primaryAttribute
     */
	public void setAlwaysDisplay(String attrAlwaysDisplayed) {
		this.attrAlwaysDisplayed = attrAlwaysDisplayed;
		
	}

    private void createBackup() {
        String strs[];
        
        strs = attrsNotDisplayedListModel.getList();
        if (strs.length > 0)  {
            backupNotDisplayedList = new String [ strs.length ];
            System.arraycopy(strs, 0, backupNotDisplayedList, 0, strs.length);
        }
        
        strs = attrsDisplayedListModel.getList();
        if (strs.length > 0)  {
            backupDisplayedList = new String [ strs.length ];
            System.arraycopy(strs, 0, backupDisplayedList, 0, strs.length);
        }
    }
    
    private void revertToBackup()  {

        if (backupNotDisplayedList != null) {
            setNotDisplayedList(backupNotDisplayedList);
            backupNotDisplayedList = null;
        }
        
        if (backupDisplayedList != null) {
            setDisplayedList(backupDisplayedList);
            backupDisplayedList = null;
        }
    }

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

        jScrollPane1 = new javax.swing.JScrollPane();
        attrsNotDisplayedList = new javax.swing.JList();
        jScrollPane2 = new javax.swing.JScrollPane();
        attrsDisplayedList = new javax.swing.JList();
        mainLabel = new javax.swing.JLabel();
        attrsNotDisplayedLabel = new javax.swing.JLabel();
        attrsDisplayedLabel = new javax.swing.JLabel();
        addtoDisplayButton = new javax.swing.JButton();
        addToNotDisplayButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();
        okButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        attrsNotDisplayedList.setModel(attrsNotDisplayedListModel);
        attrsNotDisplayedList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                attrsNotDisplayedListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(attrsNotDisplayedList);

        attrsDisplayedList.setModel(attrsDisplayedListModel);
        attrsDisplayedList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                attrsDisplayedListValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(attrsDisplayedList);

        mainLabel.setText("Select attributes to display or hide");

        attrsNotDisplayedLabel.setText("Attributes currently not displayed");

        attrsDisplayedLabel.setText("Attributes to display");

        addtoDisplayButton.setText("=>");
        addtoDisplayButton.setEnabled(false);
        addtoDisplayButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addtoDisplayButtonActionPerformed(evt);
            }
        });

        addToNotDisplayButton.setText("<=");
        addToNotDisplayButton.setEnabled(false);
        addToNotDisplayButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addToNotDisplayButtonActionPerformed(evt);
            }
        });

        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        okButton.setText("OK");
        okButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(attrsNotDisplayedLabel)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 187, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(okButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(addtoDisplayButton)
                    .addComponent(addToNotDisplayButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(attrsDisplayedLabel)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cancelButton))
                .addGap(33, 33, 33))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mainLabel)
                .addContainerGap(305, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mainLabel)
                .addGap(12, 12, 12)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(attrsDisplayedLabel)
                    .addComponent(attrsNotDisplayedLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE))
                .addGap(40, 40, 40)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(okButton)
                    .addComponent(cancelButton))
                .addGap(44, 44, 44))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(86, Short.MAX_VALUE)
                .addComponent(addtoDisplayButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 22, Short.MAX_VALUE)
                .addComponent(addToNotDisplayButton)
                .addGap(154, 154, 154))
        );

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

private void attrsNotDisplayedListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_attrsNotDisplayedListValueChanged
    if (attrsNotDisplayedList.isSelectionEmpty()) {
        addtoDisplayButton.setEnabled(false);
    } else {
        addtoDisplayButton.setEnabled(true);
        attrsDisplayedList.clearSelection();
    }
}//GEN-LAST:event_attrsNotDisplayedListValueChanged

private void attrsDisplayedListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_attrsDisplayedListValueChanged
    if (attrsDisplayedList.isSelectionEmpty()) {
        addToNotDisplayButton.setEnabled(false);
    } else {
        addToNotDisplayButton.setEnabled(true);
        attrsNotDisplayedList.clearSelection();
    }
}//GEN-LAST:event_attrsDisplayedListValueChanged

private void addtoDisplayButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addtoDisplayButtonActionPerformed

    Object[] selected = attrsNotDisplayedList.getSelectedValues();

    for (int i = 0; i < selected.length; ++i) {
        Object oneObj = selected[i];
        String oneAttr = (String) oneObj;
        attrsNotDisplayedListModel.remove(oneAttr);

        if (attrsNotDisplayedListModel.getSize() == 0) {
            addtoDisplayButton.setEnabled(false);
        }
        attrsDisplayedListModel.add(oneAttr);
    }

    attrsNotDisplayedList.clearSelection();

}//GEN-LAST:event_addtoDisplayButtonActionPerformed

private void addToNotDisplayButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addToNotDisplayButtonActionPerformed

    Object[] selected = attrsDisplayedList.getSelectedValues();

    for (int i = 0; i < selected.length; ++i) {
			Object oneObj = selected[i];
			String oneAttr = (String) oneObj;

			// ignore any attempt to remove the promary attribute from display
			if (!oneAttr.equals(attrAlwaysDisplayed)) {

				attrsDisplayedListModel.remove(oneAttr);

				if (attrsDisplayedListModel.getSize() == 0) {
					addToNotDisplayButton.setEnabled(false);
				}
				attrsNotDisplayedListModel.add(oneAttr);

			}
		}

    attrsDisplayedList.clearSelection();
}//GEN-LAST:event_addToNotDisplayButtonActionPerformed

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

private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
    setVisible(false);
    MQUIEvent e = new MQUIEvent(this, MQUIEvent.UPDATE_DATA_LIST);
    e.setAttrList(attrsDisplayedListModel.getList());
    fireMQUIEventDispatched(e);
}//GEN-LAST:event_okButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                ConfigureDisplayListDialog dialog = new ConfigureDisplayListDialog(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
					public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addToNotDisplayButton;
    private javax.swing.JButton addtoDisplayButton;
    private javax.swing.JLabel attrsDisplayedLabel;
    private javax.swing.JList attrsDisplayedList;
    private javax.swing.JLabel attrsNotDisplayedLabel;
    private javax.swing.JList attrsNotDisplayedList;
    private javax.swing.JButton cancelButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel mainLabel;
    private javax.swing.JButton okButton;
    // End of variables declaration//GEN-END:variables

}
class MQResourceListModel extends AbstractListModel {

    ArrayList<String> theStrings = new ArrayList<String>();

    public MQResourceListModel(String initList[]) {
        initStrings(initList);
    }

    public void setList(String list[]) {
        initStrings(list);
        fireContentsChanged(this, 0, getSize() + 1);
    }
    
    public String[] getList()  {
        String sArray[];
        
        if (getSize() == 0)  {
            return new String[0];
        }
        
        sArray = new String[ getSize()];
        theStrings.toArray(sArray);
        return (sArray);
    }

    public void add(String s) {
        theStrings.add(s);
        fireContentsChanged(this, 0, getSize() + 1);
    }

    public void remove(String s) {
        theStrings.remove(s);
        fireContentsChanged(this, 0, getSize());
    }

    public int getSize() {
        if (theStrings == null)  {
            return (0);
        }
        return (theStrings.size());
    }

    public Object getElementAt(int index) {
        return (theStrings.get(index));
    }

    private void initStrings(String sArray[]) {
        if (sArray != null) {
            theStrings.clear();
            for (int i = 0; i < sArray.length; ++i) {
                theStrings.add(sArray[i]);
            }
        }
    }
}
