/**
 * This is the fourth application used in the Java-GNOME tutorial.
 * It demonstrates the use of layout managers.
 */

import org.gnu.gnome.App;
import org.gnu.gnome.Program;
import org.gnu.gnome.UIInfo;
import org.gnu.gtk.AboutDialog;
import org.gnu.gtk.Adjustment;
import org.gnu.gtk.AttachOptions;
import org.gnu.gtk.ButtonsType;
import org.gnu.gtk.CheckButton;
import org.gnu.gtk.ComboBox;
import org.gnu.gtk.DialogFlags;
import org.gnu.gtk.Gtk;
import org.gnu.gtk.GtkStockItem;
import org.gnu.gtk.HBox;
import org.gnu.gtk.HScale;
import org.gnu.gtk.HScrollBar;
import org.gnu.gtk.Label;
import org.gnu.gtk.MessageDialog;
import org.gnu.gtk.MessageType;
import org.gnu.gtk.Notebook;
import org.gnu.gtk.PositionType;
import org.gnu.gtk.Scale;
import org.gnu.gtk.StatusBar;
import org.gnu.gtk.Table;
import org.gnu.gtk.UpdateType;
import org.gnu.gtk.VBox;
import org.gnu.gtk.VScale;
import org.gnu.gtk.Widget;
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;
import org.gnu.gtk.event.MenuItemEvent;
import org.gnu.gtk.event.MenuItemListener;

public class Fourth implements MenuItemListener, ButtonListener {
    private App app = null;

    private StatusBar statusbar = null;

    // widgets used for the boxes tab
    private VScale vscale = null;

    private HScale hscale = null;

    private CheckButton button = null;

    private Adjustment adj = null;

    private ComboBox valuePosition = null;

    private ComboBox updatePolicy = null;

    // widgets used for the table tab
    private VScale vscale2 = null;

    private HScale hscale2 = null;

    private CheckButton button2 = null;

    private Adjustment adj2 = null;

    private ComboBox valuePosition2 = null;

    private ComboBox updatePolicy2 = null;

    public static final String appVersion = "0.1";

    public Fourth() {
        createMainWindow();
        createMenusAndStatusbar();
        createToolbar();
        createView();
        app.showAll();
    }

    private void createMainWindow() {
        app = new App("Fourth", "Fourth App");
        app.addListener(new LifeCycleListener() {
            public void lifeCycleEvent(LifeCycleEvent event) {
            }

            public boolean lifeCycleQuery(LifeCycleEvent event) {
                Gtk.mainQuit();
                return false;
            }
        });
    }

    private void createMenusAndStatusbar() {

        UIInfo fileMenu[] = {
                UIInfo.newItem("New Window", "Open a new application window",
                        this), UIInfo.separator(),
                UIInfo.openItem((MenuItemListener) this),
                UIInfo.saveItem((MenuItemListener) this),
                UIInfo.saveAsItem((MenuItemListener) this), UIInfo.separator(),
                UIInfo.closeItem((MenuItemListener) this),
                UIInfo.quitItem(new MenuItemListener() {
                    public void menuItemEvent(MenuItemEvent event) {
                        fileExit();
                    }
                }), UIInfo.end() };

        UIInfo editMenu[] = { UIInfo.undoItem((MenuItemListener) this),
                UIInfo.redoItem((MenuItemListener) this), UIInfo.separator(),
                UIInfo.cutItem((MenuItemListener) this),
                UIInfo.copyItem((MenuItemListener) this),
                UIInfo.pasteItem((MenuItemListener) this), UIInfo.separator(),
                UIInfo.findItem((MenuItemListener) this),
                UIInfo.findAgainItem((MenuItemListener) this),
                UIInfo.replaceItem((MenuItemListener) this),
                UIInfo.propertiesItem((MenuItemListener) this), UIInfo.end() };

        UIInfo moveMenu[] = {
                UIInfo
                        .item("_Up", "Move selection up",
                                (MenuItemListener) this),
                UIInfo.item("D_own", "Move selection down",
                        (MenuItemListener) this), UIInfo.end() };

        UIInfo helpMenu[] = { UIInfo.help("second"),
                UIInfo.aboutItem(new MenuItemListener() {
                    public void menuItemEvent(MenuItemEvent event) {
                        helpAbout();
                    }
                }), UIInfo.end() };

        UIInfo mainMenu[] = { UIInfo.subtree("_File", fileMenu),
                UIInfo.subtree("_Edit", editMenu),
                UIInfo.subtree("_Move", moveMenu),
                UIInfo.subtree("_Help", helpMenu), UIInfo.end() };
        app.createMenus(mainMenu);

        statusbar = new StatusBar();
        app.setStatusBar(statusbar);
        app.installMenuHints(mainMenu);
    }

