package rangewidgets;

import org.gnu.gtk.Adjustment;
import org.gnu.gtk.Button;
import org.gnu.gtk.CheckButton;
import org.gnu.gtk.ComboBox;
import org.gnu.gtk.Gtk;
import org.gnu.gtk.HBox;
import org.gnu.gtk.HScale;
import org.gnu.gtk.HScrollBar;
import org.gnu.gtk.HSeparator;
import org.gnu.gtk.Label;
import org.gnu.gtk.MenuItem;
import org.gnu.gtk.PositionType;
import org.gnu.gtk.Scale;
import org.gnu.gtk.UpdateType;
import org.gnu.gtk.VBox;
import org.gnu.gtk.VScale;
import org.gnu.gtk.Window;
import org.gnu.gtk.WindowType;
import org.gnu.gtk.event.AdjustmentEvent;
import org.gnu.gtk.event.AdjustmentListener;
import org.gnu.gtk.event.ButtonEvent;
import org.gnu.gtk.event.ButtonListener;
import org.gnu.gtk.event.ComboBoxEvent;
import org.gnu.gtk.event.ComboBoxListener;
import org.gnu.gtk.event.LifeCycleEvent;
import org.gnu.gtk.event.LifeCycleListener;

public class RangeWidgets {

	private VScale vscale = null;
	private HScale hscale = null;
	private CheckButton button = null;
	private Adjustment adj = null;
	private ComboBox valuePosition = null;
	private ComboBox updatePolicy = null;

	public RangeWidgets() {

		Window window = new Window(WindowType.TOPLEVEL);
		window.addListener(new LifeCycleListener() {
			public void lifeCycleEvent(LifeCycleEvent event) {}
			public boolean lifeCycleQuery(LifeCycleEvent event) {
				if (event.isOfType(LifeCycleEvent.Type.DESTROY) || 
						event.isOfType(LifeCycleEvent.Type.DELETE)) {
						Gtk.mainQuit();
				}
				return false;
			}
		});
		window.setTitle("Range Controls");

		VBox box1 = new VBox(false, 0);
		window.add(box1);

		HBox box2 = new HBox(false, 10);
		box2.setBorderWidth(10);
		box1.packStart(box2, true, true, 0);

		// value,lower, upper, step_increment, page_increment, page_size
		// Note that the page_size value only makes a difference
		// for scrollbar widgets, and the highest value you'll
		// get is actually (upper - page_size).
		Adjustment adj1 = new Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0);

		vscale = new VScale(adj1);
		setDefaultValues(vscale);
		box2.packStart(vscale, true, true, 0);

		VBox box3 = new VBox(false, 10);
		box2.packStart(box3, true, true, 0);

		// Reuse the same adjustment
		hscale = new HScale(adj1);
		hscale.setMinimumSize(200, 30);
		setDefaultValues(hscale);
		box3.packStart(hscale, true, true, 0);

		// Reuse the same adjustment again
		HScrollBar scrollbar = new HScrollBar(adj1);
		// Notice how this causes the scales to always be
		// updated continuously when the scrollbar is moved.
		scrollbar.setUpdatePolicy(UpdateType.CONTINUOUS);
		box3.packStart(scrollbar, true, true, 0);

		box2 = new HBox(false, 10);
		box2.setBorderWidth(10);
		box1.packStart(box2, true, true, 0);

