#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "../guiutils.h"
#include "ascii_chart_dlg.h"
#include "config.h"

#include "../images/icon_copy_20x20.xpm"
#include "../images/icon_ok_20x20.xpm"


static gint ASCIIChartDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
);
static void ASCIIChartDlgCopyToClipboardCB(GtkWidget *widget, gpointer data);
static void ASCIIChartDlgOKCB(GtkWidget *widget, gpointer data);

static GtkWidget *ASCIIChartDlgNewASCIIValue(
	GtkWidget *parent, const guint8 v, const gchar *desc,
	GtkRcStyle *rcstyle,
	const gint border_major, const gint border_minor,
	const gint hex_value_width, const gint decimal_value_width,
	const gint octave_value_width, const gint ascii_value_width,
	const gint desc_value_width
);
ascii_chart_dlg_struct *ASCIIChartDlgNew(GtkWidget *ref_toplevel);
void ASCIIChartDlgUpdateMenus(ascii_chart_dlg_struct *d);
gboolean ASCIIChartDlgIsMapped(ascii_chart_dlg_struct *d);
void ASCIIChartDlgMap(ascii_chart_dlg_struct *d);
void ASCIIChartDlgUnmap(ascii_chart_dlg_struct *d);
void ASCIIChartDlgDelete(ascii_chart_dlg_struct *d);


#define ASCII_CHART_DLG_DEF_WIDTH	500
#define ASCII_CHART_DLG_DEF_HEIGHT	400

/* Descriptions List */
#define ASCII_CHART_DLG_DESC_LIST	{			\
	"(NUL) Null",				/* 0x00	0 */	\
	"(SOH) Start of heading",				\
	"(STX) Start of text",					\
	"(ETX) End of text",					\
	"(EOT) End of transmission",				\
	"(ENQ) Enquery",					\
	"(ACK) Acknowledge",					\
	"(BEL) Bell",						\
	"(BS) Backspace",					\
	"(TAB) Horizontal tab",					\
	"(LF) Line feed or new line",		/* 0x0A 10 */	\
	"(VT) Vertical tab",					\
	"(FF) Form feed or new page",				\
	"(CR) Carrage return",					\
	"(SO) Shift out",					\
	"(SO) Shift in",					\
	"(DLE) Data link escape",				\
	"(DC1) Device control 1",				\
	"(DC2) Device control 2",				\
	"(DC3) Device control 3",				\
	"(DC4) Device control 4",		/* 0x14 20 */	\
	"(NAK) Do not acknowledge",				\
	"(SYN) Synchronous idle",				\
	"(ETB) End of transmission block",			\
	"(CAN) Cancel",						\
	"(EM) End of medium",					\
	"(SUB) Substitute",					\
	"(ESC) Escape",						\
	"(FS) File separator",					\
	"(GS) Group separator",					\
	"(RS) Record separator",		/* 0x1E 30 */	\
	"(US) Unit separator",					\
	"(SP) Space",						\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 40 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 50 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 60 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 70 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 80 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 90 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 100 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 110 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 120 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	"(DEL)",						\
	NULL,							\
	NULL,							\
	NULL,					/* 130 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 140 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 150 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 160 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 170 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 180 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 190 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 200 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 210 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 220 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 230 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 240 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,					/* 250 */	\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL,							\
	NULL					/* 0xFF 255 */	\
}


#define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
#define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)       (((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define STRLEN(s)       (((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)   (((s) != NULL) ? (*(s) == '\0') : TRUE)


/*
 *	Toplevel GtkWindow "delete_event" signal callback.
 */
static gint ASCIIChartDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
)
{
	ASCIIChartDlgOKCB(widget, data);
	return(TRUE);
}

/*
 *	Copy to clipboard callback.
 */
static void ASCIIChartDlgCopyToClipboardCB(GtkWidget *widget, gpointer data)
{
	const guint32 v = (guint32)data;
	gchar *s = g_strdup_printf("%c", (gchar)v);
	GUIDDESetString(
	    widget,
	    GDK_SELECTION_PRIMARY,
	    GDK_CURRENT_TIME,
	    s
	);
	g_free(s);
}

