/*
 *  dialog.c:		Info or warning dialog windows, option menu	
 * 
 *  Written by:		Ullrich Hafner
 *		
 *  Copyright (C) 1998 Ullrich Hafner <hafner@bigfoot.de>
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
 */

/*
 *  $Date: 1999/12/03 15:34:23 $
 *  $Author: hafner $
 *  $Revision: 1.25 $
 *  $State: Exp $
 */

#include "config.h"

#include <gtk/gtk.h>
#include "proplist_t.h"

#include "dialog.h"
#include "misc.h"
#include "icons.h"
#include "dialog.h"

#include "error.h"

static void
vdialog (dialog_e type, const char *close_text, const char *ok_text,
	 void (*ok_function) (GtkWidget *, gpointer),
	 gpointer dataptr_ok_function, const char *format, va_list args);

/*******************************************************************************

				public code
  
*******************************************************************************/

void
dialog_popup (dialog_e type, void (*ok_function) (GtkWidget *, gpointer),
	      gpointer dataptr_ok_function, const char *format, ...)
/*
 *  Popup dialog to display an info, question, warning or error message
 *  with printf style syntax of 'format'.
 *  Message 'type' must be one of DIALOG_INFO, DIALOG_QUESTION,
 *  DIALOG_WARNING, DIALOG_ERROR.
 *  If 'ok_function' is not NULL then 'ok_function' is called in case
 *    user activates 'OK' button (which is labeled by 'ok_text').
 *    'dataptr_ok_function' argument is passed to 'ok_function'.
 *    A 'Cancel' button (which is labeled by 'close_text') is also shown.
 *  Otherwise only the 'Cancel' button is shown.
 *
 *  No return value.
 */
{
   va_list args;
   va_start (args, format);
   
   if (ok_function)
      vdialog (type, _("No"), _("Yes"), ok_function, dataptr_ok_function,
	       format, args);
   else
      vdialog (type, _("Close"), NULL, ok_function, dataptr_ok_function,
	       format, args);

   va_end (args);
}

void
dialog (dialog_e type, const char *close_text, const char *ok_text,
	void (*ok_function) (GtkWidget *, gpointer),
	gpointer dataptr_ok_function, const char *format, ...)
{
   va_list args;

   va_start (args, format);
   
   vdialog (type, close_text, ok_text, ok_function, dataptr_ok_function,
	    format, args);

   va_end (args);
}

static void
vdialog (dialog_e type, const char *close_text, const char *ok_text,
	 void (*ok_function) (GtkWidget *, gpointer),
	 gpointer dataptr_ok_function, const char *format, va_list args)
/*
 *  Popup dialog to display an info, question, warning or error message
 *  with printf style syntax of 'format'.
 *  Message 'type' must be one of DIALOG_INFO, DIALOG_QUESTION,
 *  DIALOG_WARNING, DIALOG_ERROR.
 *  If 'ok_function' is not NULL then 'ok_function' is called in case
 *    user activates 'OK' button (which is labeled by 'ok_text').
 *    'dataptr_ok_function' argument is passed to 'ok_function'.
 *    A 'Cancel' button (which is labeled by 'close_text') is also shown.
 *  Otherwise only the 'Cancel' button is shown.
 *
 *  No return value.
 */
{
   GtkWidget *hbox;
   GtkWidget *window, *button;
   char	     *window_title[] = {N_("Info"), N_("Question"),
				N_("Warning"), N_("Error")};
   xpms_e    window_icon[] = {P_INFO, P_QUESTION, P_WARNING, P_ERROR};
   
   window = gtk_dialog_new ();
   gtk_window_set_title (GTK_WINDOW (window), _(window_title [type]));
   gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
   gtk_widget_realize (window);

   hbox = gtk_hbox_new (FALSE, 5);
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
		       FALSE, FALSE, 0);
   gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
   
   gtk_box_pack_start (GTK_BOX (hbox),
		       gtk_pixmap_new (p_array [window_icon [type]].pixmap,
				       p_array [window_icon [type]].mask),
		       TRUE, FALSE, 5);
   
   {
      char *tmp = g_strdup_vprintf (format, args);
      
      gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (tmp), TRUE, TRUE, 5);
      Free (tmp);
   }

   if (ok_function && ok_text)
      button = gtk_button_new_with_label (ok_text);
   else
      button = gtk_button_new_with_label (close_text);
   
   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button,
		       TRUE, TRUE, 10);
   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
   gtk_widget_grab_default (button);

   gtk_signal_connect (GTK_OBJECT (window), "delete_event",
		       GTK_SIGNAL_FUNC (delete_button), button);

   if (ok_function)
   {
      gtk_signal_connect (GTK_OBJECT (button), "clicked",
			  GTK_SIGNAL_FUNC (ok_function), dataptr_ok_function);
      if (ok_text)
      {
	 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
				    (GtkSignalFunc) gtk_widget_destroy,
				    GTK_OBJECT (window));
	 button = gtk_button_new_with_label (close_text);
	 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button,
			     TRUE, TRUE, 10);
      }
   }
   gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
			      (GtkSignalFunc) gtk_widget_destroy,
			      GTK_OBJECT (window));

   gtk_widget_show_all (window);
}

