/*
 *  $Id: gtk_util.c,v 1.1.1.1 1999/04/26 22:44:54 route Exp $
 *
 *  Firewalk
 *  gtk code
 *  gtk_util.c - gtk interface routines
 *
 *  Copyright (c) 1999 Mike D. Schiffman <mike@infonexus.com>
 *  Copyright (c) 1998 Mike D. Schiffman <mds@es2.net>
 *  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#if (HAVE_CONFIG_H)
#include "./config.h"
#endif
#include "./main.h"
#include "./firepack.h"
#include "./gtk_main.h"
#include "./gtk_util.h"
#include "./gtk_cb.h"
#include "./gtk_pack.h"
#include "./firewalk.xpm"

/*
 *  This code is heavily commented for the benefit of the programmer who
 *  wants to learn GTK.  Note that there is no error checking done on any
 *  GTK calls.  None of the GTK code I've looked at (tutorial example code,
 *  GNU info documentation sample code, the example code that came with the
 *  library, and finally, several GTK-based applications) check for errors.
 *  I'm not sure why people don't check the return values of gtk_* calls,
 *  but they don't.  So I don't.
 */


void
gtk_text_box(gint type, gchar *msg_format, ...)
{
    GtkWidget *main_window, *main_vbox, *main_hbox, *pm, *msg, *button_box;
    GtkWidget *ok_btn;
    GdkPixmap *pixmap;
    GdkBitmap *mask;
    GtkStyle  *style;
    GdkColormap *cmap;
    va_list ap;
    gchar message[FSD_MAX_MSG_LEN];
    gchar **icon;

    /*
     *  Get main textbox window, set the borderwidth and set the icon to use.
     */
    main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_container_border_width(GTK_CONTAINER(main_window), BORDER_WIDTH_1);
    icon = firewalk_small_xpm;

    /*
     *  Set textbox title.
     */
    gtk_window_set_title(GTK_WINDOW(main_window), (type == FSD_TYPE_ERR) ?
        "Firewalk: Error" : "Firewalk: Information");

    /*
     *  Create a vertical box to pack widgets into.
     */
    main_vbox = gtk_vbox_new(FALSE, BORDER_WIDTH_2);
    gtk_container_border_width(GTK_CONTAINER(main_vbox), BORDER_WIDTH_2);
    gtk_container_add(GTK_CONTAINER(main_window), main_vbox);

    /*
     *  Create a horizontal box to pack text and icon into.
     */
    main_hbox = gtk_hbox_new(FALSE, 10);

    /*
     *  Pack the horizontal box into the vertical box.
     */
    gtk_container_add(GTK_CONTAINER(main_vbox), main_hbox);

    /*
     *  Icon pixmap widget stuff.
     */
    style = gtk_widget_get_style(main_window);
    cmap  = gdk_colormap_get_system();
    pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL, cmap,  &mask,
        &style->bg[GTK_STATE_NORMAL], icon);

    pm = gtk_pixmap_new(pixmap, mask);
    gtk_misc_set_alignment(GTK_MISC(pm), 0.5, 0.0);
    gtk_container_add(GTK_CONTAINER(main_hbox), pm);

    /*
     *  Load our vararg list into the message string.
     */
    va_start(ap, msg_format);
    vsnprintf(message, FSD_MAX_MSG_LEN, msg_format, ap);

    /*
     *  Text message widget.
     */
    msg = gtk_label_new(message);
    gtk_label_set_justify(GTK_LABEL(msg), GTK_JUSTIFY_FILL);
    gtk_container_add(GTK_CONTAINER(main_hbox), msg);

    /*
     *  Do the button.
     */
    button_box = gtk_hbutton_box_new();
    gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);
    gtk_container_add(GTK_CONTAINER(main_vbox), button_box);

    ok_btn = gtk_button_new_with_label ("OK");
    gtk_signal_connect_object(GTK_OBJECT(ok_btn), "clicked",
        GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(main_window));
    gtk_container_add(GTK_CONTAINER(button_box), ok_btn);
    GTK_WIDGET_SET_FLAGS(ok_btn, GTK_CAN_DEFAULT);
    gtk_widget_grab_default(ok_btn);

    /*
     *  Rather than individual calls to gtk_widget_show, we can make one
     *  call here and display all the widgets packed into the specified widget.
     */
    gtk_widget_show_all(main_window);
}


void
gtk_do_spin_button(GtkAdjustment *adj, GtkWidget **sb, GtkWidget **label,
    u_char *label_text)
{
    *sb = gtk_spin_button_new(adj, 0, 0);
    gtk_widget_set_usize(GTK_WIDGET(*sb), 60, 20); 
    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(*sb), TRUE);
    gtk_spin_button_set_shadow_type(GTK_SPIN_BUTTON(*sb), GTK_SHADOW_OUT);
    *label = gtk_label_new(label_text);
}


void
gtk_do_progress_bar_update(u_short port_current)
{
    gfloat pval;

    if (port_current > 0)
    {
        pval = (gfloat) port_current / (gfloat) fp->ports_total;
        gtk_progress_set_percentage(GTK_PROGRESS(gp->p_bar), pval);
        while (gtk_events_pending())
        {
            gtk_main_iteration();
        }
    }
}


void
gtk_do_file_box()
{
    GtkWidget *file_sel;

    file_sel = gtk_file_selection_new("Firewalk output file");

    gtk_signal_connect_object(GTK_OBJECT(file_sel), "destroy",
        GTK_SIGNAL_FUNC(gtk_quit_fsb_cb), GTK_OBJECT(file_sel));

    /*
     *  Connect the ok_button to gtk_ok_fsb_cb function.
     */
    gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
        "clicked", GTK_SIGNAL_FUNC(gtk_ok_fsb_cb), GTK_OBJECT(file_sel));

    /*
     *  Connect the cancel_button to destroy the widget.
     */
    gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->cancel_button),
        "clicked", GTK_SIGNAL_FUNC(gtk_quit_fsb_cb), GTK_OBJECT(file_sel));

    /*
     *  Lets set the filename, as if this were a save dialog, and we are
     *  giving a default filename
     */
    if (fp->output_file == NULL)
    {
        fp->output_file = FW_OUTPUT_FILENAME;
    }
    gtk_file_selection_set_filename(GTK_FILE_SELECTION(file_sel),
        fp->output_file);

    gtk_widget_show_all(file_sel);
}


/* EOF */