/*
 *	OK Button callback.
 */
static void ASCIIChartDlgOKCB(GtkWidget *widget, gpointer data)
{
	ascii_chart_dlg_struct *d = ASCII_CHART_DLG(data);
	if(d == NULL)
	    return;

	ASCIIChartDlgUnmap(d);
}


/*
 *	Creates a new value widget.
 */
static GtkWidget *ASCIIChartDlgNewASCIIValue(
	GtkWidget *parent, const guint8 v, const gchar *desc,
	GtkRcStyle *rcstyle,
	const gint border_major, const gint border_minor,
	const gint hex_value_width, const gint decimal_value_width,
	const gint octave_value_width, const gint ascii_value_width,
	const gint desc_value_width
)
{
	gchar *s;
	GtkWidget *w, *parent2;

	w = gtk_hbox_new(FALSE, border_major);
	if(parent != NULL)
	{
	    if(GTK_IS_BOX(parent))
		gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	    else if(GTK_IS_CONTAINER(parent))
		gtk_container_add(GTK_CONTAINER(parent), w);
	}
	gtk_widget_show(w);                         
	parent = w;


	/* Hex value GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_widget_set_usize(w, hex_value_width, -1);
	gtk_container_border_width(GTK_CONTAINER(w), border_minor);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* Hex value GtkLabel */
	s = g_strdup_printf("0x%.2X", v);
	w = gtk_label_new(s);
	g_free(s);
        if(rcstyle != NULL)
            gtk_widget_modify_style(w, rcstyle);
	gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


	/* Decimal value GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_widget_set_usize(w, decimal_value_width, -1);
	gtk_container_border_width(GTK_CONTAINER(w), border_minor);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* Decimal value GtkLabel */
	s = g_strdup_printf("%i", v);
	w = gtk_label_new(s);
	g_free(s);
        if(rcstyle != NULL)
            gtk_widget_modify_style(w, rcstyle);
	gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


	/* Octave value GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_widget_set_usize(w, octave_value_width, -1);
	gtk_container_border_width(GTK_CONTAINER(w), border_minor);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* Octave value GtkLabel */
	s = g_strdup_printf("%.4o", v);
	w = gtk_label_new(s);
	g_free(s);
        if(rcstyle != NULL)
            gtk_widget_modify_style(w, rcstyle);
	gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


	/* ASCII value GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_widget_set_usize(w, ascii_value_width, -1);
	gtk_container_border_width(GTK_CONTAINER(w), border_minor);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* aSCII value GtkLabel */
	if((v == '\n') || (v == '\r') || (v == '\t') || (v == '\v'))
	    s = g_strdup("");
	else
	    s = g_strdup_printf("%c", (gchar)v);
	w = gtk_label_new(s);
	g_free(s);
        if(rcstyle != NULL)
            gtk_widget_modify_style(w, rcstyle);
	gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


	/* Description value GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_widget_set_usize(w, desc_value_width, -1);
	gtk_container_border_width(GTK_CONTAINER(w), border_minor);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	if(desc != NULL)
	{
	    w = gtk_label_new(desc);
	    gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	}


	/* Copy to clipboard button */
#if 1
	if(TRUE)
#else
	if((v != '\n') && (v != '\r') && (v != '\t') && (v != '\v'))
#endif
	{
	    guint32 v32;

	    w = GUIButtonPixmap((guint8 **)icon_copy_20x20_xpm);
	    gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	    v32 = (guint32)v;
	    gtk_signal_connect(
		GTK_OBJECT(w), "clicked",
		ASCIIChartDlgCopyToClipboardCB, (gpointer)v32
	    );
	    gtk_widget_show(w);
	}

	return(parent);
}


/*
 *	Creates a new ASCII Chart Dialog.
 */
