/** BEGIN COPYRIGHT BLOCK
 * Copyright (C) 2001 Sun Microsystems, Inc.  Used by permission.
 * Copyright (C) 2005 Red Hat, Inc.
 * All rights reserved.
 * 
 * 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; version 2
 * of the License.
 * 
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * END COPYRIGHT BLOCK **/
package com.netscape.management.admserv.config;

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.*;
import com.netscape.management.client.util.*;
import com.netscape.management.nmclf.SuiLookAndFeel;

/**
  *
  * @version 0.1 11/28/97
  * @author miodrag@netscape.com
  */

/**
 * Create a command button bar. The main purpose of this class is to privide consistent
 * look for buutons. By default, button bar has OK, Cancel and Help buttons. Inside
 * a dialog, Close button is also added. The button bar can have horizonal or vertical
 * orientation. A reference to a button can be obtained by it's command string. Action
 * Listener on the ButtonBar receives action events triggered by any of the buttons.
 * The particular button command string should be used to differenciate the buttons.
 */
public class ButtonBar extends JPanel {

    static ResourceSet _resource;
    static public String _i18nOKButton, _i18nCancelButton,
	_i18nCloseButton, _i18nHelpButton;
    static public String _i18nSaveButton, _i18nResetButton, 
	_i18nSaveToolTip, _i18nResetToolTip, _i18nHelpToolTip;
    
    static {
        _resource = new ResourceSet("com.netscape.management.admserv.config.config");
        _i18nOKButton = _resource.getString("common", "OKButton");
        _i18nCancelButton = _resource.getString("common", "CancelButton");
        _i18nCloseButton = _resource.getString("common", "CloseButton");
        _i18nSaveButton = _resource.getString("common", "SaveButton");
        _i18nResetButton = _resource.getString("common", "ResetButton");
        _i18nHelpButton = _resource.getString("common", "HelpButton");
	_i18nSaveToolTip = _resource.getString("common", "SaveToolTip");
	_i18nResetToolTip = _resource.getString("common", "ResetToolTip");
	_i18nHelpToolTip = _resource.getString("common", "HelpToolTip");
    }

    /**
      * Standard Command Buttons
     */
    public static final String cmdOK = "ok", cmdCancel = "cancel",
    cmdClose = "close", cmdHelp = "help";

    protected Vector _buttons = new Vector(5);

    // Standard panel commands buttons OK, Cancel, Help
    static private String[] stdCommands = { cmdOK, cmdCancel, null,
					    cmdHelp};
    static private String[] stdLabels = { _i18nSaveButton,
					  _i18nResetButton, null, _i18nHelpButton };

    static private String[] stdToolTips = { _i18nSaveToolTip, 
					    _i18nResetToolTip, null,  _i18nHelpToolTip};

    // Standard panel command buttons when running inside a dialog. All standard + Close button
    static private String[] stdDialogCommands = { cmdOK, cmdCancel,
						  null, cmdHelp};
    static private String[] stdDialogLabels = { _i18nOKButton,
						_i18nCancelButton, null, _i18nHelpButton };

    /**
     * No-Arg constructor, create default button bar, horizontal orientation
     */
    public ButtonBar() {
        this(stdCommands, stdLabels, true);
    }

    /**
      * Construct default button bar for dailog panel, horizontal orientation
      * @param isDialog A flag whether the panel that create ButtonBar runs inside a dialog
      */
    public ButtonBar(boolean isDialog) {
        this(isDialog ? stdDialogCommands : stdCommands,
	     isDialog ? stdDialogLabels : stdLabels, true);
    }

    /**
      * Construct default button bar for dailog panel, horizontal orientation
      * @param isDialog A flag whether the panel that create ButtonBar runs inside a dialog
      * @param toolTips Customized tool tips
      */
    public ButtonBar(boolean isDialog, String[] toolTips) {
        this(isDialog ? stdDialogCommands : stdCommands,
	     isDialog ? stdDialogLabels : stdLabels, toolTips, true);
    }

    /**
      * The generic button bar constrator. Enabels for constructon of custom button bars.
      * <i>null</i> as a command/label has a special meaning: Start a new button group. In
      * that case, a bigger spacing is aplied to the next button's left (horizontal bar) or
      * top (vertical bar) inset in accordance with the Kingpin L&F style guide
      * @param commands Array of command string for the buttons
      * @param labels Array of labels for the buttons
      * @param isHorizontal A flag whether the button bar has horzontal orientation
      * @exception IllegalArgumentException Length of <i>commands</i> and <i>lebels</i>
      *            arrays are not the same
      */
    public ButtonBar(String[] commands, String[] labels, boolean isHorizontal) {
	this(commands, labels, stdToolTips, isHorizontal);
    }

