/*
Copyright (c) 2011 by Simon Schneegans

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.
*/

namespace GnomePie {

/////////////////////////////////////////////////////////////////////////
/// The settings menu of Gnome-Pie.
/////////////////////////////////////////////////////////////////////////

public class PreferencesWindow : GLib.Object {

    /////////////////////////////////////////////////////////////////////
    /// The ID of the currently selected Pie.
    /////////////////////////////////////////////////////////////////////

    private string selected_id = "";

    /////////////////////////////////////////////////////////////////////
    /// Some Gtk widgets used by this window.
    /////////////////////////////////////////////////////////////////////

    private Gtk.Window? window = null;
    private Gtk.Label? id_label = null;
    private Gtk.Label? name_label = null;
    private Gtk.Label? hotkey_label = null;
    private Gtk.Label? no_pie_label = null;
    private Gtk.Label? no_slice_label = null;
    private Gtk.Box? preview_box = null;
    private Gtk.Image? icon = null;
    private Gtk.EventBox? preview_background = null;
    private Gtk.Button? icon_button = null;
    private Gtk.Button? name_button = null;
    private Gtk.Button? hotkey_button = null;
    private Gtk.ToolButton? remove_pie_button = null;

    /////////////////////////////////////////////////////////////////////
    /// Some custom widgets and dialogs used by this window.
    /////////////////////////////////////////////////////////////////////

    private PiePreview? preview = null;
    private PieList? pie_list = null;
    private SettingsWindow? settings_window = null;
    private TriggerSelectWindow? trigger_window = null;
    private IconSelectWindow? icon_window = null;
    private RenameWindow? rename_window = null;

    /////////////////////////////////////////////////////////////////////
    /// C'tor, creates the window.
    /////////////////////////////////////////////////////////////////////

    public PreferencesWindow() {
        var builder = new Gtk.Builder.from_file(Paths.ui_files + "/preferences.ui");

        this.window = builder.get_object("window") as Gtk.Window;
        this.window.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK |
                    Gdk.EventMask.KEY_RELEASE_MASK |
                    Gdk.EventMask.KEY_PRESS_MASK |
                    Gdk.EventMask.POINTER_MOTION_MASK);

        var toolbar = builder.get_object ("toolbar") as Gtk.Widget;
        toolbar.get_style_context().add_class("primary-toolbar");

        var inline_toolbar = builder.get_object ("pies-toolbar") as Gtk.Widget;
        inline_toolbar.get_style_context().add_class("inline-toolbar");

        this.pie_list = new PieList();
        this.pie_list.on_select.connect(this.on_pie_select);

        var scroll_area = builder.get_object("pies-scrolledwindow") as Gtk.ScrolledWindow;
        scroll_area.add(this.pie_list);

        this.preview = new PiePreview();
        this.preview.on_first_slice_added.connect(() => {
            this.no_slice_label.hide();
        });

        this.preview.on_last_slice_removed.connect(() => {
            this.no_slice_label.show();
        });

        preview_box = builder.get_object("preview-box") as Gtk.Box;
        this.preview_box.pack_start(preview, true, true);
        this.id_label = builder.get_object("id-label") as Gtk.Label;
        this.name_label = builder.get_object("pie-name-label") as Gtk.Label;
        this.hotkey_label = builder.get_object("hotkey-label") as Gtk.Label;
        this.no_pie_label = builder.get_object("no-pie-label") as Gtk.Label;
        this.no_slice_label = builder.get_object("no-slice-label") as Gtk.Label;
        this.icon = builder.get_object("icon") as Gtk.Image;
        this.preview_background = builder.get_object("preview-background") as Gtk.EventBox;

        (builder.get_object("settings-button") as Gtk.ToolButton).clicked.connect(on_settings_button_clicked);

        this.hotkey_button = builder.get_object("key-button") as Gtk.Button;
        this.hotkey_button.clicked.connect(on_key_button_clicked);

        this.icon_button = builder.get_object("icon-button") as Gtk.Button;
        this.icon_button.clicked.connect(on_icon_button_clicked);

        this.name_button = builder.get_object("rename-button") as Gtk.Button;
        this.name_button.clicked.connect(on_rename_button_clicked);

        this.remove_pie_button = builder.get_object("remove-pie-button") as Gtk.ToolButton;
        this.remove_pie_button.clicked.connect(on_remove_pie_button_clicked);

        (builder.get_object("add-pie-button") as Gtk.ToolButton).clicked.connect(on_add_pie_button_clicked);

        this.window.hide.connect(() => {
            // save settings on close
            Config.global.save();
            Pies.save();

            Timeout.add(100, () => {
                IconSelectWindow.clear_icons();
                return false;
            });
        });

        this.window.delete_event.connect(this.window.hide_on_delete);
    }