GtkWidget *
generate_option_menu (const char *description,
		      GtkTooltips *tooltips, const char *info,
		      const char **entry, const char *current,
		      proplist_t text,
		      void (*callback) (GtkWidget *, gpointer),
		      gpointer callback_data)
/*
 *  Generate an option menu of all available text strings given in NULL
 *  terminated array 'entry'. Optional 'description' is prepended if not NULL.
 *  'current' is the string of the default option.
 *  'callback' function is called if user changes options,
 *  'callback_data' argument is passed to 'callback'.
 *
 *  Return value:
 *	container widget containing the option menu
 */
{
   GtkWidget	*hbox = NULL;
   GtkWidget	*menu;
   GtkWidget	*menu_item;
   GtkWidget	*option_menu;
   const char	**ptr;
   
   option_menu = gtk_option_menu_new ();
   menu = gtk_menu_new ();

   if (description)
   {
      hbox = gtk_hbox_new (FALSE, 5);
      gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (description),
			  FALSE, FALSE, 5);
      gtk_widget_show_all (hbox);
   }

   for (ptr = entry; *ptr; ptr++)
   {
      if (text && WMIsPLArray (text))
      {
	 char *label = D_(WMGetFromPLString (WMGetFromPLArray (text, ptr - entry)));
	 menu_item = gtk_menu_item_new_with_label (label);
      }
      else
	 menu_item = gtk_menu_item_new_with_label (*ptr);
      if (callback)
	 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
			     GTK_SIGNAL_FUNC (callback), callback_data);
      gtk_object_set_user_data (GTK_OBJECT (menu_item), (gpointer) *ptr);
      gtk_menu_append (GTK_MENU (menu), menu_item);
      gtk_widget_show (menu_item);
   }
   gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
   set_option_menu_default (GTK_OPTION_MENU (option_menu), entry, current);
   
   gtk_widget_show (option_menu);
   if (info)
      gtk_tooltips_set_tip (tooltips, option_menu, info, NULL);  

   if (description)
   {
      gtk_box_pack_start (GTK_BOX (hbox), option_menu, FALSE, FALSE, 5);
      return hbox;
   }
   else
      return option_menu;
}

void
set_option_menu_default (GtkOptionMenu *menu, const char **list,
			 const char *value)
{
   const char **ptr;
   
   for (ptr = list; *ptr; ptr++)
      if (strcaseeq (value, *ptr))
      {
	 gtk_option_menu_set_history (GTK_OPTION_MENU (menu), ptr - list);
	 break;
      }
}

gint
progress_timer (gpointer data)
{
  gfloat	new_val;
  GtkAdjustment *adj;

  adj = GTK_PROGRESS (data)->adjustment;

  new_val = adj->value + 1;
  if (new_val > adj->upper)
    new_val = adj->lower;

  gtk_progress_set_value (GTK_PROGRESS (data), new_val);

  return TRUE;
}

gint
delete_button (GtkWidget *widget, GdkEventAny  *event, gpointer ptr)
{
   gtk_signal_emit_by_name (GTK_OBJECT (ptr), "clicked");

   return TRUE;
}