		// A checkbutton to control whether the value is 
		// displayed or not.
		button = new CheckButton("Display value on scale widgets", false);
		button.setState(true);
		button.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					drawValue();
				}
			}
		});
		box2.packStart(button, true, true, 0);

		box2 = new HBox(false, 10);
		box2.setBorderWidth(10);

		// An option menu to change the position of the value
		Label label = new Label("Scale Value Position:");
		box2.packStart(label, false, false, 0);

		valuePosition = new ComboBox();
		valuePosition.appendText("Top");
		valuePosition.appendText("Bottom");
		valuePosition.appendText("Left");
		valuePosition.appendText("Right");
		valuePosition.addListener(new ComboBoxListener() {
			public void comboBoxEvent(ComboBoxEvent event) {
				int index = valuePosition.getActive();
				if (0 == index)
					posMenuSelect(PositionType.TOP);
				else if (1 == index)
					posMenuSelect(PositionType.BOTTOM);
				else if (2 == index)
					posMenuSelect(PositionType.LEFT);
				else
					posMenuSelect(PositionType.RIGHT);
			}
		});
		box2.packStart(valuePosition, true, true, 0);

		box1.packStart(box2, true, true, 0);

		box2 = new HBox(false, 10);
		box2.setBorderWidth(10);

		// Yet another option menu, this time for the update
		// policy of the scale widgets.
		label = new Label("Scale Update Policy:");
		box2.packStart(label, false, false, 0);

		updatePolicy = new ComboBox();
		updatePolicy.appendText("Continuous");
		updatePolicy.appendText("Discontinuous");
		updatePolicy.appendText("Delayed");
		updatePolicy.addListener(new ComboBoxListener() {
			public void comboBoxEvent(ComboBoxEvent event) {
				int index = updatePolicy.getActive();
				if (0 == index)
					updateMenuSelect(UpdateType.CONTINUOUS);
				else if (1 == index)
					updateMenuSelect(UpdateType.DISCONTINUOUS);
				else 
					updateMenuSelect(UpdateType.DELAYED);
			}
		});
		box2.packStart(updatePolicy, true, true, 0);

		box1.packStart(box2, true, true, 0);

		box2 = new HBox(false, 10);
		box2.setBorderWidth(10);

		// An HScale widget for adjusting the number of digits
		// on the sample scales.
		label = new Label("Scale Digits:");
		box2.packStart(label, false, false, 0);

		adj = new Adjustment(1.0, 0.0, 5.0, 1.0, 1.0, 0.0);
		adj.addListener(new AdjustmentListener() {
			public void adjustmentEvent(AdjustmentEvent event) {
				digitsScale();
			}
		});
		HScale scale = new HScale(adj);
		scale.setDigits(0);
		box2.packStart(scale, true, true, 0);

		box1.packStart(box2, true, true, 0);

		box2 = new HBox(false, 10);
		box2.setBorderWidth(10);

		HSeparator separator = new HSeparator();
		box1.packStart(separator, false, true, 0);

		box3 = new VBox(false, 10);
		box3.setBorderWidth(10);
		box1.packStart(box3, false, true, 0);

		Button quit = new Button("Quit");
		quit.addListener(new ButtonListener() {
			public void buttonEvent(ButtonEvent event) {
				if (event.isOfType(ButtonEvent.Type.CLICK)) {
					Gtk.mainQuit();
				}
			}
		});
		box3.packStart(quit, true, true, 0);

		window.showAll();
	}

	public void setDefaultValues(Scale scale) {
		scale.setUpdatePolicy(UpdateType.CONTINUOUS);
		scale.setDigits(1);
		scale.setValuePosition(PositionType.TOP);
		scale.setDrawValue(true);
	}

	public MenuItem makeMenuItem(String name) {
		MenuItem item = new MenuItem(name, false);
		item.show();
		return item;
	}

	public void drawValue() {
		hscale.setDrawValue(button.getState());
		vscale.setDrawValue(button.getState());
	}

	public void posMenuSelect(PositionType positionType) {
		hscale.setValuePosition(positionType);
		vscale.setValuePosition(positionType);
	}

	public void updateMenuSelect(UpdateType updateType) {
		hscale.setUpdatePolicy(updateType);
		vscale.setUpdatePolicy(updateType);
	}

	public void digitsScale() {
		hscale.setDigits((int) adj.getValue());
		vscale.setDigits((int) adj.getValue());
	}

	public static void main(String[] args) {
		// Initialize GTK 
		Gtk.init(args);

		new RangeWidgets();

		Gtk.main();
	}
}