    /////////////////////////////////////////////////////////////////////
    /// Shows the window.
    /////////////////////////////////////////////////////////////////////

    public void show() {
        this.preview.draw_loop();
        this.window.show_all();
        this.pie_list.select_first();

        var style = this.preview_background.get_style_context();
        this.preview_background.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL));
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when a new Pie is selected in the PieList.
    /////////////////////////////////////////////////////////////////////

    private void on_pie_select(string id) {
        selected_id = id;

        this.no_slice_label.hide();
        this.no_pie_label.hide();
        this.preview_box.hide();

        this.name_button.sensitive = false;
        this.hotkey_button.sensitive = false;
        this.icon_button.sensitive = false;
        this.remove_pie_button.sensitive = false;

        if (id == "") {
            this.id_label.label = "";
            this.name_label.label = _("No Pie selected.");
            this.hotkey_label.set_markup("");
            this.icon.icon_name = "stock_unknown";

            this.no_pie_label.show();
        } else {
            var pie = PieManager.all_pies[selected_id];
            this.id_label.label = ("ID: %s").printf(pie.id);
            this.name_label.label = PieManager.get_name_of(pie.id);
            this.hotkey_label.set_markup(PieManager.get_accelerator_label_of(pie.id));

            if (pie.icon.contains("/"))
                try {
                    this.icon.pixbuf = new Gdk.Pixbuf.from_file_at_scale(pie.icon,
                                            this.icon.get_pixel_size(), this.icon.get_pixel_size(), true);
                } catch (GLib.Error error) {
                    warning(error.message);
                }
            else
                this.icon.icon_name = pie.icon;

            this.preview.set_pie(id);
            this.preview_box.show();

            if (pie.action_groups.size == 0) {
                this.no_slice_label.show();
            }

            this.name_button.sensitive = true;
            this.hotkey_button.sensitive = true;
            this.icon_button.sensitive = true;
            this.remove_pie_button.sensitive = true;
        }
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when the add Pie button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_add_pie_button_clicked(Gtk.ToolButton button) {
        var new_pie = PieManager.create_persistent_pie(_("New Pie"), "stock_unknown", null);
        this.pie_list.reload_all();
        this.pie_list.select(new_pie.id);
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when the remove Pie button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_remove_pie_button_clicked(Gtk.ToolButton button) {
        if (this.selected_id != "") {
            var dialog = new Gtk.MessageDialog((Gtk.Window)this.window.get_toplevel(), Gtk.DialogFlags.MODAL,
                         Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,
                         _("Do you really want to delete the selected Pie with all contained Slices?"));

            dialog.response.connect((response) => {
                if (response == Gtk.ResponseType.YES) {
                    PieManager.remove_pie(selected_id);
                    this.pie_list.reload_all();
                    this.pie_list.select_first();
                }
            });

            dialog.run();
            dialog.destroy();
        }
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when rename Pie button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_rename_button_clicked(Gtk.Button button) {
        if (this.rename_window == null) {
            this.rename_window = new RenameWindow();
            this.rename_window.set_parent(window);
            this.rename_window.on_ok.connect((name) => {
                var pie = PieManager.all_pies[selected_id];
                pie.name = name;
                PieManager.create_launcher(pie.id);
                this.name_label.label = name;
                this.pie_list.reload_all();
            });
        }

        this.rename_window.set_pie(selected_id);
        this.rename_window.show();
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when the hotkey button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_key_button_clicked(Gtk.Button button) {
        if (this.trigger_window == null) {
            this.trigger_window = new TriggerSelectWindow();
            this.trigger_window.set_parent(window);
            this.trigger_window.on_ok.connect((trigger) => {
                PieManager.bind_trigger(trigger, selected_id);
                this.hotkey_label.set_markup(trigger.label_with_specials);
            });
        }

        this.trigger_window.set_pie(selected_id);
        this.trigger_window.show();
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when the general settings button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_settings_button_clicked(Gtk.ToolButton button) {
        if (this.settings_window == null) {
            this.settings_window = new SettingsWindow();
            this.settings_window.set_parent(this.window.get_toplevel() as Gtk.Window);
        }

        this.settings_window.show();
    }

    /////////////////////////////////////////////////////////////////////
    /// Called when the icon button is clicked.
    /////////////////////////////////////////////////////////////////////

    private void on_icon_button_clicked(Gtk.Button button) {
        if (this.icon_window == null) {
            this.icon_window = new IconSelectWindow(this.window);
            this.icon_window.on_ok.connect((icon) => {
                var pie = PieManager.all_pies[selected_id];
                pie.icon = icon;
                PieManager.create_launcher(pie.id);
                this.pie_list.reload_all();
            });
        }

        this.icon_window.show();
        this.icon_window.set_icon(PieManager.all_pies[selected_id].icon);
    }
}

}