// Copyright 1996, Marimba Inc. All Rights Reserved.


// @(#)ButtonWidget.java, 1.29, 11/28/96





package marimba.gui;





import java.awt.*;


import marimba.persist.*;





/**


 * A button widget. This is the base class for all


 * button-like widgets.


 *


 * @author	Arthur van Hoff


 * @version 	1.29, 11/28/96


 */


public abstract class ButtonWidget extends Widget {


    public boolean  down;


    public boolean  value;


    public String  group;





    /**


     * The label that is displayed on the button.


     * @see #getText


     * @see #setText


     */


    public String  label = "";





    /**


     * Get the properties of this widget.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setBoolean("disabled", disabled, false);


	list.setBoolean("value", value, false);


	list.setString("group", group, null);


	list.setString("label", label, "");


    }





    /**


     * Set the properties of this widget.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	disabled = list.getBoolean("disabled", false);


	value = list.getBoolean("value", false);


	group = list.getString("group", null);


	label = list.getString("label", "");


    }





    /**


     * Get the group.


     */


    public String getGroup() {


	return group;


    }





    /**


     * Set the group.


     */


    public void setGroup(String group) {


	this.group = group;


    }





    /**


     * Get the next button in the same group that is not disabled.


     * @see #getPrevious


     * @see #getCurrent


     * @see #groupCount


     * @return	This button if no group has been specified or this is the last button in the group, otherwise the next button.


     */


    public ButtonWidget getNext() {


	ButtonWidget  result = this;


	if (group != null) {


	    // search for this button


	    int  index;


	    for (index = 0; index < parent.nwidgets; index++) {


		Widget w = parent.widgets[index];


		if (w == this) {


		    break;


		}


	    }


	    // search for next button


	    for (int i = index+1; i < parent.nwidgets; i++) {


		Widget w = parent.widgets[i];


		if (w instanceof ButtonWidget) {


		    ButtonWidget b = (ButtonWidget)w;


		    if (!b.disabled && group.equals(b.group)) {


			result = b;


			break;


		    }


		}


	    }


	}


	return result;


    }





    /**


     * Get the previous button in the same group that is not disabled.


     * @see #getNext


     * @see #getCurrent


     * @see #groupCount


     * @return	This button if no group has been specified or this is the first button in the group, otherwise the previous button.


     */


    public ButtonWidget getPrevious() {


	ButtonWidget  result = this;


	if (group != null) {


	    // search for this button


	    int  index;


	    for (index = 0; index < parent.nwidgets; index++) {


		Widget w = parent.widgets[index];


		if (w == this) {


		    break;


		}


	    }


	    // search for previous button


	    for (int i = index-1; i >= 0; i--) {


		Widget w = parent.widgets[i];


		if (w instanceof ButtonWidget) {


		    ButtonWidget b = (ButtonWidget)w;


		    if (!b.disabled && group.equals(b.group)) {


			result = b;


			break;


		    }


		}


	    }


	}


	return result;


    }





    /**


     * Get the current button with the value in the group.


     * @see #getNext


     * @see #getPrevious


     * @see #groupCount


     */


    public ButtonWidget getCurrent() {


	ButtonWidget  result = this;


	if (group != null) {


	    // search for this button


	    int  index;


	    for (index = 0; index < parent.nwidgets; index++) {


		Widget w = parent.widgets[index];


		if (w instanceof ButtonWidget) {


		    ButtonWidget b = (ButtonWidget)w;


		    if (group.equals(b.group) && b.value) {


			result = b;


			break;


		    }


		}


	    }


	}


	return result;


    }





    /**


     * Count the number of widgets in this group.


     * @see #getNext


     * @see #getPrevious


     * @see #getCurrent


     */


    public int groupCount() {


	int  result = 1;


	if (group != null) {


	    for (int index = 0; index < parent.nwidgets; index++) {


		Widget  w = parent.widgets[index];


		if (w != this && w instanceof ButtonWidget) {


		    ButtonWidget b = (ButtonWidget)w;


		    if (group.equals(b.group)) {


			result++;


		    }


		}


	    }


	}


	return result;


    }





    /**


     * Get the value as a boolean.


     */


