/*
    DeaDBeeF -- the music player
    Copyright (C) 2009-2013 Alexey Yakovenko and other contributors

    This software is provided 'as-is', without any express or implied
    warranty.  In no event will the authors be held liable for any damages
    arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:

    1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.

    2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.

    3. This notice may not be removed or altered from any source distribution.
*/
#include "../../deadbeef.h"
#include <gtk/gtk.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include "../../gettext.h"
#include <string.h>
#include <stdlib.h>
#include "gtkui.h"
#include "interface.h"
#include "support.h"

#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
  g_object_set_data (G_OBJECT (component), name, widget)

// selected playlist for the context menu
static int pltmenu_idx;

void
plt_get_title_wrapper (int plt, char *buffer, int len) {
    if (plt == -1) {
        strcpy (buffer, "");
        return;
    }
    ddb_playlist_t *p = deadbeef->plt_get_for_idx (plt);
    deadbeef->plt_get_title (p, buffer, len);
    deadbeef->plt_unref (p);
    char *end;
    if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) {
        *end = 0;
    }
}

static void
on_rename_playlist1_activate           (GtkMenuItem     *menuitem,
                                        gpointer         user_data)
{
    GtkWidget *dlg = create_entrydialog ();
    gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
    gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist"));
    GtkWidget *e;
    e = lookup_widget (dlg, "title_label");
    gtk_label_set_text (GTK_LABEL(e), _("Title:"));
    e = lookup_widget (dlg, "title");
    char t[1000];
    plt_get_title_wrapper (pltmenu_idx, t, sizeof (t));
    gtk_entry_set_text (GTK_ENTRY (e), t);
    int res = gtk_dialog_run (GTK_DIALOG (dlg));
    if (res == GTK_RESPONSE_OK) {
        const char *text = gtk_entry_get_text (GTK_ENTRY (e));
        deadbeef->pl_lock ();
        ddb_playlist_t *p = deadbeef->plt_get_for_idx (pltmenu_idx);
        deadbeef->plt_set_title (p, text);
        deadbeef->plt_unref (p);
        deadbeef->pl_unlock ();
    }
    gtk_widget_destroy (dlg);
}

static void
on_remove_playlist1_activate           (GtkMenuItem     *menuitem,
                                        gpointer         user_data)
{
    if (pltmenu_idx != -1) {
        deadbeef->plt_remove (pltmenu_idx);
        search_refresh ();
        int playlist = deadbeef->plt_get_curr_idx ();
        deadbeef->conf_set_int ("playlist.current", playlist);
    }
}

static void
on_add_new_playlist1_activate          (GtkMenuItem     *menuitem,
                                        gpointer         user_data)
{
    int playlist = gtkui_add_new_playlist ();
    if (playlist != -1) {
        gtkui_playlist_set_curr (playlist);
    }
}

static void
on_actionitem_activate (GtkMenuItem     *menuitem,
                           DB_plugin_action_t *action)
{
    if (action->callback) {
        ddb_playlist_t *plt = NULL;
        if (pltmenu_idx != -1) {
            plt = deadbeef->plt_get_for_idx (pltmenu_idx);
        }
        action->callback (action, plt);
        if (plt) {
            deadbeef->plt_unref (plt);
        }
    }
    else {
        action->callback2 (action, DDB_ACTION_CTX_PLAYLIST);
    }
}

static GtkWidget*
find_popup                          (GtkWidget       *widget,
                                        const gchar     *widget_name)
{
  GtkWidget *parent, *found_widget;

  for (;;)
    {
      if (GTK_IS_MENU (widget))
        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
      else
        parent = gtk_widget_get_parent (widget);
      if (!parent)
        parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
      if (parent == NULL)
        break;
      widget = parent;
    }

  found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
                                                 widget_name);
  return found_widget;
}

