/*
 * transmission-remote-gtk - A GTK RPC client to Transmission
 * Copyright (C) 2011-2013  Alan Fitton

 * 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 2 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "config.h"

#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkkeysyms-compat.h>

#include "trg-prefs.h"
#include "trg-torrent-graph.h"
#include "trg-tree-view.h"
#include "trg-torrent-tree-view.h"
#include "trg-main-window.h"
#include "trg-menu-bar.h"

enum {
    PROP_0,
    PROP_CONNECT_BUTTON,
    PROP_DISCONNECT_BUTTON,
    PROP_ADD_BUTTON,
    PROP_ADD_URL_BUTTON,
    PROP_REMOVE_BUTTON,
    PROP_DELETE_BUTTON,
    PROP_RESUME_BUTTON,
    PROP_RESUME_ALL_BUTTON,
    PROP_PAUSE_BUTTON,
    PROP_PAUSE_ALL_BUTTON,
    PROP_VERIFY_BUTTON,
    PROP_REANNOUNCE_BUTTON,
    PROP_PROPS_BUTTON,
    PROP_COPYMAGNET_BUTTON,
    PROP_MOVE_BUTTON,
    PROP_REMOTE_PREFS_BUTTON,
    PROP_LOCAL_PREFS_BUTTON,
    PROP_ABOUT_BUTTON,
    PROP_VIEW_STATS_BUTTON,
#if HAVE_RSS
    PROP_VIEW_RSS_BUTTON,
#endif
    PROP_VIEW_STATES_BUTTON,
    PROP_VIEW_NOTEBOOK_BUTTON,
    PROP_QUIT,
    PROP_PREFS,
    PROP_MAIN_WINDOW,
    PROP_TORRENT_TREE_VIEW,
    PROP_ACCEL_GROUP,
    PROP_DIR_FILTERS,
    PROP_TRACKER_FILTERS,
    PROP_DIRECTORIES_FIRST,
#if TRG_WITH_GRAPH
    PROP_VIEW_SHOW_GRAPH,
#endif
    PROP_MOVE_DOWN_QUEUE,
    PROP_MOVE_UP_QUEUE,
    PROP_MOVE_BOTTOM_QUEUE,
    PROP_MOVE_TOP_QUEUE,
    PROP_START_NOW
};

#define G_DATAKEY_CONF_KEY "conf-key"
#define G_DATAKEY_PREF_VALUE "pref-index"

G_DEFINE_TYPE(TrgMenuBar, trg_menu_bar, GTK_TYPE_MENU_BAR)
#define TRG_MENU_BAR_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_MENU_BAR, TrgMenuBarPrivate))
typedef struct _TrgMenuBarPrivate TrgMenuBarPrivate;

struct _TrgMenuBarPrivate {
    GtkWidget *mb_connect;
    GtkWidget *mb_disconnect;
    GtkWidget *mb_add;
    GtkWidget *mb_add_url;
    GtkWidget *mb_move;
    GtkWidget *mb_remove;
    GtkWidget *mb_delete;
    GtkWidget *mb_resume;
    GtkWidget *mb_pause;
    GtkWidget *mb_resume_all;
    GtkWidget *mb_pause_all;
    GtkWidget *mb_verify;
    GtkWidget *mb_reannounce;
    GtkWidget *mb_props;
    GtkWidget *mb_copy_magnetlink;
    GtkWidget *mb_local_prefs;
    GtkWidget *mb_remote_prefs;
    GtkWidget *mb_view_states;
    GtkWidget *mb_view_notebook;
    GtkWidget *mb_view_stats;
#if HAVE_RSS
    GtkWidget *mb_view_rss;
#endif
    GtkWidget *mb_about;
    GtkWidget *mb_quit;
    GtkWidget *mb_directory_filters;
    GtkWidget *mb_tracker_filters;
    GtkWidget *mb_directory_first;
#if TRG_WITH_GRAPH
    GtkWidget *mb_view_graph;
#endif
    GtkWidget *mb_down_queue;
    GtkWidget *mb_up_queue;
    GtkWidget *mb_bottom_queue;
    GtkWidget *mb_top_queue;
    GtkWidget *mb_start_now;
    GtkWidget *mb_queues_seperator;
    GtkWidget *mb_view_classic;
    GtkWidget *mb_view_transmission;
    GtkWidget *mb_view_transmission_compact;
    GtkAccelGroup *accel_group;
    TrgPrefs *prefs;
    TrgMainWindow *main_window;
    TrgTorrentTreeView *torrent_tree_view;
};

void trg_menu_bar_set_supports_queues(TrgMenuBar * mb,
                                      gboolean supportsQueues)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(mb);

    gtk_widget_set_visible(priv->mb_down_queue, supportsQueues);
    gtk_widget_set_visible(priv->mb_up_queue, supportsQueues);
    gtk_widget_set_visible(priv->mb_top_queue, supportsQueues);
    gtk_widget_set_visible(priv->mb_bottom_queue, supportsQueues);
    gtk_widget_set_visible(priv->mb_queues_seperator, supportsQueues);
    gtk_widget_set_visible(priv->mb_start_now, supportsQueues);
}

void trg_menu_bar_connected_change(TrgMenuBar * mb, gboolean connected)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(mb);

    gtk_widget_set_sensitive(priv->mb_add, connected);
    gtk_widget_set_sensitive(priv->mb_add_url, connected);
    gtk_widget_set_sensitive(priv->mb_disconnect, connected);
    gtk_widget_set_sensitive(priv->mb_remote_prefs, connected);
    gtk_widget_set_sensitive(priv->mb_view_stats, connected);
#if HAVE_RSS
    gtk_widget_set_sensitive(priv->mb_view_rss, connected);
#endif
    gtk_widget_set_sensitive(priv->mb_resume_all, connected);
    gtk_widget_set_sensitive(priv->mb_pause_all, connected);
}

void
trg_menu_bar_torrent_actions_sensitive(TrgMenuBar * mb, gboolean sensitive)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(mb);

    gtk_widget_set_sensitive(priv->mb_props, sensitive);
    gtk_widget_set_sensitive(priv->mb_copy_magnetlink, sensitive);
    gtk_widget_set_sensitive(priv->mb_remove, sensitive);
    gtk_widget_set_sensitive(priv->mb_delete, sensitive);
    gtk_widget_set_sensitive(priv->mb_resume, sensitive);
    gtk_widget_set_sensitive(priv->mb_pause, sensitive);
    gtk_widget_set_sensitive(priv->mb_verify, sensitive);
    gtk_widget_set_sensitive(priv->mb_reannounce, sensitive);
    gtk_widget_set_sensitive(priv->mb_move, sensitive);
    gtk_widget_set_sensitive(priv->mb_start_now, sensitive);
    gtk_widget_set_sensitive(priv->mb_up_queue, sensitive);
    gtk_widget_set_sensitive(priv->mb_down_queue, sensitive);
    gtk_widget_set_sensitive(priv->mb_top_queue, sensitive);
    gtk_widget_set_sensitive(priv->mb_bottom_queue, sensitive);
}

static void
trg_menu_bar_set_property(GObject * object,
                          guint prop_id, const GValue * value,
                          GParamSpec * pspec G_GNUC_UNUSED)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(object);

    switch (prop_id) {
    case PROP_ACCEL_GROUP:
        priv->accel_group = g_value_get_object(value);
        break;
    case PROP_PREFS:
        priv->prefs = g_value_get_object(value);
        break;
    case PROP_MAIN_WINDOW:
        priv->main_window = g_value_get_object(value);
        break;
    case PROP_TORRENT_TREE_VIEW:
        priv->torrent_tree_view = g_value_get_object(value);
        break;
    }
}

static void
trg_menu_bar_get_property(GObject * object, guint property_id,
                          GValue * value, GParamSpec * pspec)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(object);
    switch (property_id) {
    case PROP_CONNECT_BUTTON:
        g_value_set_object(value, priv->mb_connect);
        break;
    case PROP_DISCONNECT_BUTTON:
        g_value_set_object(value, priv->mb_disconnect);
        break;
    case PROP_ADD_BUTTON:
        g_value_set_object(value, priv->mb_add);
        break;
    case PROP_ADD_URL_BUTTON:
        g_value_set_object(value, priv->mb_add_url);
        break;
    case PROP_REMOVE_BUTTON:
        g_value_set_object(value, priv->mb_remove);
        break;
    case PROP_DELETE_BUTTON:
        g_value_set_object(value, priv->mb_delete);
        break;
    case PROP_MOVE_UP_QUEUE:
        g_value_set_object(value, priv->mb_up_queue);
        break;
    case PROP_MOVE_DOWN_QUEUE:
        g_value_set_object(value, priv->mb_down_queue);
        break;
    case PROP_MOVE_TOP_QUEUE:
        g_value_set_object(value, priv->mb_top_queue);
        break;
    case PROP_MOVE_BOTTOM_QUEUE:
        g_value_set_object(value, priv->mb_bottom_queue);
        break;
    case PROP_START_NOW:
        g_value_set_object(value, priv->mb_start_now);
        break;
    case PROP_MOVE_BUTTON:
        g_value_set_object(value, priv->mb_move);
        break;
    case PROP_RESUME_BUTTON:
        g_value_set_object(value, priv->mb_resume);
        break;
    case PROP_RESUME_ALL_BUTTON:
        g_value_set_object(value, priv->mb_resume_all);
        break;
    case PROP_PAUSE_BUTTON:
        g_value_set_object(value, priv->mb_pause);
        break;
    case PROP_PAUSE_ALL_BUTTON:
        g_value_set_object(value, priv->mb_pause_all);
        break;
    case PROP_VERIFY_BUTTON:
        g_value_set_object(value, priv->mb_verify);
        break;
    case PROP_REANNOUNCE_BUTTON:
        g_value_set_object(value, priv->mb_reannounce);
        break;
    case PROP_PROPS_BUTTON:
        g_value_set_object(value, priv->mb_props);
        break;
    case PROP_COPYMAGNET_BUTTON:
        g_value_set_object(value, priv->mb_copy_magnetlink);
        break;
    case PROP_REMOTE_PREFS_BUTTON:
        g_value_set_object(value, priv->mb_remote_prefs);
        break;
    case PROP_LOCAL_PREFS_BUTTON:
        g_value_set_object(value, priv->mb_local_prefs);
        break;
    case PROP_ABOUT_BUTTON:
        g_value_set_object(value, priv->mb_about);
        break;
#if TRG_WITH_GRAPH
    case PROP_VIEW_SHOW_GRAPH:
        g_value_set_object(value, priv->mb_view_graph);
        break;
#endif
    case PROP_VIEW_STATES_BUTTON:
        g_value_set_object(value, priv->mb_view_states);
        break;
    case PROP_VIEW_NOTEBOOK_BUTTON:
        g_value_set_object(value, priv->mb_view_notebook);
        break;
    case PROP_VIEW_STATS_BUTTON:
        g_value_set_object(value, priv->mb_view_stats);
        break;
#if HAVE_RSS
    case PROP_VIEW_RSS_BUTTON:
        g_value_set_object(value, priv->mb_view_rss);
        break;
#endif
    case PROP_QUIT:
        g_value_set_object(value, priv->mb_quit);
        break;
    case PROP_DIR_FILTERS:
        g_value_set_object(value, priv->mb_directory_filters);
        break;
    case PROP_TRACKER_FILTERS:
        g_value_set_object(value, priv->mb_tracker_filters);
        break;
	case PROP_DIRECTORIES_FIRST:
		g_value_set_object(value, priv->mb_directory_first);
		break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
        break;
    }
}

static void
trg_menu_bar_install_widget_prop(GObjectClass * class, guint propId,
                                 const gchar * name, const gchar * nick)
{
    g_object_class_install_property(class,
                                    propId,
                                    g_param_spec_object(name,
                                                        nick,
                                                        nick,
                                                        GTK_TYPE_WIDGET,
                                                        G_PARAM_READABLE
                                                        |
                                                        G_PARAM_STATIC_NAME
                                                        |
                                                        G_PARAM_STATIC_NICK
                                                        |
                                                        G_PARAM_STATIC_BLURB));
}

GtkWidget *trg_menu_bar_item_new(GtkMenuShell * shell, const gchar * text,
                                 gboolean sensitive)
{
    GtkWidget *item = gtk_menu_item_new_with_label(text);
    gtk_menu_item_set_use_underline(GTK_MENU_ITEM(item), TRUE);
    gtk_widget_set_sensitive(item, sensitive);
    gtk_menu_shell_append(shell, item);

    return item;
}

static void
trg_menu_bar_accel_add(TrgMenuBar * menu, GtkWidget * item,
                       guint key, GdkModifierType mods)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(menu);

    gtk_widget_add_accelerator(item, "activate", priv->accel_group,
                               key, mods, GTK_ACCEL_VISIBLE);

}

static void view_menu_radio_item_toggled_cb(GtkCheckMenuItem * w,
                                            gpointer data)
{
    TrgPrefs *p = TRG_PREFS(data);
    const gchar *key =
        (gchar *) g_object_get_data(G_OBJECT(w), G_DATAKEY_CONF_KEY);

    if (gtk_check_menu_item_get_active(w)) {
        gint index =
            GPOINTER_TO_INT(g_object_get_data
                            (G_OBJECT(w), G_DATAKEY_PREF_VALUE));
        trg_prefs_set_int(p, key, index, TRG_PREFS_GLOBAL);
    }
}

static void view_menu_item_toggled_cb(GtkCheckMenuItem * w, gpointer data)
{
    TrgPrefs *p = TRG_PREFS(data);
    const gchar *key =
        (gchar *) g_object_get_data(G_OBJECT(w), G_DATAKEY_CONF_KEY);
    trg_prefs_set_bool(p, key, gtk_check_menu_item_get_active(w),
                       TRG_PREFS_GLOBAL);
}

static void
view_menu_bar_toggled_dependency_cb(GtkCheckMenuItem * w, gpointer data)
{
    gtk_widget_set_sensitive(GTK_WIDGET(data),
                             gtk_check_menu_item_get_active
                             (GTK_CHECK_MENU_ITEM(w)));
}

static void
trg_menu_bar_view_item_update(TrgPrefs * p, const gchar * updatedKey,
                              gpointer data)
{
    const gchar *key =
        (gchar *) g_object_get_data(G_OBJECT(data), G_DATAKEY_CONF_KEY);
    if (!g_strcmp0(updatedKey, key))
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data),
                                       trg_prefs_get_bool(p, key,
                                                          TRG_PREFS_GLOBAL));
}

static void
trg_menu_bar_view_radio_item_update(TrgPrefs * p, const gchar * updatedKey,
                                    gpointer data)
{
    const gchar *key =
        (gchar *) g_object_get_data(G_OBJECT(data), G_DATAKEY_CONF_KEY);
    gint myIndex =
        GPOINTER_TO_INT(g_object_get_data
                        (G_OBJECT(data), G_DATAKEY_PREF_VALUE));

    if (!g_strcmp0(updatedKey, key)) {
        gboolean shouldBeActive =
            trg_prefs_get_int(p, key, TRG_PREFS_GLOBAL) == myIndex;
        if (shouldBeActive !=
            gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(data)))
            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(data),
                                           shouldBeActive);
    }
}

static GtkWidget *trg_menu_bar_view_radio_item_new(TrgPrefs * prefs,
                                                   GSList * group,
                                                   const gchar * key,
                                                   gint index,
                                                   const gchar * label)
{
    GtkWidget *w = gtk_radio_menu_item_new_with_label(group, label);
    g_object_set_data_full(G_OBJECT(w), G_DATAKEY_CONF_KEY, g_strdup(key),
                           g_free);
    g_object_set_data(G_OBJECT(w), G_DATAKEY_PREF_VALUE,
                      GINT_TO_POINTER(index));

    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),
                                   trg_prefs_get_int(prefs, key,
                                                     TRG_PREFS_GLOBAL) ==
                                   (gint64) index);

    g_signal_connect(w, "toggled",
                     G_CALLBACK(view_menu_radio_item_toggled_cb), prefs);
    g_signal_connect(prefs, "pref-changed",
                     G_CALLBACK(trg_menu_bar_view_radio_item_update), w);

    return w;
}

static GtkWidget *trg_menu_bar_view_item_new(TrgPrefs * prefs,
                                             const gchar * key,
                                             const gchar * label,
                                             GtkWidget * dependency)
{
    GtkWidget *w = gtk_check_menu_item_new_with_label(label);
    g_object_set_data_full(G_OBJECT(w), G_DATAKEY_CONF_KEY, g_strdup(key),
                           g_free);

    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),
                                   trg_prefs_get_bool(prefs, key,
                                                      TRG_PREFS_GLOBAL));

    if (dependency) {
        gtk_widget_set_sensitive(w,
                                 gtk_check_menu_item_get_active
                                 (GTK_CHECK_MENU_ITEM(dependency)));
        g_signal_connect(dependency, "toggled",
                         G_CALLBACK(view_menu_bar_toggled_dependency_cb),
                         w);
    }

    g_signal_connect(w, "toggled",
                     G_CALLBACK(view_menu_item_toggled_cb), prefs);
    g_signal_connect(prefs, "pref-changed",
                     G_CALLBACK(trg_menu_bar_view_item_update), w);

    return w;
}

static GtkWidget *trg_menu_bar_view_menu_new(TrgMenuBar * mb)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(mb);

    GtkWidget *view = gtk_menu_item_new_with_mnemonic(_("_View"));
    GtkWidget *viewMenu = gtk_menu_new();
    GSList *group;

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), viewMenu);

    priv->mb_view_transmission =
        trg_menu_bar_view_radio_item_new(priv->prefs, NULL,
                                         TRG_PREFS_KEY_STYLE, TRG_STYLE_TR,
                                         _("Transmission Style"));
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          priv->mb_view_transmission);
    group =
        gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM
                                      (priv->mb_view_transmission));
    priv->mb_view_transmission_compact =
        trg_menu_bar_view_radio_item_new(priv->prefs, group,
                                         TRG_PREFS_KEY_STYLE,
                                         TRG_STYLE_TR_COMPACT,
                                         _("Transmission Compact Style"));
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          priv->mb_view_transmission_compact);
    group =
        gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM
                                      (priv->mb_view_transmission_compact));
    priv->mb_view_classic =
        trg_menu_bar_view_radio_item_new(priv->prefs, group,
                                         TRG_PREFS_KEY_STYLE,
                                         TRG_STYLE_CLASSIC,
                                         _("Classic Style"));
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_classic);

    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          trg_tree_view_sort_menu(TRG_TREE_VIEW
                                                  (priv->torrent_tree_view),
                                                  _("Sort")));

    priv->mb_view_states =
        trg_menu_bar_view_item_new(priv->prefs,
                                   TRG_PREFS_KEY_SHOW_STATE_SELECTOR,
                                   _("State selector"), NULL);
    trg_menu_bar_accel_add(mb, priv->mb_view_states, GDK_F2, 0);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_states);

    priv->mb_directory_filters =
        trg_menu_bar_view_item_new(priv->prefs, TRG_PREFS_KEY_FILTER_DIRS,
                                   _("Directory filters"),
                                   priv->mb_view_states);
    trg_menu_bar_accel_add(mb, priv->mb_directory_filters, GDK_F3, 0);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          priv->mb_directory_filters);

    priv->mb_tracker_filters =
        trg_menu_bar_view_item_new(priv->prefs,
                                   TRG_PREFS_KEY_FILTER_TRACKERS,
                                   _("Tracker filters"),
                                   priv->mb_view_states);
    trg_menu_bar_accel_add(mb, priv->mb_tracker_filters, GDK_F4, 0);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          priv->mb_tracker_filters);

	priv->mb_directory_first =
		trg_menu_bar_view_item_new(priv->prefs,
									TRG_PREFS_KEY_DIRECTORIES_FIRST,
									_("Directories first"),
									priv->mb_view_states);
	gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
							priv->mb_directory_first);

    priv->mb_view_notebook =
        trg_menu_bar_view_item_new(priv->prefs,
                                   TRG_PREFS_KEY_SHOW_NOTEBOOK,
                                   _("Torrent Details"), NULL);
    trg_menu_bar_accel_add(mb, priv->mb_view_notebook, GDK_F5, 0);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu),
                          priv->mb_view_notebook);

#if TRG_WITH_GRAPH
    priv->mb_view_graph =
        trg_menu_bar_view_item_new(priv->prefs, TRG_PREFS_KEY_SHOW_GRAPH,
                                   _("Graph"), priv->mb_view_notebook);
    trg_menu_bar_accel_add(mb, priv->mb_view_graph, GDK_F6, 0);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_graph);
#endif

    priv->mb_view_stats =
        gtk_menu_item_new_with_mnemonic(_("_Statistics"));
    trg_menu_bar_accel_add(mb, priv->mb_view_stats, GDK_F7, 0);
    gtk_widget_set_sensitive(priv->mb_view_stats, FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_stats);

#if HAVE_RSS
    priv->mb_view_rss =
        gtk_menu_item_new_with_mnemonic(_("_RSS"));
    //trg_menu_bar_accel_add(mb, priv->mb_view_rss, GDK_F7, 0);
    gtk_widget_set_sensitive(priv->mb_view_rss, FALSE);
    gtk_menu_shell_append(GTK_MENU_SHELL(viewMenu), priv->mb_view_rss);
#endif

    return view;
}

static GtkWidget *trg_menu_bar_options_menu_new(TrgMenuBar * menu)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(menu);

    GtkWidget *opts = gtk_menu_item_new_with_mnemonic(_("_Options"));
    GtkWidget *optsMenu = gtk_menu_new();
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(opts), optsMenu);

    priv->mb_local_prefs =
        trg_menu_bar_item_new(GTK_MENU_SHELL(optsMenu),
                              _("_Local Preferences"),
                              TRUE);
    trg_menu_bar_accel_add(menu, priv->mb_local_prefs, GDK_s,
                           GDK_CONTROL_MASK);

    priv->mb_remote_prefs =
        trg_menu_bar_item_new(GTK_MENU_SHELL(optsMenu),
                              _("_Remote Preferences"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_remote_prefs, GDK_s,
                           GDK_MOD1_MASK);

    return opts;
}

static void
trg_menu_bar_file_connect_item_new(TrgMainWindow * win,
                                   GtkMenuShell * shell,
                                   const gchar * text,
                                   gboolean checked, JsonObject * profile)
{
    GtkWidget *item = gtk_check_menu_item_new_with_label(text);

    gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), checked);
    g_object_set_data(G_OBJECT(item), "profile", profile);
    gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(item), TRUE);

    g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(connect_cb),
                     win);

    gtk_menu_shell_append(shell, item);
}

GtkWidget *trg_menu_bar_file_connect_menu_new(TrgMainWindow * win,
                                              TrgPrefs * p)
{
    GtkWidget *menu = gtk_menu_new();
    GList *profiles = json_array_get_elements(trg_prefs_get_profiles(p));
    JsonObject *currentProfile = trg_prefs_get_profile(p);
    GList *li;

    for (li = profiles; li; li = g_list_next(li)) {
        JsonObject *profile = json_node_get_object((JsonNode *) li->data);
        const gchar *name_value;

        if (json_object_has_member(profile, TRG_PREFS_KEY_PROFILE_NAME)) {
            name_value = json_object_get_string_member(profile,
                                                       TRG_PREFS_KEY_PROFILE_NAME);
        } else {
            name_value = _(TRG_PROFILE_NAME_DEFAULT);
        }

        trg_menu_bar_file_connect_item_new(win, GTK_MENU_SHELL(menu),
                                           name_value,
                                           profile == currentProfile,
                                           profile);
    }

    g_list_free(profiles);

    return menu;
}

static GtkWidget *trg_menu_bar_file_file_menu_new(TrgMenuBar * menu)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(menu);

    GtkWidget *file = gtk_menu_item_new_with_mnemonic(_("_File"));
    GtkWidget *fileMenu = gtk_menu_new();

    GtkWidget *connectMenu =
        trg_menu_bar_file_connect_menu_new(priv->main_window, priv->prefs);

    priv->mb_connect =
        trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), _("Connect"),
                              TRUE);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(priv->mb_connect),
                              connectMenu);

    priv->mb_disconnect =
        trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), _("_Disconnect"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_disconnect, GDK_d,
                           GDK_CONTROL_MASK);

    priv->mb_add =
        trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), _("_Add"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_add, GDK_o, GDK_CONTROL_MASK);

    priv->mb_add_url =
        trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), _("Add from _URL"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_add_url, GDK_u,
                           GDK_CONTROL_MASK);

    priv->mb_quit =
        trg_menu_bar_item_new(GTK_MENU_SHELL(fileMenu), _("_Quit"),
                              TRUE);
    trg_menu_bar_accel_add(menu, priv->mb_quit, GDK_q,
                           GDK_CONTROL_MASK);

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), fileMenu);

    return file;
}

static GtkWidget *trg_menu_bar_torrent_menu_new(TrgMenuBar * menu)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(menu);
    GtkWidget *torrent = gtk_menu_item_new_with_mnemonic(_("_Torrent"));
    GtkWidget *torrentMenu = gtk_menu_new();

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(torrent), torrentMenu);

    priv->mb_props =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("Properties"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_props, GDK_i, GDK_CONTROL_MASK);

    priv->mb_copy_magnetlink =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Copy Magnet Link"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_copy_magnetlink, GDK_c, GDK_CONTROL_MASK);

    priv->mb_resume =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Resume"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_resume, GDK_r, GDK_CONTROL_MASK);

    priv->mb_pause =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Pause"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_pause, GDK_p, GDK_CONTROL_MASK);

    priv->mb_verify =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Verify"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_verify, GDK_h, GDK_CONTROL_MASK);

    priv->mb_reannounce =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("Re-_announce"), FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_reannounce, GDK_q,
                           GDK_CONTROL_MASK);

    priv->mb_move =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Move"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_move, GDK_m, GDK_CONTROL_MASK);

    priv->mb_remove =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("Remove"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_remove, GDK_Delete, 0);

    priv->mb_delete =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("Remove and delete data"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_delete, GDK_Delete,
                           GDK_SHIFT_MASK);

    priv->mb_queues_seperator = gtk_separator_menu_item_new();
    gtk_menu_shell_append(GTK_MENU_SHELL(torrentMenu),
                          priv->mb_queues_seperator);

    priv->mb_start_now = trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                                               _("Start Now"),
                                               FALSE);

    priv->mb_up_queue = trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                                              _("Move Up Queue"),
                                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_up_queue, GDK_Up,
                           GDK_SHIFT_MASK);

    priv->mb_down_queue =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("Move Down Queue"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_down_queue, GDK_Down,
                           GDK_SHIFT_MASK);

    priv->mb_bottom_queue =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("Bottom Of Queue"),
                              FALSE);

    priv->mb_top_queue = trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                                               _("Top Of Queue"),
                                               FALSE);

    gtk_menu_shell_append(GTK_MENU_SHELL(torrentMenu),
                          gtk_separator_menu_item_new());

    priv->mb_resume_all =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu),
                              _("_Resume All"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_resume_all, GDK_r,
                           GDK_SHIFT_MASK | GDK_CONTROL_MASK);

    priv->mb_pause_all =
        trg_menu_bar_item_new(GTK_MENU_SHELL(torrentMenu), _("_Pause All"),
                              FALSE);
    trg_menu_bar_accel_add(menu, priv->mb_pause_all, GDK_p,
                           GDK_SHIFT_MASK | GDK_CONTROL_MASK);

    return torrent;
}

static GtkWidget *trg_menu_bar_help_menu_new(TrgMenuBar * menuBar)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(menuBar);

    GtkWidget *help = gtk_menu_item_new_with_mnemonic(_("_Help"));
    GtkWidget *helpMenu = gtk_menu_new();
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(help), helpMenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), help);

    priv->mb_about =
        trg_menu_bar_item_new(GTK_MENU_SHELL(helpMenu), _("_About"),
                              TRUE);

    return helpMenu;
}

static void menu_bar_refresh_menu(GtkWidget * w, gpointer data)
{
    TrgMenuBarPrivate *priv = TRG_MENU_BAR_GET_PRIVATE(data);
    GtkWidget *old =
        gtk_menu_item_get_submenu(GTK_MENU_ITEM(priv->mb_connect));
    GtkWidget *new =
        trg_menu_bar_file_connect_menu_new(priv->main_window, priv->prefs);

    gtk_widget_destroy(old);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(priv->mb_connect), new);
    gtk_widget_show_all(new);
}

static GObject *trg_menu_bar_constructor(GType type,
                                         guint n_construct_properties,
                                         GObjectConstructParam *
                                         construct_params)
{
    GObject *object;
    TrgMenuBarPrivate *priv;
    TrgMenuBar *menu;

    object = G_OBJECT_CLASS
        (trg_menu_bar_parent_class)->constructor(type,
                                                 n_construct_properties,
                                                 construct_params);
    menu = TRG_MENU_BAR(object);
    priv = TRG_MENU_BAR_GET_PRIVATE(object);

    gtk_menu_shell_append(GTK_MENU_SHELL(object),
                          trg_menu_bar_file_file_menu_new(menu));
    gtk_menu_shell_append(GTK_MENU_SHELL(object),
                          trg_menu_bar_torrent_menu_new(menu));
    gtk_menu_shell_append(GTK_MENU_SHELL(object),
                          trg_menu_bar_options_menu_new(menu));
    gtk_menu_shell_append(GTK_MENU_SHELL(object),
                          trg_menu_bar_view_menu_new(menu));
    trg_menu_bar_help_menu_new(TRG_MENU_BAR(object));

    g_signal_connect(G_OBJECT(priv->prefs), "pref-profile-changed",
                     G_CALLBACK(menu_bar_refresh_menu), object);

    return object;
}

static void trg_menu_bar_class_init(TrgMenuBarClass * klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS(klass);
    object_class->get_property = trg_menu_bar_get_property;
    object_class->set_property = trg_menu_bar_set_property;
    object_class->constructor = trg_menu_bar_constructor;

    g_type_class_add_private(klass, sizeof(TrgMenuBarPrivate));

    trg_menu_bar_install_widget_prop(object_class, PROP_CONNECT_BUTTON,
                                     "connect-button", "Connect Button");
    trg_menu_bar_install_widget_prop(object_class,
                                     PROP_DISCONNECT_BUTTON,
                                     "disconnect-button",
                                     "Disconnect Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_ADD_BUTTON,
                                     "add-button", "Add Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_ADD_URL_BUTTON,
                                     "add-url-button", "Add URL Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_REMOVE_BUTTON,
                                     "remove-button", "Remove Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_MOVE_BUTTON,
                                     "move-button", "Move Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_DELETE_BUTTON,
                                     "delete-button", "Delete Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_RESUME_BUTTON,
                                     "resume-button", "Resume Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_RESUME_ALL_BUTTON,
                                     "resume-all-button",
                                     "Resume All Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_VERIFY_BUTTON,
                                     "verify-button", "Verify Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_REANNOUNCE_BUTTON,
                                     "reannounce-button",
                                     "Re-announce Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_PAUSE_ALL_BUTTON,
                                     "pause-all-button",
                                     "Pause All Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_PAUSE_BUTTON,
                                     "pause-button", "Pause Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_PROPS_BUTTON,
                                     "props-button", "Props Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_COPYMAGNET_BUTTON,
                                     "copymagnet-button", "Copy-magnet Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_ABOUT_BUTTON,
                                     "about-button", "About Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_STATS_BUTTON,
                                     "view-stats-button",
                                     "View stats button");
#if HAVE_RSS
    trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_RSS_BUTTON,
                                     "view-rss-button",
                                     "View rss button");
#endif
    trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_STATES_BUTTON,
                                     "view-states-button",
                                     "View states Button");
    trg_menu_bar_install_widget_prop(object_class,
                                     PROP_VIEW_NOTEBOOK_BUTTON,
                                     "view-notebook-button",
                                     "View notebook Button");
    trg_menu_bar_install_widget_prop(object_class,
                                     PROP_REMOTE_PREFS_BUTTON,
                                     "remote-prefs-button",
                                     "Remote Prefs Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_LOCAL_PREFS_BUTTON,
                                     "local-prefs-button",
                                     "Local Prefs Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_QUIT,
                                     "quit-button", "Quit Button");
    trg_menu_bar_install_widget_prop(object_class, PROP_DIR_FILTERS,
                                     "dir-filters", "Dir Filters");
    trg_menu_bar_install_widget_prop(object_class, PROP_TRACKER_FILTERS,
                                     "tracker-filters", "Tracker Filters");
	trg_menu_bar_install_widget_prop(object_class, PROP_DIRECTORIES_FIRST,
									 TRG_PREFS_KEY_DIRECTORIES_FIRST, "Directories first");
#if TRG_WITH_GRAPH
    trg_menu_bar_install_widget_prop(object_class, PROP_VIEW_SHOW_GRAPH,
                                     "show-graph", "Show Graph");
#endif
    trg_menu_bar_install_widget_prop(object_class, PROP_MOVE_DOWN_QUEUE,
                                     "down-queue", "Down Queue");
    trg_menu_bar_install_widget_prop(object_class, PROP_MOVE_UP_QUEUE,
                                     "up-queue", "Up Queue");
    trg_menu_bar_install_widget_prop(object_class, PROP_MOVE_BOTTOM_QUEUE,
                                     "bottom-queue", "Bottom Queue");
    trg_menu_bar_install_widget_prop(object_class, PROP_MOVE_TOP_QUEUE,
                                     "top-queue", "Top Queue");
    trg_menu_bar_install_widget_prop(object_class, PROP_START_NOW,
                                     "start-now", "Start Now");

    g_object_class_install_property(object_class,
                                    PROP_PREFS,
                                    g_param_spec_object("prefs",
                                                        "prefs",
                                                        "Prefs",
                                                        TRG_TYPE_PREFS,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY
                                                        |
                                                        G_PARAM_STATIC_NAME
                                                        |
                                                        G_PARAM_STATIC_NICK
                                                        |
                                                        G_PARAM_STATIC_BLURB));

    g_object_class_install_property(object_class,
                                    PROP_ACCEL_GROUP,
                                    g_param_spec_object("accel-group",
                                                        "accel-group",
                                                        "accel-group",
                                                        GTK_TYPE_ACCEL_GROUP,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY
                                                        |
                                                        G_PARAM_STATIC_NAME
                                                        |
                                                        G_PARAM_STATIC_NICK
                                                        |
                                                        G_PARAM_STATIC_BLURB));

    g_object_class_install_property(object_class,
                                    PROP_MAIN_WINDOW,
                                    g_param_spec_object("mainwin",
                                                        "mainwin",
                                                        "mainwin",
                                                        TRG_TYPE_MAIN_WINDOW,
                                                        G_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY
                                                        |
                                                        G_PARAM_STATIC_NAME
                                                        |
                                                        G_PARAM_STATIC_NICK
                                                        |
                                                        G_PARAM_STATIC_BLURB));

    g_object_class_install_property(object_class,
                                    PROP_TORRENT_TREE_VIEW,
                                    g_param_spec_object
                                    ("torrent-tree-view",
                                     "torrent-tree-view",
                                     "torrent-tree-view",
                                     TRG_TYPE_TORRENT_TREE_VIEW,
                                     G_PARAM_READWRITE |
                                     G_PARAM_CONSTRUCT_ONLY |
                                     G_PARAM_STATIC_NAME |
                                     G_PARAM_STATIC_NICK |
                                     G_PARAM_STATIC_BLURB));
}

static void trg_menu_bar_init(TrgMenuBar * self)
{
}

TrgMenuBar *trg_menu_bar_new(TrgMainWindow * win, TrgPrefs * prefs,
                             TrgTorrentTreeView * ttv,
                             GtkAccelGroup * accel_group)
{
    return g_object_new(TRG_TYPE_MENU_BAR,
                        "torrent-tree-view", ttv, "prefs", prefs,
                        "mainwin", win, "accel-group", accel_group, NULL);
}