    /**
      * The generic button bar constrator. Enabels for constructon of custom button bars.
      * <i>null</i> as a command/label has a special meaning: Start a new button group. In
      * that case, a bigger spacing is aplied to the next button's left (horizontal bar) or
      * top (vertical bar) inset in accordance with the Kingpin L&F style guide
      * @param commands Array of command string for the buttons
      * @param labels Array of labels for the buttons
      * @param toolTips Array of tool tips for the buttons
      * @param isHorizontal A flag whether the button bar has horzontal orientation
      * @exception IllegalArgumentException Length of <i>commands</i> and <i>labels</i>
      *            arrays are not the same
      */
    public ButtonBar(String[] commands, String[] labels, String[] toolTips, boolean isHorizontal) {
	
        JButton button;
        JPanel p = new JPanel();
        GBC gbc = new GBC();

        if ((commands.length != labels.length) 
	    && (commands.length != toolTips.length)) {
            throw new IllegalArgumentException(
                    "In Constructor ButtonBar():  commands.length=" +
                    commands.length + ",labels.length=" + labels.length
		    + ",toolTips.length=" + toolTips.length);
        }

        setLayout(new GridBagLayout());
        p.setLayout (new GridBagLayout());

        int gridx = 0, gridy = 0, insetTop = 0, insetLeft = 0,
        insetBottom = 0, insetRight = 0;
        boolean newButtonGroup = false;

        JButton[] factoryButtons = JButtonFactory.create(labels);

        for (int i = 0; i < labels.length; i++) {

            if (labels[i] == null) {
                newButtonGroup = true;
                continue;
            }

            _buttons.addElement(button = factoryButtons[i]);
            button.setActionCommand(commands[i]);
	    JButtonFactory.initializeMnemonic(button);
	    button.setToolTipText(toolTips[i]);

            /*
             * Apply the proper button spacing. If start of a new button group
             * use SEPARATED_COMPONENT_SPACE
            */
            insetTop = insetLeft = insetBottom = insetRight = 0;
            if (isHorizontal) {
                if (i != 0) {
                    if (newButtonGroup) {
                        insetLeft =
                                SuiLookAndFeel.SEPARATED_COMPONENT_SPACE;
                    } else {
                        insetLeft = SuiLookAndFeel.COMPONENT_SPACE;
                    }
                }
            } else {
                if (i != 0) {
                    if (newButtonGroup) {
                        insetTop = SuiLookAndFeel.SEPARATED_COMPONENT_SPACE;
                    } else {
                        insetTop = SuiLookAndFeel.COMPONENT_SPACE;
                    }
                }
            }

            gbc.setInsets(insetTop, insetLeft, insetBottom, insetRight);
            gbc.setGrid(gridx, gridy, 1, 1);
            gbc.setSpace(1.0, 0.0, /*anchor=*/GBC.CENTER,
                    /*fill=*/GBC.NONE);
            p.add(button, gbc);

            if (isHorizontal) {
                gridx++;
            } else {
                gridy++;
            }
            newButtonGroup = false;
        }

        /**
          * Add the buttons to the panel right left conner
          */
        gbc.setInsets(0, 0, 0, 0);
        gbc.setGrid(0, 0, 1, 1);
        gbc.setSpace(1.0, 0.0, /*anchor=*/GBC.EAST, /*fill=*/GBC.NONE);
        add(p, gbc);
    }

    /**
      * Get a button with the command string <i>command</i>
      */
    public JButton getButton(String command) {
        for (int i = 0; i < _buttons.size(); i++) {
            JButton button = (JButton)_buttons.elementAt(i);
            if (button.getActionCommand().equals(command)) {
                return button;
            }
        }
        return null;
    }

    /**
      * Add listener too all buttons
     */
    public void addActionListener(ActionListener listener) {
        for (int i = 0; i < _buttons.size(); i++) {
            JButton button = (JButton)_buttons.elementAt(i);
            button.addActionListener(listener);
        }
    }

    /**
      * Remove action listener on all buttons
     */
    public void removeActionListener(ActionListener listener) {
        for (int i = 0; i < _buttons.size(); i++) {
            JButton button = (JButton)_buttons.elementAt(i);
            button.removeActionListener(listener);
        }
    }
}