    public boolean getBooleanValue() {


	return value;


    }





    /**


     * Get the value.


     */


    public Object getValue() {


	return new Boolean(getBooleanValue());


    }





    /**


     * Set the value.


     */


    public void setValue(Object value) {


	if (value instanceof Boolean) {


	    setValue(((Boolean)value).booleanValue());


	} else if (value instanceof String) {


	    setValue(value.equals("true"));


	} else if (value instanceof Number) {


	    setValue(((Number)value).intValue() != 0);


	} else {


	    setValue(value != null);


	}


    }





    /**


     * Set the value of the button.


     */


    public void setValue(boolean value) {


	if (this.value != value) {


	    if (value && (group != null)) {


		for (int i = parent.nwidgets ; i-- > 0 ;) {


		    Widget w = parent.widgets[i];


		    if (w instanceof ButtonWidget) {


			ButtonWidget b = (ButtonWidget)w;


			if (b.value && group.equals(b.group)) {


			    b.value = false;


			    b.repaint();


			}


		    }


		}


	    }


	    this.value = value;


	    repaint();


	}


    }





    /**


     * Get the label of the button.


     * @see #label


     * @see #getLabel


     */


    public String getText() {


	return label;


    }





    /**


     * Set the label of the button.


     * @see #label


     * @see #setLabel


     */


    public void setText(String label) {


	if ((label != null) && !this.label.equals(label)) {


	    this.label = label;


	    repaint();


	}


    }





    /**


     * Get the label.


     * @see #label


     */


    public String getLabel() {


	return getText();


    }





    /**


     * Set the label.


     * @see #label


     */


    public void setLabel(String label) {


	setText(label);


    }





    /**


     * Get the sticky-ness.


     */


    public boolean getSticky() {


	return true;


    }





    /**


     * Set the sticky-ness. This functions does nothing here, but is overridden in subclasses when necessary.


     */


    public void setSticky(boolean sticky) {


    }





    /**


     * Paint the button label.


     */


    public void paintLabel(Graphics g) {


    }





    /**


     * Paint the button itself.


     */


    public void paintButton(Graphics g) {


    }





    /**


     * Paint the button.


     */


    public void paint(Graphics g) {


	paintButton(g);


	paintLabel(g);


    }





    /**


     * Handle mouse events.


     */


    public boolean handleEvent(Event evt) {


	if (!disabled) {


	    switch (evt.id) {


	      case Event.MOUSE_DOWN:


	      case Event.MOUSE_DRAG:


		if (down != ((evt.x >= 0) && (evt.x < width) && (evt.y >= 0) && (evt.y < height))) {


		    down = !down;


		    requestFocus();


		    repaint();


		}


		return false;


		


	      case Event.MOUSE_UP:


		if (down) {


		    down = false;


		    if (getSticky() && ((group == null) || !value)) {


			setValue(!value);


		    }


		    repaint();


		    action();


		}


		return true;





	    case Event.KEY_ACTION:


		switch (evt.key) {


		    case Event.LEFT:


		    case Event.UP:


			getPrevious().requestFocus();


			return true;





		    case Event.RIGHT:


		    case Event.DOWN:


			getNext().requestFocus();


			return true;


		}


		break;





	      case Event.KEY_PRESS:


		switch (evt.key) {


		  case ' ':


		    down = true;


		    repaint();


		    return true;


		}


		break;





	      case Event.KEY_RELEASE:


		switch(evt.key) {


		  case ' ':


		    down = false;


		    if (getSticky() && ((group == null) || !value)) {


			setValue(!value);


		    }


		    repaint();


		    action();


		    return true;


		}


		break;


	    }


	}


	return super.handleEvent(evt);


    }





    /**


     * All buttons supports input focus.


     */


    public boolean focusInterest() {


	return !disabled;


    }





    /**


     * Debugging.


     */


    public void paramString(StringBuffer buf) {


	super.paramString(buf);


	buf.append(",label=");


	buf.append(label);


	buf.append(",value=");


	buf.append(value);


	if (group != null) {


	    buf.append(",group=");


	    buf.append(group);


	}


	if (getSticky()) {


	    buf.append(",sticky");


	}


    }


}