    private void createToolbar() {

        UIInfo toolbar[] = {
                UIInfo.itemStock("New", "Create a new file",
                        (ButtonListener) this, GtkStockItem.NEW),
                UIInfo.itemStock("Open", "Open a file", (ButtonListener) this,
                        GtkStockItem.OPEN),
                UIInfo.separator(),
                UIInfo.itemStock("Save", "Save this file",
                        (ButtonListener) this, GtkStockItem.SAVE),
                UIInfo.itemStock("Save As", "Save this file as",
                        (ButtonListener) this, GtkStockItem.SAVE_AS),
                UIInfo.separator(),
                UIInfo.itemStock("Close", "Close this file",
                        (ButtonListener) this, GtkStockItem.CLOSE),
                UIInfo.end() };

        app.createToolBar(toolbar);
    }

    private void createView() {
        // Create a notebook to hold our two example pages
        Notebook notebook = new Notebook();
        notebook.setTabPosition(PositionType.TOP);
        app.setContent(notebook);

        notebook.appendPage(buildBoxPage(), new Label("GtkBox"));
        notebook.appendPage(buildTablePage(), new Label("GtkTable"));
    }

    private Widget buildBoxPage() {

        VBox mainBox = new VBox(false, 0);

        HBox hbox = new HBox(false, 10);
        hbox.setBorderWidth(10);
        mainBox.packStart(hbox, true, true, 0);

        Adjustment adj1 = new Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
        vscale = new VScale(adj1);
        setDefaultValues(vscale);
        hbox.packStart(vscale, true, true, 0);

        VBox vbox = new VBox(false, 10);
        hbox.packStart(vbox, true, true, 0);

        hscale = new HScale(adj1);
        hscale.setMinimumSize(200, 30);
        setDefaultValues(hscale);
        vbox.packStart(hscale, true, true, 0);

        HScrollBar scrollbar = new HScrollBar(adj1);
        scrollbar.setUpdatePolicy(UpdateType.CONTINUOUS);
        vbox.packStart(scrollbar, true, true, 0);

        hbox = new HBox(false, 10);
        hbox.setBorderWidth(10);
        mainBox.packStart(hbox, true, true, 0);

        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();
            }
        });
        hbox.packStart(button, true, true, 0);

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

        Label label = new Label("Scale Value Position:");
        hbox.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);
            }
        });
        hbox.packStart(valuePosition, true, true, 0);

        mainBox.packStart(hbox, true, true, 0);

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

        label = new Label("Scale Update Policy:");
        hbox.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);
            }
        });
        hbox.packStart(updatePolicy, true, true, 0);

        mainBox.packStart(hbox, true, true, 0);

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

        label = new Label("Scale Digits:");
        hbox.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);
        hbox.packStart(scale, true, true, 0);

        mainBox.packStart(hbox, true, true, 0);

        return mainBox;
    }

    private Widget buildTablePage() {

        Table table = new Table(6, 3, false);

        Adjustment adj1 = new Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
        vscale2 = new VScale(adj1);
        setDefaultValues(vscale2);
        table.attach(vscale2, 0, 1, 0, 2, AttachOptions.FILL,
                AttachOptions.FILL, 2, 10);

        hscale2 = new HScale(adj1);
        hscale2.setMinimumSize(200, 30);
        setDefaultValues(hscale2);
        table.attach(hscale2, 1, 3, 0, 1, AttachOptions.FILL,
                AttachOptions.FILL, 5, 5);

        HScrollBar scrollbar = new HScrollBar(adj1);
        scrollbar.setUpdatePolicy(UpdateType.CONTINUOUS);
        table.attach(scrollbar, 1, 3, 1, 2, AttachOptions.FILL,
                AttachOptions.FILL, 5, 5);

        button2 = new CheckButton("Display value on scale widgets", false);
        button2.setState(true);
        table.attach(button2, 0, 3, 2, 3, AttachOptions.FILL,
                AttachOptions.FILL, 5, 10);

        Label label = new Label("Scale Value Position:");
        table.attach(label, 0, 2, 3, 4, AttachOptions.FILL, AttachOptions.FILL,
                2, 10);

        valuePosition2 = new ComboBox();
        valuePosition2.appendText("Top");
        valuePosition2.appendText("Bottom");
        valuePosition2.appendText("Left");
        valuePosition2.appendText("Right");
        valuePosition2.addListener(new ComboBoxListener() {
            public void comboBoxEvent(ComboBoxEvent event) {
                int index = valuePosition2.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);
            }
        });
        table.attach(valuePosition2, 2, 3, 3, 4, AttachOptions.FILL,
                AttachOptions.FILL, 2, 10);

        label = new Label("Scale Update Policy:");
        table.attach(label, 0, 2, 4, 5, AttachOptions.FILL, AttachOptions.FILL,
                2, 10);

        updatePolicy2 = new ComboBox();
        updatePolicy2.appendText("Continuous");
        updatePolicy2.appendText("Discontinuous");
        updatePolicy2.appendText("Delayed");
        updatePolicy2.addListener(new ComboBoxListener() {
            public void comboBoxEvent(ComboBoxEvent event) {
                int index = updatePolicy2.getActive();
                if (0 == index)
                    updateMenuSelect(UpdateType.CONTINUOUS);
                else if (1 == index)
                    updateMenuSelect(UpdateType.DISCONTINUOUS);
                else
                    updateMenuSelect(UpdateType.DELAYED);
            }
        });
        table.attach(updatePolicy2, 2, 3, 4, 5, AttachOptions.FILL,
                AttachOptions.FILL, 2, 10);

        label = new Label("Scale Digits:");
        table.attach(label, 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL,
                2, 5);

        adj2 = new Adjustment(1.0, 0.0, 5.0, 1.0, 1.0, 0.0);
        HScale scale = new HScale(adj2);
        scale.setDigits(0);
        table.attach(scale, 1, 3, 5, 6, AttachOptions.FILL, AttachOptions.FILL,
                3, 5);
        return table;
    }

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

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

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

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

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

    public void helpAbout() {
        String appname = "Java-GNOME Tutorial";
        String version = "0.1";
        String license = "GPL";
        String description = "Java-GNOME Tutorial.";
        String authors[] = { "http://java-gnome.sf.net", "http://www.gtk.org" };
        String documentors[] = { "<java-gnome-developer@lists.sf.net>",
                "http://www.gnome.org" };
        String translators = "Language Guys Inc.";
        String website = "http://java-gnome.sf.net";

        AboutDialog about = new AboutDialog();
        about.setName(appname);
        about.setVersion(version);
        about.setLicense(license);
        about.setComments(description);
        about.setAuthors(authors);
        about.setDocumenters(documentors);
        about.setTranslatorCredits(translators);
        about.setWebsite(website);
        about.show();
    }

    public void fileExit() {
        Gtk.mainQuit();
    }

    public void menuItemEvent(MenuItemEvent event) {
        displayMessage();
    }

    public void buttonEvent(ButtonEvent event) {
        displayMessage();
    }

    private void displayMessage() {
        MessageDialog dialog = new MessageDialog(app, DialogFlags.MODAL,
                MessageType.INFO, ButtonsType.OK, "Not implemented", false);
        dialog.run();
        dialog.destroy();
    }

    public static void main(String[] args) {
        Program.initGnomeUI("Fourth", Fourth.appVersion, args);
        new Fourth();
        Gtk.main();
    }
}
