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();
    }
}
