/* PureAdmin
 * Copyright (C) 2003 Isak Savo
 *
 *  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-1307, USA.
 */

/*
 * Functions for displaying help in the application.
 *
 * Copyright (C) 2003 Isak Savo
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <errno.h>

#include "binreloc.h"
#include "gui_helper.h"
#include "globals.h"
#include "helper.h"
#include "helpview.h"

static gulong hlp_menu_changed_id = 0;

static const gchar *nodes[NUM_HLP_ITEMS][2] =
{
	/* filename (w/o .txt extension) : Human readable name (w/ mnemonic) */
	{"index", N_("Inde_x")},
	{"", ""}, /* Separator */
	{"introduction", N_("_Introduction")},
	{"main_window", N_("_Main Window")},
	{"user_manager", N_("_User Manager")},
	{"preferences", N_("_Preferences")},
};

/* void hlp_create_helpview (void); */
/* void hlp_select_node (hlp_items_t node); */
/* void menu_callback (GtkOptionMenu *menu, gpointer user_data); */
/* void hlp_hide (GtkButton *btn, gpointer user_data); */
/* void hlp_select_menuitem (hlp_items_t node); */

typedef struct _helpview {
  GtkWidget *win;
  GtkWidget *text;
  GtkWidget *menu;
  
  gchar *cur_node;
} HelpView_t;

static HelpView_t *hw = NULL;


static
void hlp_select_menuitem (hlp_items_t node)
{
	g_signal_handler_block (hw->menu, hlp_menu_changed_id);
	gtk_option_menu_set_history (GTK_OPTION_MENU (hw->menu), node);
	g_signal_handler_unblock (hw->menu, hlp_menu_changed_id);
   
	g_signal_emit_by_name (hw->menu, "changed", hw->menu, NULL);
}

static
void hlp_select_node (hlp_items_t node)
{
	GtkTextBuffer *buf;
	GtkTextIter iter;
	gchar *filename, line[LINE_MAX];
	FILE *fl;

	if (hw->cur_node && strcmp (hw->cur_node, nodes[node][0]) == 0)
		return;
  
	
	filename = g_strconcat(docdir, G_DIR_SEPARATOR_S, nodes[node][0], ".txt", NULL);
	//strdup_printf ("%s/%s.txt", PUR_DOC_DIR, nodes[node][0]);
	pur_log_dbg ("Opening helpfile: %s", filename);
  
	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
	{
		g_free (filename);
		filename = g_strconcat(docdir, G_DIR_SEPARATOR_S, nodes[0][0], ".txt", NULL);
		//g_strdup_printf ("%s/%s.txt", PUR_DOC_DIR, nodes[0][0]);
		pur_log_wrn ("Helpfile not found, opening %s", filename);
		if (!g_file_test (filename, G_FILE_TEST_EXISTS))
		{
			pur_log_wrn ("Helpfile %s not found either, aborting!!", filename);
			g_free (filename);
			return;
		}
		/* Force change of GUI-menu. This will trigger appropriate signals.. */
		hlp_select_menuitem (0);
		return;
	}
	buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (hw->text));
	gtk_text_buffer_set_text (buf, "", -1);
	gtk_text_buffer_get_iter_at_offset (buf, &iter, 0);

	if ((fl = fopen (filename, "r")) == NULL)
	{
		pur_log_wrn ("Unable to open helpfile: %s", strerror(errno));
		g_free (filename);
		return;
	}
	while (fgets (line, LINE_MAX, fl))
	{
		gtk_text_buffer_insert (buf, &iter, line, -1);
	}
	fclose (fl);
	if (hw->cur_node)
		g_free (hw->cur_node);
	hw->cur_node = g_strdup (nodes[node][0]);
	g_free (filename);
}


static
void menu_callback (GtkOptionMenu *menu, gpointer user_data)
{
	gint i;
   
	i = gtk_option_menu_get_history (menu);
	if (i != -1)
		hlp_select_node (i);
}

static
void hlp_hide (GtkButton *btn, gpointer user_data)
{
	gtk_widget_hide (hw->win);
}

static
GtkWidget *hlp_fill_menu (void)
{
	GtkWidget *menu, *img, *sep, *node;
	gint i;

	menu = gtk_menu_new ();
   
	node = gtk_image_menu_item_new_with_mnemonic (_(nodes[HLP_ITEM_INDEX][1]));
	gtk_widget_show (node);
	gtk_container_add (GTK_CONTAINER (menu), node);
   
	img = gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU);
	gtk_widget_show (img);
	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (node), img);
   
	sep = gtk_menu_item_new ();
	gtk_widget_show (sep);
	gtk_container_add (GTK_CONTAINER (menu), sep);
	gtk_widget_set_sensitive (sep, FALSE);
   
	for (i = 2; i < NUM_HLP_ITEMS; i++)
	{
		node = gtk_menu_item_new_with_mnemonic (_(nodes[i][1]));
		gtk_widget_show (node);
		gtk_container_add (GTK_CONTAINER (menu), node);
	}

	return menu;
}

