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


// @(#)DropDownListBoxWidget.java, 1.40, 12/19/96





package marimba.gui;





import java.awt.*;


import java.util.*;





import marimba.persist.*;





/**


 * A multiple choice widget.


 *


 * @author	Klaas Waslander


 * @version 	1.40, 12/19/96


 */


public class DropDownListBoxWidget extends ChoiceWidget {


    /**


     * The possible options for the alignment.


     * @see #getAlignOptions


     * @see #align


     */


    public static Options alignOptions = new Options();


    static {


	alignOptions.add("left", LEFT);


	alignOptions.add("right", RIGHT);


    }





    /**


     * The possible options for the style.


     * @see #getStyleOptions


     * @see #style


     */


    public static Options styleOptions = new Options();


    static {


	styleOptions.add("plain", PLAIN);


	styleOptions.add("boxed", BOXED);


	styleOptions.add("filled", FILLED);


	styleOptions.add("underline", UNDERLINE);


    }





    /**


     * A dropdownlistbox can be plain, boxed, filled or underlined.


     * @see #getStyle


     * @see #setStyle


     * @see #styleOptions


     */


    public int  style = FILLED;





    /**


     * The arrow button can be displayed at the left or the right.


     * @see #getAlign


     * @see #setAlign


     * @see #alignOptions


     */


    public int  align = RIGHT;





    /**


     * The textbox used for this dropdownlistbox.


     * @see #newTextBox


     */


    public DropDownTextBoxWidget  text;





    /**


     * The maximum number of visible items, if there are more


     * items a scrollbar is used. If this number is zero or


     * smaller the max number of visible items is determined


     * by the size of the menu.


     * @see #getMaxVisible


     * @see #setMaxVisible


     */


    public int  maxVisible = 0;





    /**


     * If true, the dropdown button will be filled.


     * @see #getFillButton


     * @see #setFillButton


     */


    public boolean  fillButton;








    /**


     * Constructor.


     */


    public DropDownListBoxWidget() {


	add(text = newTextBox());


    }





    /**


     * Constructor.


     */


    public DropDownListBoxWidget(String value, int style, int align, String list) {


	setChoices(list);


	setValue(value);


	setStyle(style);


	setAlign(align);


	add(text = newTextBox());


    }





    /**


     * Get the properties of this widget.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setOption("align", alignOptions, align, RIGHT);


	list.setOption("style", styleOptions, style, FILLED);


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


	list.setInteger("maxVisible", maxVisible, 0);


    }





    /**


     * Set the properties of this widget.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	align = list.getOption("align", alignOptions, RIGHT);


	style = list.getOption("style", styleOptions, FILLED);


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


	maxVisible = list.getInteger("maxVisible", 0);


	add(text = newTextBox());


    }





    /**


     * Get the possible options for the alignment.


     * @see #alignOptions


     */


    public Options getAlignOptions() {


	return alignOptions;


    }





    /**


     * Get the possible options for the style.


     * @see #styleOptions


     */


    public Options getStyleOptions() {


	return styleOptions;


    }





    /**


     * Get align.


     * @see #align


     */


    public int getAlign() {


	return align;


    }





    /**


     * Set align.


     * @see #align


     */


    public void setAlign(int align) {


	if (this.align != align) {


	    this.align = align;


	    if (text != null) {


		text.setAlign(align);


	    }


	}


    }





    /**


     * Check whether the dropdown button is being filled.


     * @see #fillButton


     */


    public boolean getFillButton() {


	return fillButton;


    }





    /**


     * Fill the dropdown button or not.


     * @see #fillButton


     */


    public void setFillButton(boolean fillButton) {


	this.fillButton = fillButton;


	if (text != null) {


	    text.setFillButton(fillButton);


	}


    }





    /**


     * Get the maximum number of visible items.


     * @see #maxVisible


     */


    public int getMaxVisible() {


	return maxVisible;


    }





    /**


     * Set the maximum number of visible items.


     * @see #maxVisible


     */


    public void setMaxVisible(int maxVisible) {


	this.maxVisible = maxVisible;


    }





    /**


     * Get style.


     * @see #style


     */


    public int getStyle() {


	return style;


    }





    /**


     * Set style.


     * @see #style


     */


    public void setStyle(int style) {


	if (style==PLAIN || style==BOXED || style==FILLED || style==UNDERLINE) {


	    if (this.style != style) {


		this.style = style;


		if (text != null) {


		    text.setStyle(style);


		}


	    }


	}


    }





    /**


     * Set the current choice given the index.


     */


    public void setValue(int value) {


	super.setValue(value);


	if (text != null) {


	    text.setText((current < 0) ? null : choices[current]);


	}


    }





    /**


     * Returns a new textbox with the necessary properties set


     * to let it behave like the dropdownlist wants it to.


     * @see #text


     */


    protected DropDownTextBoxWidget newTextBox() {


	DropDownTextBoxWidget text = new DropDownTextBoxWidget();


	text.setAlign(align);


	text.setEditable(false);


	text.setStyle(style);


	text.setFillButton(fillButton);


	text.setText((current < 0) ? null : choices[current]);


	text.disable(disabled);


	return text;


    }





    /**


     * Disable the textbox too, if there is one.


     */


    public void disable(boolean disabled) {


	super.disable(disabled);


	if (text != null) {


	    text.disable(disabled);


	}


    }





    /**


     * Get rid of the menu (just in case).


     */


    public void stop() {


	clearPopups();


    }





    /**


     * Layout the container.


     */


    public void layout() {


	text.reshape(0, 0, width, height);


    }





    /**


     * Display and return a new dropdownmenu with the required settings


     * for letting it behave like the dropdownlistbox wants it to.


     */


    protected DropDownMenu newDropDown() {


	DropDownMenu  dropDown = new DropDownMenu(this, align == LEFT, maxVisible);


	dropDown.setBackground(hilite);


	dropDown.setItemFocus(true);


	dropDown.setOwner(text);


	return dropDown;


    }





    /**


     * Handle events.


     */


    public boolean handleEvent(Event evt) {


	switch (evt.id) {


	    case Event.MOUSE_DOWN:


		if (!disabled) {


		    boolean  onButton = ((Boolean)evt.arg).booleanValue();


		    if (onButton) {


			text.setDown(true);


		    }


		    newDropDown().requestFocus();


		}


		return false;





	    case Event.MOUSE_DRAG:


		return true;





	    case Event.MOUSE_UP:


		text.setDown(false);


		clearPopups();


		return true;





	    case Event.KEY_ACTION:


		switch (evt.key) {


		    case Event.DOWN:


			setValue(Math.min(getChoiceCount(), current+1));


			while (current < getChoiceCount() &&


				    ( getStringValue().startsWith("*") ||


				      getStringValue().startsWith("-") )) {


			    setValue(Math.min(getChoiceCount(), current+1));


			}


			action();


			return true;





		    case Event.UP:


			setValue(Math.max(0, current-1));


			while (current >= 0 &&


				    ( getStringValue().startsWith("*") ||


				      getStringValue().startsWith("-") )) {


			    setValue(Math.max(0, current-1));


			}


			action();


			return true;


		}


		break;





	    case Event.ACTION_EVENT:


		if (evt.target instanceof PopupMenuItemWidget) {


		    action();


		    return true;


		}


		break;	    


	}


	return super.handleEvent(evt);


    }


}