static void
add_tab_actions (GtkWidget *menu) {
    DB_plugin_t **plugins = deadbeef->plug_get_list();
    int i;

    int added_entries = 0;

    int hide_remove_from_disk = deadbeef->conf_get_int ("gtkui.hide_remove_from_disk", 0);

    for (i = 0; plugins[i]; i++)
    {
        if (!plugins[i]->get_actions)
            continue;

        DB_plugin_action_t *actions = plugins[i]->get_actions (NULL);
        DB_plugin_action_t *action;

        int count = 0;
        for (action = actions; action; action = action->next)
        {
            char *tmp = NULL;
            if (!(action->flags & DB_ACTION_MULTIPLE_TRACKS))
                continue;

            if (action->name && !strcmp (action->name, "delete_from_disk") && hide_remove_from_disk) {
                continue;
            }

            // create submenus (separated with '/')
            const char *prev = action->title;
            while (*prev && *prev == '/') {
                prev++;
            }
            
            GtkWidget *popup = NULL;
            
            for (;;) {
                const char *slash = strchr (prev, '/');
                if (slash && *(slash-1) != '\\') {
                    char name[slash-prev+1];
                    // replace \/ with /
                    const char *p = prev;
                    char *t = name;
                    while (*p && p < slash) {
                        if (*p == '\\' && *(p+1) == '/') {
                            *t++ = '/';
                            p += 2;
                        }
                        else {
                            *t++ = *p++;
                        }
                    }
                    *t = 0;

                    // add popup
                    GtkWidget *prev_menu = popup ? popup : menu;

                    popup = find_popup (prev_menu, name);
                    if (!popup) {
                        GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (_(name));
                        gtk_widget_show (item);
                        gtk_container_add (GTK_CONTAINER (prev_menu), item);
                        popup = gtk_menu_new ();
                        GLADE_HOOKUP_OBJECT_NO_REF (prev_menu, popup, name);
                        gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), popup);
                    }
                }
                else {
                    break;
                }
                prev = slash+1;
            }


            count++;
            added_entries++;
            GtkWidget *actionitem;

            // replace \/ with /
            const char *p = popup ? prev : action->title;
            char title[strlen (p)+1];
            char *t = title;
            while (*p) {
                if (*p == '\\' && *(p+1) == '/') {
                    *t++ = '/';
                    p += 2;
                }
                else {
                    *t++ = *p++;
                }
            }
            *t = 0;

            actionitem = gtk_menu_item_new_with_mnemonic (_(title));
            gtk_widget_show (actionitem);
            gtk_container_add (popup ? GTK_CONTAINER (popup) : GTK_CONTAINER (menu), actionitem);

            g_signal_connect ((gpointer) actionitem, "activate",
                    G_CALLBACK (on_actionitem_activate),
                    action);
        }
    }
}

GtkWidget*
gtkui_create_pltmenu (int plt_idx) {
    GtkWidget *plmenu;
    GtkWidget *rename_playlist1;
    GtkWidget *remove_playlist1;
    GtkWidget *add_new_playlist1;
    GtkWidget *separator11;
    GtkWidget *load_playlist1;
    GtkWidget *save_playlist1;
    GtkWidget *save_all_playlists1;

    plmenu = gtk_menu_new ();
    pltmenu_idx = plt_idx;

    rename_playlist1 = gtk_menu_item_new_with_mnemonic (_("Rename Playlist"));
    if (pltmenu_idx == -1) {
        gtk_widget_set_sensitive (rename_playlist1, FALSE);
    }
    gtk_widget_show (rename_playlist1);
    gtk_container_add (GTK_CONTAINER (plmenu), rename_playlist1);

    remove_playlist1 = gtk_menu_item_new_with_mnemonic (_("Remove Playlist"));
    if (pltmenu_idx == -1) {
        gtk_widget_set_sensitive (remove_playlist1, FALSE);
    }
    gtk_widget_show (remove_playlist1);
    gtk_container_add (GTK_CONTAINER (plmenu), remove_playlist1);

    add_new_playlist1 = gtk_menu_item_new_with_mnemonic (_("Add New Playlist"));
    gtk_widget_show (add_new_playlist1);
    gtk_container_add (GTK_CONTAINER (plmenu), add_new_playlist1);

    g_signal_connect ((gpointer) rename_playlist1, "activate",
            G_CALLBACK (on_rename_playlist1_activate),
            NULL);
    g_signal_connect ((gpointer) remove_playlist1, "activate",
            G_CALLBACK (on_remove_playlist1_activate),
            NULL);
    g_signal_connect ((gpointer) add_new_playlist1, "activate",
            G_CALLBACK (on_add_new_playlist1_activate),
            NULL);

    add_tab_actions (plmenu);

    return plmenu;
}