ascii_chart_dlg_struct *ASCIIChartDlgNew(GtkWidget *ref_toplevel)
{
	const gint	border_major = 5,
			border_minor = 2;
	GdkWindow *window;
	GtkAccelGroup *accelgrp;
	GtkWidget *w, *parent, *parent2, *parent3, *parent4;
	ascii_chart_dlg_struct *d = ASCII_CHART_DLG(g_malloc0(
	    sizeof(ascii_chart_dlg_struct)
	));

	d->accelgrp = accelgrp = gtk_accel_group_new();
	d->processing = FALSE;
	d->freeze_count = 0;

	/* Create toplevel */
	d->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_window_set_title(
	    GTK_WINDOW(w),
	    PROG_NAME_FULL ": Extended ASCII Chart"
	);
	gtk_window_set_wmclass(
	    GTK_WINDOW(w), "dialog", PROG_NAME
	);
	gtk_widget_set_usize(
	    w,
	    ASCII_CHART_DLG_DEF_WIDTH, ASCII_CHART_DLG_DEF_HEIGHT
	);
	gtk_widget_realize(w);
	window = w->window;
	if(window != NULL)
	{
	    gdk_window_set_decorations(
		window,
		GDK_DECOR_BORDER | GDK_DECOR_TITLE | GDK_DECOR_MENU |
		GDK_DECOR_MINIMIZE
	    );
	    gdk_window_set_functions(
		window,
		GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE
	    );
/*	    GUISetWMIcon(window, (guint8 **)archiver_48x48_xpm); */
	}
	gtk_signal_connect(
	    GTK_OBJECT(w), "delete_event",
	    GTK_SIGNAL_FUNC(ASCIIChartDlgDeleteEventCB), d
	);
	gtk_container_border_width(GTK_CONTAINER(w), 0);
	gtk_window_add_accel_group(GTK_WINDOW(w), accelgrp);
	if((ref_toplevel != NULL) ?
	    GTK_IS_WINDOW(GTK_OBJECT(ref_toplevel)) : FALSE
	)
	{
	    gtk_window_set_transient_for(
		GTK_WINDOW(w), GTK_WINDOW(ref_toplevel)
	    );
	}
	parent = w;

	/* Main GtkVBox */
	d->main_vbox = w = gtk_vbox_new(FALSE, 0);
	gtk_container_border_width(GTK_CONTAINER(w), 0);
	gtk_container_add(GTK_CONTAINER(parent), w);
	gtk_widget_show(w);
	parent = w;


	/* Scrolled window for the ASCII table */
	w = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(
	    GTK_SCROLLED_WINDOW(w),
	    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
	);
	gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* ASCII table GtkVBox */
	w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_scrolled_window_add_with_viewport(
	    GTK_SCROLLED_WINDOW(parent2), w
	);
	gtk_widget_show(w);
	parent3 = w;



	/* Create each ASCII value */
	if(parent3 != NULL)
	{
	    const gint	hex_value_width = 60,
			decimal_value_width = 60,
			octave_value_width = 60,
			ascii_value_width = 60,
			desc_value_width = 175;
	    guint32 v;
	    const gchar *desc_list[] = ASCII_CHART_DLG_DESC_LIST;
	    GdkColor c_fg, c_bg;
	    GtkRcStyle *rcstyle = gtk_rc_style_new();

	    /* Heading GtkHBox */
	    w = gtk_hbox_new(FALSE, border_major);
	    gtk_container_border_width(GTK_CONTAINER(w), 0);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent4 = w;

	    GDK_COLOR_SET_COEFF(&c_fg, 1.0, 1.0, 1.0);
	    GDK_COLOR_SET_COEFF(&c_bg, 0.0, 0.0, 0.0);

	    /* Hex */
	    w = GUIBannerCreate(
		"Hex",
		PROG_GTK_FONT_NAME_TEXT_HEADING5, c_fg, c_bg,
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_widget_set_usize(w, hex_value_width, 20);
	    gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    /* Decimal */
	    w = GUIBannerCreate(
		"Decimal",
		PROG_GTK_FONT_NAME_TEXT_HEADING5, c_fg, c_bg,
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_widget_set_usize(w, decimal_value_width, 20);
	    gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    /* Octave */
	    w = GUIBannerCreate(
		"Octave",
		PROG_GTK_FONT_NAME_TEXT_HEADING5, c_fg, c_bg,
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_widget_set_usize(w, octave_value_width, 20);
	    gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    /* ASCII */
	    w = GUIBannerCreate(
		"ASCII",
		PROG_GTK_FONT_NAME_TEXT_HEADING5, c_fg, c_bg,
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_widget_set_usize(w, ascii_value_width, 20);
	    gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    /* Description */
	    w = GUIBannerCreate(
		"Description",
		PROG_GTK_FONT_NAME_TEXT_HEADING5, c_fg, c_bg,
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_widget_set_usize(w, desc_value_width, 20);
	    gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    g_free(rcstyle->font_name);
#ifdef PROG_GTK_FONT_NAME_TEXT_EDITABLE
	    rcstyle->font_name = STRDUP(PROG_GTK_FONT_NAME_TEXT_EDITABLE);
#else
	    rcstyle->font_name = STRDUP("7x14");
#endif

	    /* Values */
	    for(v = 0x00; v <= 0xff; v++)
		parent4 = ASCIIChartDlgNewASCIIValue(
		    parent3, (guint8)v, desc_list[(int)v],
		    rcstyle,
		    border_major, border_minor,
		    hex_value_width, decimal_value_width,
		    octave_value_width, ascii_value_width,
		    desc_value_width
		);

	    GTK_RC_STYLE_UNREF(rcstyle);
	}

#if 0
	/* Separator */
	w = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(d->main_vbox), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
#endif

	/* Buttons */
	w = gtk_hbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(d->main_vbox), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* OK button */
	d->ok_btn = w = GUIButtonPixmapLabelH(
	    (guint8 **)icon_ok_20x20_xpm, "OK", NULL
	);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_widget_set_usize(
	    w,
	    GUI_BUTTON_HLABEL_WIDTH_DEF, GUI_BUTTON_HLABEL_HEIGHT_DEF
	);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(ASCIIChartDlgOKCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	gtk_accel_group_add(
	    accelgrp, GDK_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	GUIButtonLabelUnderline(w, GDK_o);
	gtk_widget_show(w);


	ASCIIChartDlgUpdateMenus(d);


	return(d);
}

/*
 *	Updates the ASCII Chart Dialog's widgets to reflect current
 *	values.
 */
void ASCIIChartDlgUpdateMenus(ascii_chart_dlg_struct *d)
{
	if(d == NULL)
	    return;
}

/*
 *	Checks if the ASCII Chart Dialog is mapped.
 */
gboolean ASCIIChartDlgIsMapped(ascii_chart_dlg_struct *d)
{
	GtkWidget *w = (d != NULL) ? d->toplevel : NULL;
	return((w != NULL) ? GTK_WIDGET_MAPPED(w) : FALSE);
}

/*
 *	Maps the ASCII Chart Dialog.
 */
void ASCIIChartDlgMap(ascii_chart_dlg_struct *d)
{
	GtkWidget *w = (d != NULL) ? d->toplevel : NULL;
	if(w == NULL)
	    return;

	gtk_widget_show_raise(w);

	/* Grab focus and default on the OK button */
	w = d->ok_btn;
	if(w != NULL)
	{
	    gtk_widget_grab_focus(w);
	    gtk_widget_grab_default(w);
	}
}

/*
 *	Unmap the ASCII Chart Dialog.
 */
void ASCIIChartDlgUnmap(ascii_chart_dlg_struct *d)
{
	GtkWidget *w = (d != NULL) ? d->toplevel : NULL;
	if(w == NULL)
	    return;

	gtk_widget_hide(w);
}

/*
 *	Deletes the ASCII Chart Dialog.
 */
void ASCIIChartDlgDelete(ascii_chart_dlg_struct *d)
{
	if(d == NULL)
	    return;

	GTK_WIDGET_DESTROY(d->ok_btn);
	GTK_WIDGET_DESTROY(d->main_vbox);

	gtk_window_set_modal(GTK_WINDOW(d->toplevel), FALSE);
	gtk_window_set_transient_for(GTK_WINDOW(d->toplevel), NULL);
	GTK_WIDGET_DESTROY(d->toplevel);

	GTK_ACCEL_GROUP_UNREF(d->accelgrp);

	g_free(d);
}
