/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.gui.panel;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import net.sf.jaxodraw.gui.JaxoDialogs;
import net.sf.jaxodraw.util.JaxoDictionary;


/** Brings up a dialog that allows the inclusion of custom Latex packages
 * in the Latex output.
 * @since 2.0
 */
public class JaxoLatexPackage implements ListSelectionListener {
    private final JaxoDictionary language = new JaxoDictionary(JaxoLatexPackage.class);

    private final List<String> listVector;
    private JList list;
    private final DefaultListModel listModel;
    private JButton removeButton;
    private JTextField packageName;
    private JDialog dialog;
    private boolean cancelled;

    /** Constructor: initializes the dialog with the current list of
     * included Latex packages (at least axodraw and color).
     * @param parent The parent component.
     * @param vector The list of currently included Latex packages
     */
    public JaxoLatexPackage(final Component parent, final List<String> vector) {
        this.listVector = vector;
        listModel = new DefaultListModel();

        for (int i = 0; i < listVector.size(); i++) {
            listModel.add(i, listVector.get(i));
        }

        initComponents(parent);
    }

    private void initComponents(final Component parent) {
        //Create the list and put it in a scroll pane
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setSelectedIndex(0);
        list.addListSelectionListener(this);

        final JScrollPane listScrollPane = new JScrollPane(list);

        final ActionListener addPackage =
            new ActionListener() {
                public final void actionPerformed(final ActionEvent e) {
                    if (!listModel.contains(packageName.getText())) {
                        listModel.addElement(packageName.getText());
                        list.setSelectedIndex(listModel.getSize() - 1);
                    }
                }
            };

        final JButton addButton = new JButton(language.value("/Add"));
        addButton.setEnabled(false);
        addButton.addActionListener(addPackage);

        removeButton = new JButton(language.value("/Remove"));
        removeButton.addActionListener(new ActionListener() {
                public final void actionPerformed(final ActionEvent e) {
                    removeButtonClicked();
                }
            });
        removeButton.setEnabled(false);

        final JButton okButton = new JButton(language.value("/OK"));

        //okButton.setToolTipText();
        okButton.addActionListener(new ActionListener() {
                public final void actionPerformed(final ActionEvent e) {
                    okButtonClicked();
                }
            });

        final JButton cancelButton = new JButton(language.value("/Cancel"));

        //okButton.setToolTipText();
        cancelButton.addActionListener(new ActionListener() {
                public final void actionPerformed(final ActionEvent e) {
                    cancelButtonClicked();
                }
            });

        packageName = new JTextField(10);
        packageName.getDocument().addDocumentListener(new DocumentListener() {
                public void insertUpdate(final DocumentEvent e) {
                    update();
                }

                public void removeUpdate(final DocumentEvent e) {
                    update();
                }

                public void changedUpdate(final DocumentEvent e) {
                    // nothing to do
                }

                private void update() {
                    addButton.setEnabled(packageName.getDocument().getLength() > 0);
                }
            });
        packageName.addActionListener(addPackage);

        //         String name =
        //             listModel.getElementAt(list.getSelectedIndex()).toString();
        //Create a panel that uses FlowLayout (the default).
        final JPanel buttonPane = new JPanel();
        buttonPane.add(packageName);
        buttonPane.add(addButton);
        buttonPane.add(removeButton);
        buttonPane.add(okButton);
        buttonPane.add(cancelButton);

        dialog =
            JaxoDialogs.newDialog(parent,
            JaxoDialogs.translatedWindowTitle(language.value("title")), true);
        dialog.getContentPane().add(listScrollPane, BorderLayout.CENTER);
        dialog.getContentPane().add(buttonPane, BorderLayout.PAGE_END);

        //dialog.setSize(new Dimension(400, 200));
        dialog.pack();
        dialog.setLocationRelativeTo(parent);

        cancelled = true;
        dialog.setVisible(true);
    }

    private void removeButtonClicked() {
        //This method can be called only if there's a valid selection.
        int index = list.getSelectedIndex();

        if ((index == 0) || (index == 1) || (index == 2)) {
            Toolkit.getDefaultToolkit().beep();

            return;
        }

        listModel.remove(index);

        final int size = listModel.getSize();

        if (size == 3) {
            removeButton.setEnabled(false);
        } else {
            if (index == size) { //removed item in last position
                index--;
            }

            list.setSelectedIndex(index); //otherwise select same index
        }
    }

    /** Executes the corresponding action when the list of Latex packages
     * has been changed.
     * @param e The ListSelectionEvent
     */
    public final void valueChanged(final ListSelectionEvent e) {
        if (!e.getValueIsAdjusting()) {
            final int index = list.getSelectedIndex();

            if (index == -1) {
                removeButton.setEnabled(false);
                packageName.setText("");
            } else if ((index == 0) || (index == 1) || (index == 2)) {
                removeButton.setEnabled(false);
                packageName.setText("");
            } else {
                removeButton.setEnabled(true);

                final String name = list.getSelectedValue().toString();
                packageName.setText(name);
            }
        }
    }

    /** Cheks if the dialog was closed via the cancel button.
     * @return True if the dialog was cancelled..
     */
    public final boolean wasCancelled() {
        return cancelled;
    }

    /** Returns the Vector holding the list of Latex packages.
     * @return The vector holding the list of Latex packages.
     */
    public final List<String> getPackageList() {
        return listVector;
    }

    private void okButtonClicked() {
        cancelled = false;
        listVector.clear();

        for (int i = 0; i < listModel.getSize(); i++) {
            listVector.add((String) listModel.getElementAt(i));
        }

        dialog.dispose();
    }

    private void cancelButtonClicked() {
        dialog.dispose();
    }
}
