/* Copyright 2000 by Basil Vandegriend.  All rights reserved. */

package com.basilv.core.richui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;

import com.basilv.core.IntegerValue;

/**
 * A type of spinner for WholeNumberField implemented with buttons.
 */
public class WholeNumberButtonSpinner
{
	private JButton plusButton = null;

	private JButton minusButton = null;

	private WholeNumberField field = null;

	private IntegerValue valueModel = null;

	/**
	 * Create the spinner buttons for the specified WholeNumberField.
	 */
	public WholeNumberButtonSpinner(WholeNumberField newField) {
		field = newField;
		valueModel = field.getValueModel();
		plusButton = createButton("+");
		minusButton = createButton("-");

		setEnablingOfButtons();

		// On change of current, min or max values, need to update
		// state of buttons.
		PropertyChangeListener listener = new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent event) {
				setEnablingOfButtons();
			}
		};
		valueModel.addPropertyChangeListener(IntegerValue.CURRENT_VALUE_PROPERTY, listener);
		valueModel.addPropertyChangeListener(IntegerValue.MAX_VALUE_PROPERTY, listener);
		valueModel.addPropertyChangeListener(IntegerValue.MIN_VALUE_PROPERTY, listener);

		plusButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				valueModel.setValueEnforcingMinAndMax(valueModel.getValue() + 1);
				field.requestFocus();
			}
		});

		minusButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				valueModel.setValueEnforcingMinAndMax(valueModel.getValue() - 1);
				field.requestFocus();
			}
		});
	}

	/**
	 * Create and return a panel with a horizontal box layout containing the
	 * spinner buttons followed by the whole number field. Additional components
	 * can be added to the right side of the panel.
	 */
	public JPanel createSpinnerPanel() {
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));

		panel.add(getPlusButton());
		panel.add(getMinusButton());
		panel.add(getWholeNumberField());

		return panel;
	}

	/**
	 * Return the plus button.
	 */
	public JButton getPlusButton() {
		return plusButton;
	}

	/**
	 * Return the minus button.
	 */
	public JButton getMinusButton() {
		return minusButton;
	}

	/**
	 * Return the field controlled by this spinner.
	 */
	private WholeNumberField getWholeNumberField() {
		return field;
	}

	/**
	 * Set the enabling of the plus and minus buttons.
	 */
	private void setEnablingOfButtons() {
		boolean enablePlus = !valueModel.isValueAtMax();
		boolean enableMinus = !valueModel.isValueAtMin();

		plusButton.setEnabled(enablePlus);
		minusButton.setEnabled(enableMinus);
	}

	private JButton createButton(String buttonText) {
		JButton button = new NoFocusButton(buttonText);
		button.setMargin(new java.awt.Insets(0, 2, 0, 2));
		return button;
	}

} // class WholeNumberButtonSpinner


/**
 * A specialization of the normal JButton that does not receive keyboard focus.
 */
class NoFocusButton extends JButton
{
	private static final long serialVersionUID = 1L;

	public NoFocusButton(String buttonText) {
		super(buttonText);
	}

	@Override
	public boolean isFocusable() {
		return false;
	}

} // class NoFocusButton
