/* Chrysalide - Outil d'analyse de fichiers binaires
 * binary.c - gestion du menu 'Binaire'
 *
 * Copyright (C) 2012-2017 Cyrille Bagard
 *
 *  This binary is part of Chrysalide.
 *
 *  Chrysalide 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.
 *
 *  Chrysalide 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "binary.h"


#include <i18n.h>


#include "../editem-int.h"
#include "../core/global.h"
#include "../dialogs/export.h"
#include "../dialogs/gotox.h"
#include "../dialogs/storage.h"
#include "../../gtkext/easygtk.h"



/* Réagit au menu "Binaire -> Points d'entrée". */
static void mcb_binary_entry_points(GtkMenuItem *, GMenuBar *);

/* Réagit au menu "Binaire -> Attacher un débogueur". */
static void mcb_binary_attach_debugger(GtkMenuItem *, GMenuBar *);

/* Réagit au menu "Binaire -> Enregistrements...". */
static void mcb_binary_storage(GtkMenuItem *, GMenuBar *);

/* Réagit au menu "Binaire -> Exporter...". */
static void mcb_binary_export(GtkMenuItem *, GMenuBar *);



/******************************************************************************
*                                                                             *
*  Paramètres  : ref      = espace de référencement global.                   *
*                accgroup = groupe d'accélérateurs pour les menus.            *
*                bar      = barre de menu parente.                            *
*                                                                             *
*  Description : Construit le menu "Binaire".                                 *
*                                                                             *
*  Retour      : Panneau de menus mis en place.                               *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

GtkWidget *build_menu_binary(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar)
{
    GtkWidget *result;                      /* Support à retourner         */
    GtkWidget *menubar;                     /* Support pour éléments       */
    GtkWidget *submenuitem;                 /* Sous-élément de menu        */

    result = gtk_menu_item_new_with_mnemonic(_("_Binary"));
    gtk_widget_show(result);

    menubar = qck_create_menu(GTK_MENU_ITEM(result));

    submenuitem = qck_create_menu_item(ref, "mnu_binary_epoints", _("Entry points"),
                                       G_CALLBACK(mcb_binary_entry_points), bar);
    add_accelerator_to_menu_item(submenuitem, "<Ctrl>E", accgroup);
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    submenuitem = qck_create_menu_separator();
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    submenuitem = qck_create_menu_item(ref, "mnu_binary_attach_debugger", _("Attach a debugger"),
                                       G_CALLBACK(mcb_binary_attach_debugger), bar);
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    submenuitem = qck_create_menu_separator();
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    submenuitem = qck_create_menu_item(ref, "mnu_binary_storage", _("Storage..."),
                                       G_CALLBACK(mcb_binary_storage), bar);
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    submenuitem = qck_create_menu_item(ref, "mnu_binary_export", _("Export..."),
                                       G_CALLBACK(mcb_binary_export), bar);
    gtk_container_add(GTK_CONTAINER(menubar), submenuitem);

    return result;

}


/******************************************************************************
*                                                                             *
*  Paramètres  : ref   = espace de référencements à consulter.                *
*                panel = panneau d'affichage actif ou NULL si aucun.          *
*                                                                             *
*  Description : Met à jour les accès du menu "Binaire" selon le contenu.     *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

void update_access_in_menu_binary(GObject *ref, GtkDisplayPanel *panel)
{
    gboolean access;                        /* Accès à déterminer          */
    GtkWidget *item;                        /* Elément de menu à traiter   */

    /* Préliminaire */

    access = (panel != NULL);

    /* Menus */

    item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_epoints"));
    gtk_widget_set_sensitive(item, access);

    item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_storage"));
    gtk_widget_set_sensitive(item, access);

    item = GTK_WIDGET(g_object_get_data(ref, "mnu_binary_export"));
    gtk_widget_set_sensitive(item, access);

}


/******************************************************************************
*                                                                             *
*  Paramètres  : menuitem = élément de menu sélectionné.                      *
*                bar      = barre de menu parente.                            *
*                                                                             *
*  Description : Réagit au menu "Binaire -> Points d'entrée".                 *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void mcb_binary_entry_points(GtkMenuItem *menuitem, GMenuBar *bar)
{
    GEditorItem *item;                      /* Elément d'éditeur graphique */
    GObject *ref;                           /* Espace de référencements    */
    GLoadedBinary *binary;                  /* Binaire présenté à l'écran  */
    GtkWidget *dialog;                      /* Boîte de dialogue à montrer */
    vmpa2t *addr;                           /* Adresse de destination      */
    GtkDisplayPanel *panel;                 /* Afficheur effectif de code  */

    item = G_EDITOR_ITEM(bar);

    ref = g_editor_item_get_global_ref(item);
    binary = get_current_binary();

    dialog = create_gotox_dialog_for_entry_points(GTK_WINDOW(ref), binary);

    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
    {
        addr = get_address_from_gotox_dialog(dialog);

        panel = get_current_view();
        gtk_display_panel_request_move(panel, addr);
        g_object_unref(G_OBJECT(panel));

        delete_vmpa(addr);

    }

    gtk_widget_destroy(dialog);

    g_object_unref(G_OBJECT(binary));

}


/******************************************************************************
*                                                                             *
*  Paramètres  : menuitem = élément de menu sélectionné.                      *
*                bar      = barre de menu parente.                            *
*                                                                             *
*  Description : Réagit au menu "Binaire -> Attacher un débogueur".           *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void mcb_binary_attach_debugger(GtkMenuItem *menuitem, GMenuBar *bar)
{

}


/******************************************************************************
*                                                                             *
*  Paramètres  : menuitem = élément de menu sélectionné.                      *
*                bar      = barre de menu parente.                            *
*                                                                             *
*  Description : Réagit au menu "Binaire -> Enregistrements...".              *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void mcb_binary_storage(GtkMenuItem *menuitem, GMenuBar *bar)
{
    GLoadedBinary *binary;                  /* Edition courante            */
    GObject *ref;                           /* Espace de référencements    */
    GtkBuilder *builder;                    /* Constructeur utilisé        */
    GtkWidget *dialog;                      /* Boîte de dialogue à montrer */

    binary = get_current_binary();
    ref = g_editor_item_get_global_ref(G_EDITOR_ITEM(bar));

    dialog = create_storage_dialog(binary, GTK_WINDOW(ref), &builder);

    gtk_dialog_run(GTK_DIALOG(dialog));

    gtk_widget_destroy(dialog);

    g_object_unref(G_OBJECT(builder));

    g_object_unref(G_OBJECT(binary));

}


/******************************************************************************
*                                                                             *
*  Paramètres  : menuitem = élément de menu sélectionné.                      *
*                bar      = barre de menu parente.                            *
*                                                                             *
*  Description : Réagit au menu "Binaire -> Exporter...".                     *
*                                                                             *
*  Retour      : -                                                            *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

static void mcb_binary_export(GtkMenuItem *menuitem, GMenuBar *bar)
{
    GLoadedBinary *binary;                  /* Edition courante            */

    binary = get_current_binary();

    run_export_assistant(binary, GTK_WINDOW(G_EDITOR_ITEM(bar)->ref));

    g_object_unref(G_OBJECT(binary));

}