#include <gtk/gtk.h>
#include <gnome.h>
#include <glade/glade.h>
#include <string.h>
#include "tsl.h"
#include "brl.h"
extern char *booknamestr[]; /* should be in brl.h */

/* These are needed for the itemfactories */

int book=0, chap=0, oldbook=0, oldchap=0, jumpsection=0, jumpbook=0,jumpchap=0;
GladeXML *xml;
GdkFont *prevfont, *thefont = NULL;
GtkWidget *sectopt, *section_menu, *section_item [9];
GtkWidget *bookopt, *book_menu, *book_item [12];
int start_book [] = { 0, 5, 17, 22, 27, 39, 44, 53, 58, 66 };

#define CSIZE 10000 /* Size of the chapter buffer. */
#define min(a,b) (((a) > (b)) ? (b) : (a))

/* General purpose display engine called by everything else */
void display_current()
{
  GtkWidget *bibless, *thebar;
  gchar thestatus [80], chapbuff [CSIZE];
  int verse, cbuffpointer, len;

  /* Bounds check and fit */
  if (chap < 0)
    {
      if (book <= 0)
	book = chap = 0;
      else
	{
	  book--;
	  chap = start_chapter [book+1] - start_chapter [book] -1;
	}
    }
  else if (chap >= start_chapter [book+1] - start_chapter [book])
    {
      if (book >= REV)
	chap = start_chapter [(book=REV) +1] - start_chapter [REV] -1;
      else
	{
	  book++;
	  chap = 0;
	}
    }
  if (book < 0)
    book = 0;
  if (book > REV)
    book = REV;

  /* Get new chapter one verse at a time and update less window */
  bibless = glade_xml_get_widget(xml, "less1");

  cbuffpointer = 0;
  for (verse = start_verse [start_chapter [book] + chap + 1] + 1;
       verse < start_verse [start_chapter [book] + chap + 2] + 1;
       verse++)
    {
      len = tsl_gettext (verse, 1, chapbuff + cbuffpointer, 550);
      cbuffpointer = strlen (chapbuff);
    }

  if (thefont)
    gnome_less_set_font (GNOME_LESS (bibless), thefont);
  else
    gnome_less_set_font (GNOME_LESS (bibless), prevfont);

  gnome_less_show_string (GNOME_LESS (bibless), chapbuff);

  /* Turn on/off toolbar buttons */
  /* (Put code in here to grey out the prev buttons in Genesis 1, etc.) */

  /* Update status bar */
  thebar = glade_xml_get_widget(xml, "appbar1");
  sprintf (thestatus, "%s %d [%s]", booknamestr [book],
	   chap + 1, brl_textname);
  gnome_appbar_set_default (GNOME_APPBAR (thebar), thestatus);
  gnome_appbar_set_progress (GNOME_APPBAR (thebar),
			     (gfloat) start_verse [start_chapter[book] +chap] /
			     start_verse [start_chapter [REV +1] -1]);

  return;
}

/* Toolbar button signal callbacks */
void on_nextbook_clicked (GtkWidget *widget, gpointer user_data) {
  oldbook = ++book; chap = 0; display_current(); }

void on_prevbook_clicked (GtkWidget *widget, gpointer user_data) {
  oldbook = --book; chap = 0; display_current(); }

void on_nextchap_clicked (GtkWidget *widget, gpointer user_data) {
  oldchap = ++chap; display_current(); }

void on_prevchap_clicked (GtkWidget *widget, gpointer user_data) {
  oldchap = --chap; display_current(); }

/* Jump to passage menu item and spinner signal callbacks */
void on_chap_spinbutton_changed (GtkWidget *widget, gpointer user_data)
{
  if (widget)
    jumpchap = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)) -1;
  else
    {
      widget = glade_xml_get_widget(xml, "chap_spinbutton");
      gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gfloat)jumpchap+1);
    }
}

void change_book (GtkWidget *widget, gpointer user_data)
{
  static int prevbook = -1;
  jumpbook = GPOINTER_TO_INT (widget);
  if (jumpbook == prevbook)
    return;

  gtk_option_menu_set_history (GTK_OPTION_MENU (bookopt),
			       jumpbook - start_book [jumpsection]);
  on_chap_spinbutton_changed (NULL, GINT_TO_POINTER (jumpchap));
}

