/***********************************************************************

GECCO, a platform for command and control gaming

Copyright (C) 2001 Henrik Bäärnhielm, Andreas Enblom, Niklas
Hallenfur, Karl Hasselström, Henrik Hägerström, Oskar Linde, Jing Fu
Zi and Jon Åslund

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 2 of the License, or (at
your option) 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.

***********************************************************************/

package gecco.client.infopanels;
import gecco.client.*;
import java.awt.*;

import java.awt.List;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;

/**
 *  This panel contains the action information of a piece. The ongoing action of
 *  a piece and its queued actions are displayed. The queued actions are
 *  selectable. There are buttons that stop the ongoing action or the selected
 *  queued actions.
 *
 * @author     Jing Fu Zi
 * @author     Andreas Enblom
 * @created    June 27, 2001
 */
public class ActionDisplay extends JPanel implements ActionListener {
    /**
     *  Description of the Field
     */
    protected Game game;
    /**
     *  Description of the Field
     */
    protected Piece activePiece;

    /**
     *  Description of the Field
     */
    protected JList actionInfo;
    /**
     *  Description of the Field
     */
    protected JLabel executingAction;
    /**
     *  Description of the Field
     */
    protected JButton removeButton;
    /**
     *  Description of the Field
     */
    protected JButton abortButton;


    /**
     * @param  g  The game object that owns the pieces that comes into this
     *      panel, used for aborting actions.
     */
    public ActionDisplay(Game g) {
        // components
        game = g;
        actionInfo = new JList();
        actionInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
        actionInfo.addListSelectionListener(
            new ListSelectionListener() {
                /**
                 *  Description of the Method
                 *
                 * @param  e  Description of Parameter
                 */
                public void valueChanged(ListSelectionEvent e) {
                    // enable remove button exactly when something in
                    // the list is selected and there is a selected piece
                    // with queued actions
                    if ((activePiece != null) &&
                            (activePiece.getAllQueuedActions().size() > 0) &&
                            (actionInfo.getSelectedIndex() != -1)) {
                        removeButton.setEnabled(true);
                    } else {
                        removeButton.setEnabled(false);
                    }
                }
            });
        executingAction = new JLabel(" ");
        executingAction.setHorizontalAlignment(SwingConstants.CENTER);
        executingAction.setAlignmentX(Component.CENTER_ALIGNMENT);
        abortButton = new JButton("Stop");
        abortButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        abortButton.addActionListener(this);
        removeButton = new JButton("Stop selected actions");
        removeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
        removeButton.addActionListener(this);

        // layout
        JPanel execActionPanel = new JPanel();
        execActionPanel.setLayout(new BorderLayout());
        execActionPanel.add(executingAction, BorderLayout.CENTER);
        JPanel p1 = new JPanel();
        p1.add(Box.createHorizontalGlue());
        p1.add(abortButton);
        p1.add(Box.createHorizontalGlue());
        execActionPanel.add(p1, BorderLayout.SOUTH);
        execActionPanel.setBorder(
                BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(
                Color.gray),
                "Ongoing action",
                TitledBorder.CENTER,
                TitledBorder.TOP));

        int fill = 10;
        JScrollPane scrollPane = new JScrollPane(actionInfo);
        scrollPane.setAlignmentX(Component.CENTER_ALIGNMENT);

        JPanel mainArea = new JPanel();
        mainArea.setLayout(new BoxLayout(mainArea, BoxLayout.Y_AXIS));
        mainArea.add(execActionPanel);
        mainArea.add(Box.createVerticalStrut(fill));
        mainArea.add(scrollPane);
        mainArea.add(Box.createVerticalStrut(fill));
        JPanel p2 =
            new JPanel() {
                /**
                 *  Gets the PreferredSize attribute of the ActionDisplay object
                 *
                 * @return    The PreferredSize value
                 */
                public Dimension getPreferredSize() {
                    return this.getMinimumSize();
                }


                /**
                 *  Gets the MaximumSize attribute of the ActionDisplay object
                 *
                 * @return    The MaximumSize value
                 */
                public Dimension getMaximumSize() {
                    return this.getMinimumSize();
                }
            };
        p2.add(Box.createHorizontalGlue());
        p2.add(removeButton);
        p2.add(Box.createHorizontalGlue());
        mainArea.add(p2);
        mainArea.add(Box.createVerticalStrut(fill));

        this.setLayout(new BorderLayout());
        this.add(Box.createHorizontalStrut(10), BorderLayout.WEST);
        this.add(mainArea, BorderLayout.CENTER);
        this.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
        this.setBorder(
                BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(Color.black),
                "Actions",
                TitledBorder.CENTER,
                TitledBorder.TOP));
        setPiece(null);
    }


    /**
     *  Set the piece whosse actions is displayed in the panel.
     *
     * @param  p  The piece or NULL to empty the panel.
     */
    public void setPiece(Piece p) {
        activePiece = p;

        // put the queued actions in the list, only if the piece has changed
        // or its actions has changed
        Vector newActions = getListData(p);
        if ((p != activePiece) || (newActions.size()
                 != actionInfo.getModel().getSize())) {
            actionInfo.setListData(newActions);
        }

        // show the executing action
        if (p != null) {
            gecco.client.Action a = activePiece.getExecutingAction();
            if (a != null) {
                abortButton.setEnabled(true);
                executingAction.setText(a.toString());
            } else {
                abortButton.setEnabled(false);
                executingAction.setText(" ");
            }
        } else {
            abortButton.setEnabled(false);
            executingAction.setText(" ");
        }
    }


    /**
     *  Gets the MinimumSize attribute of the ActionDisplay object
     *
     * @return    The MinimumSize value
     */
    public Dimension getMinimumSize() {
        return new Dimension(230, 300);
    }


    /**
     *  Handles button clicks.
     *
     * @param  e  Description of Parameter
     */
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == removeButton) {
            removeSelectedActions();
        } else if (e.getSource() == abortButton) {
            abortCurrentAction();
        }
    }


    /**
     *  Returns the queued actions of the given piece in a way suitable for the
     *  JList used.
     *
     * @param  p  Description of Parameter
     * @return    The ListData value
     */
    Vector getListData(Piece p) {
        Vector data = null;
        if (p == null) {
            data = new Vector();
        } else {
            data = p.getAllQueuedActions();
        }
        // XXX This makes sure that the size of the list is preserved
        data.add(" ");
        return data;
    }


    /**
     *  Called when the remove selected button is clicked.
     */
    void removeSelectedActions() {
        if (activePiece == null) {
            return;
        }
        int[] actions = actionInfo.getSelectedIndices();
        Vector v = activePiece.getAllQueuedActions();
        for (int i = 0; i < actions.length; ++i) {
            if (i < v.size()) {
                gecco.client.Action a = (gecco.client.Action) v.elementAt(actions[i]);
                activePiece.abortQueuedAction(a);
            }
        }
        setPiece(activePiece);
    }


    /**
     *  Called when the stop current action button is clicked.
     */
    void abortCurrentAction() {
        game.abortExecutingAction(activePiece);
    }
}