/* FIXME: This should be done in Glade instead */
static
void hlp_create_helpview (void)
{
	GtkWidget *win;
	GtkWidget *vbox;
	GtkWidget *hbox;
	GtkWidget *lbl;
	GtkWidget *menu;
	GtkWidget *menu_items;
	GtkWidget *scr_win;
	GtkWidget *text;
	GtkWidget *hbuttonbox2;
	GtkWidget *button2;
	GdkPixbuf *icon;
	GtkTextBuffer *buf;
	PangoFontDescription *font_desc;

	win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title (GTK_WINDOW (win), _("PureAdmin: Help"));
	gtk_widget_set_size_request (win, 550, 600);
	vbox = gtk_vbox_new (FALSE, 4);
	gtk_widget_show (vbox);
	gtk_container_add (GTK_CONTAINER (win), vbox);
   
	icon = gtk_widget_render_icon (GTK_WIDGET (win), GTK_STOCK_HELP,
				       GTK_ICON_SIZE_MENU,
				       NULL);
	gtk_window_set_icon (GTK_WINDOW (win), icon);
	gdk_pixbuf_unref (icon);

	hbox = gtk_hbox_new (FALSE, 12);
	gtk_widget_show (hbox);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
   
	lbl = gtk_label_new (_("Select chapter:"));
	gtk_widget_show (lbl);
	gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 0);
	gtk_label_set_justify (GTK_LABEL (lbl), GTK_JUSTIFY_LEFT);
   
	menu = gtk_option_menu_new ();
	gtk_widget_show (menu);
	gtk_box_pack_start (GTK_BOX (hbox), menu, FALSE, FALSE, 0);
   
	menu_items = hlp_fill_menu ();
	gtk_option_menu_set_menu (GTK_OPTION_MENU (menu), menu_items);
	hlp_menu_changed_id = g_signal_connect ((gpointer) menu, "changed",
						G_CALLBACK (menu_callback), NULL);

	scr_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_show (scr_win);
	gtk_box_pack_start (GTK_BOX (vbox), scr_win, TRUE, TRUE, 0);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scr_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	text = gtk_text_view_new ();
	gtk_widget_show (text);
	gtk_container_add (GTK_CONTAINER (scr_win), text);
	gtk_text_view_set_editable (GTK_TEXT_VIEW (text), FALSE);
	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text), GTK_WRAP_WORD);
	gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text), FALSE);
	gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text), 5);

	buf = gtk_text_buffer_new (NULL);
	/* Change default font throughout the widget */
	font_desc = pango_font_description_from_string ("Monospace");
	gtk_widget_modify_font (text, font_desc);
	pango_font_description_free (font_desc);

	gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), buf);
   
	hbuttonbox2 = gtk_hbutton_box_new ();
	gtk_widget_show (hbuttonbox2);
	gtk_box_pack_start (GTK_BOX (vbox), hbuttonbox2, FALSE, FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox2), 6);
	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_END);

	button2 = gtk_button_new_from_stock ("gtk-close");
	gtk_widget_show (button2);
	gtk_container_add (GTK_CONTAINER (hbuttonbox2), button2);
	GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
   
	g_signal_connect ((gpointer) button2, "clicked",
			  G_CALLBACK (hlp_hide), NULL);
	g_signal_connect ((gpointer) win, "delete-event",
			  G_CALLBACK (gtk_widget_hide), NULL);
	hw = g_new0 (HelpView_t, 1);
	hw->win = win;
	hw->text = text;
	hw->menu = menu;
}

/** GLOBAL FUNCTIONS **/

/* hlp_terminate: Destroys the help window and frees any allocated
 *		  resources.
 */
void hlp_terminate (void)
{
	if (hw)
	{
		gtk_widget_destroy (hw->win);
		if (hw->cur_node)
			g_free (hw->cur_node);
	}
	g_free (hw);
	hw = NULL;
}

/* hlp_show_help: Shows the help window and displays the selected node.
 *
 * Arguments: node	The help node to show
 *
 */
void hlp_show_help (hlp_items_t node)
{
	pur_log_dbg ("Docdir: %s", docdir);
	if (!g_file_test (docdir, G_FILE_TEST_EXISTS))
	{
		pur_log_wrn ("Docdir %s doesn't exist!", docdir);
		gui_display_msgdialog (_("Help not found"), 
				       _("PureAdmin could not find the helpfiles."
					 "Try reinstalling PureAdmin to see if that solves the problem."), 
				       MSGDLG_TYPE_ERROR, MW("main_window"));
		return;
	}

	if (!hw)
		hlp_create_helpview ();
	
	pur_log_dbg ("Showing help, node %d", node);
	hlp_select_menuitem (node);
	gtk_widget_show (hw->win);
}


syntax highlighted by Code2HTML, v. 0.9.1