void change_section (GtkWidget *widget, gpointer user_data)
{
  int i;
  static int prevsection = -1;
  jumpsection = GPOINTER_TO_INT (widget);
  if (jumpsection == prevsection)
    return;

  prevsection = jumpsection;
  gtk_option_menu_set_history (GTK_OPTION_MENU (sectopt), jumpsection);

  /* Assume this frees the old menu and its items (IS_... does return zero) */
  gtk_option_menu_remove_menu (GTK_OPTION_MENU (bookopt));
  /* Make a new book menu for this section */
  book_menu = gtk_menu_new ();
  for (i=0; i< start_book [jumpsection+1] - start_book [jumpsection]; i++)
    {
      book_item [i] = gtk_menu_item_new_with_label
	(booknamestr [start_book [jumpsection] + i]);
      gtk_menu_append (GTK_MENU (book_menu), book_item [i]);
      gtk_signal_connect_object (GTK_OBJECT (book_item [i]), "activate",
				 GTK_SIGNAL_FUNC (change_book),
				 GINT_TO_POINTER (start_book[jumpsection]+i));
      gtk_widget_show (book_item [i]);
    }
  gtk_option_menu_set_menu (GTK_OPTION_MENU (bookopt), book_menu);
  gtk_widget_show (book_menu);

  change_book (GINT_TO_POINTER (jumpbook), NULL);
}

void on_jump_apply_button_clicked (GtkWidget *widget, gpointer user_data) {
  book = jumpbook; chap = jumpchap; display_current (); }

void on_jump_ok_button_clicked (GtkWidget *jumpdialog, gpointer user_data) {
  oldbook = book = jumpbook; oldchap = chap = jumpchap; display_current ();
  gtk_widget_hide (jumpdialog); }

void on_jump_cancel_button_clicked (GtkWidget *jumpdialog, gpointer user_data){
  book = oldbook; chap = oldchap; display_current();
  gtk_widget_hide (jumpdialog); }

/* Font selection button signal callbacks */
void on_font_apply_button_clicked (GtkWidget *fontpick, gpointer user_data) {
  thefont = gnome_font_picker_get_font (GNOME_FONT_PICKER (fontpick));
  display_current(); }  

void on_font_ok_button_clicked (GtkWidget *fontpick, gpointer user_data) {
  on_font_apply_button_clicked (fontpick, user_data); prevfont = thefont;
  gtk_widget_hide (glade_xml_get_widget(xml, "font_dialog")); }

void on_font_cancel_button_clicked (GtkWidget *fontdialog, gpointer user_data){
  thefont = NULL; display_current(); gtk_widget_hide (fontdialog); }

/* Menu signal callbacks */
void on_jump_clicked (GtkWidget *widget, gpointer user_data)
{
  /* Set oldbook, oldchap, jumpsection */
  for (jumpsection=0; start_book [jumpsection+1] < book; jumpsection++) ;
  oldbook = jumpbook = book;
  oldbook = jumpchap = chap;

  /* Update section and book option menus, and chapter spin button */
  change_section (GINT_TO_POINTER (jumpsection), NULL);

  gtk_widget_show (glade_xml_get_widget(xml, "jump_dialog"));
}

void on_font1_activate (GtkWidget *widget, gpointer user_data) {
  gtk_widget_show (glade_xml_get_widget(xml, "font_dialog")); }

void on_about1_activate (GtkWidget *widget, gpointer user_data) {
  gtk_widget_show (glade_xml_get_widget(xml, "about1")); }

/* And of course, main() itself */
int main(int argc, char *argv[]) {
  int i;
  char buff[200], *section_name [] =
  { "Torah", "History", "Wisdom", "Major Prophets", "Minor Prophets",
    "Gospels & Acts", "Letters to Churches", "Pastoral Letters",
    "General Letters" };

  /* Basic init stuff */
  gnome_init ("Gnome Bible Browser", "0.1", argc, argv);
  glade_gnome_init();
  brl_init ("bible.data", "/usr/lib", 1024);

  /* load the interface and display initial window */
  xml = glade_xml_new("gnome-bible.glade", NULL);

  /* connect the signals in the interface */
  glade_xml_signal_autoconnect(xml);

  /* Initialize optionmenus and section's contained menu */
  sectopt = glade_xml_get_widget (xml, "section_optionmenu");
  bookopt = glade_xml_get_widget (xml, "book_optionmenu");
  gtk_option_menu_remove_menu (GTK_OPTION_MENU (sectopt));

  section_menu = gtk_menu_new ();

  /* Fill the section menu "by hand" :-) */
  for (i=0; i<9; i++)
    {
      section_item [i] = gtk_menu_item_new_with_label (section_name [i]);
      gtk_menu_append (GTK_MENU (section_menu), section_item [i]);
      gtk_signal_connect_object (GTK_OBJECT (section_item [i]), "activate",
				 GTK_SIGNAL_FUNC (change_section),
				 GINT_TO_POINTER (i));
    }

  /* Show all the widgets */
  for (i=0; i<9; i++)
    gtk_widget_show (section_item [i]);
  gtk_option_menu_set_menu (GTK_OPTION_MENU (sectopt), section_menu);
  gtk_widget_show (section_menu);
  gtk_widget_show (sectopt);

  /* Set the default font; FIXME: this should be the gtk+ theme default */
  prevfont = gdk_font_load
    ("-adobe-times-medium-r-normal-*-14-*-*-*-p-*-iso8859-1");

  /* Start the less window with the default book, chapter and font */
  display_current();

  /* start the event loop */
  gtk_main();

  brl_close();
  return 0;
}
