#include <strings.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "bwindow.h"
#include "bwindow_callbacks.h"
#include "express.h"
#include "browser.h"
#include "menus.h"
#include "alert.h"
#include "options.h"
#include "url.h"
#include "open_url.h"


/*gint num_bwindows=0;*/

guint bwindow_get_type(void);
static void bwindow_class_init (BWindowClass *class);
static void bwindow_init (BWindow *b);
GtkWidget* bwindow_new ();
void bwindow_clear (BWindow *b);
void urlentry_changed(GtkWidget *widget, GdkEventKey *event, gpointer data);
void browser_url_changed(BWindow *bwindow);
void back_button_pressed(GtkWidget *widget, gpointer data);
void forward_button_pressed(GtkWidget *widget, gpointer data);
void home_button_pressed(GtkWidget *widget, gpointer data);
void reload_button_pressed(GtkWidget *widget, gpointer data);
gint delete_event(GtkWidget *widget, gpointer data);
void destroy(GtkWidget *widget, gpointer data);

guint
bwindow_get_type ()
{
  static guint b_type = 0;

  if (!b_type)
    {
      GtkTypeInfo b_info =
      {
        "BWindow",
        sizeof (BWindow),
        sizeof (BWindowClass),
        (GtkClassInitFunc) bwindow_class_init,
        (GtkObjectInitFunc) bwindow_init,
        (GtkArgSetFunc) NULL,
        (GtkArgGetFunc) NULL,
      };

      b_type = gtk_type_unique (gtk_window_get_type (), &b_info);
    }

  return b_type;
}
enum {
  URL_CHANGED_SIGNAL,
  LAST_SIGNAL
};

/*static gint bwindow_signals[LAST_SIGNAL] = { 0 };*/

static void
bwindow_class_init (BWindowClass *class)
{
  GtkObjectClass *object_class;

  object_class = (GtkObjectClass*) class;
  
#if 0
  bwindow_signals[URL_CHANGED_SIGNAL] = gtk_signal_new ("url_changed",
                                         GTK_RUN_FIRST,
                                         object_class->type,
                                         GTK_SIGNAL_OFFSET (BWindowClass, bwindow),
                                         gtk_signal_default_marshaller, GTK_ARG_NONE, 0);


  gtk_object_class_add_signals (object_class, bwindow_signals, LAST_SIGNAL);
#endif

  class->bwindow = NULL;
}

GtkWidget *
new_pixmap(char *filename, GtkWidget *window)
{
  GtkWidget *wpixmap;
  GdkPixmap *pixmap;
  GdkBitmap *mask;

  pixmap=gdk_pixmap_create_from_xpm(window->window, &mask,
    &window->style->bg[GTK_STATE_NORMAL] , filename);
  wpixmap = gtk_pixmap_new(pixmap, mask);
  return wpixmap;
}

static void
bwindow_init (BWindow *bwindow)
{
  GtkWidget *menubar;
  GtkWidget *scrolled_window;
  GtkWidget *vbox;
  GtkWidget *handle_box;
  
/* GtkAcceleratorTable *accel; */

#if 0
  GtkWidget *mule;
  GdkPixmap *pixmap;
  GdkBitmap *mask;
#endif

  GtkStyle *style;

  gtk_window_set_title(GTK_WINDOW(bwindow), "Verge Express");
  
  gtk_signal_connect(GTK_OBJECT(bwindow), "delete_event",
		      GTK_SIGNAL_FUNC(delete_event), NULL);
  
/*
  gtk_signal_connect(GTK_OBJECT(bwindow), "destroy",
		      GTK_SIGNAL_FUNC(destroy), NULL);
*/
  
  /* sets the border width of the window */
  gtk_container_border_width(GTK_CONTAINER(bwindow), 0);

  /* set window policy: allow to grow etc */
  gtk_window_set_policy(GTK_WINDOW(bwindow), FALSE, TRUE, TRUE);
  
  vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(bwindow), vbox);

  gtk_container_enable_resize(GTK_CONTAINER(vbox));

  bwindow->history = NULL;
  bwindow->current = (URL *)g_malloc(sizeof(struct _URL));
  bwindow->current->url[0] = '\0';
  bwindow->current->buf[0] = '\0';
  bwindow->current->src=NULL; bwindow->current->hdr=NULL;

#if 0
  get_main_menu(bwindow, &menubar, &accel);
  gtk_window_add_accelerator_table(GTK_WINDOW(bwindow), accel);
#endif

  menubar = bwindow_get_menu_bar(bwindow);
  gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
  gtk_widget_show(menubar);

/*
  hbox = gtk_hbox_new(FALSE, 2);
  gtk_container_border_width(GTK_CONTAINER(hbox), 2);
  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
*/
  
  handle_box = gtk_handle_box_new();
  gtk_container_enable_resize(GTK_CONTAINER(handle_box));
  gtk_box_pack_start(GTK_BOX(vbox), handle_box, FALSE, FALSE, 0);

  bwindow->tb1 = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_TEXT);
  gtk_container_add(GTK_CONTAINER(handle_box), bwindow->tb1);

  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));

  bwindow->backbutton = gtk_button_new_with_label("Back");
  gtk_signal_connect(GTK_OBJECT(bwindow->backbutton), "clicked",
		     GTK_SIGNAL_FUNC(bwindow_back_callback), bwindow);
/*  gtk_box_pack_start(GTK_BOX(hbox), bwindow->backbutton, TRUE, TRUE, 0);*/
  gtk_toolbar_append_widget(GTK_TOOLBAR(bwindow->tb1), bwindow->backbutton, "");
  gtk_widget_set_sensitive(GTK_WIDGET(bwindow->backbutton), FALSE);
  gtk_widget_show(bwindow->backbutton);
  bwindow->backtooltips = gtk_tooltips_new();
  

  bwindow->forwardbutton = gtk_button_new_with_label("Forward");
  gtk_signal_connect(GTK_OBJECT(bwindow->forwardbutton), "clicked",
		     GTK_SIGNAL_FUNC(bwindow_forward_callback), bwindow);
  /*gtk_box_pack_start(GTK_BOX(hbox), bwindow->forwardbutton, TRUE, TRUE, 0);*/
  gtk_toolbar_append_widget(GTK_TOOLBAR(bwindow->tb1), bwindow->forwardbutton, "");
  gtk_widget_set_sensitive(GTK_WIDGET(bwindow->forwardbutton), FALSE);
  gtk_widget_show(bwindow->forwardbutton);
  bwindow->forwardtooltips = gtk_tooltips_new();

#if 0
  button = gtk_button_new_with_label("Home");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, DEFAULT_HOME_URL);
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(bwindow_home_callback), bwindow);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif

  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Home",
    DEFAULT_HOME_URL, new_pixmap (DEFAULT_HOME_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_home_callback, bwindow);
  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));
  
  
#if 0
  button = gtk_button_new_with_label("Reload");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Reload");
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(bwindow_reload_callback), bwindow);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif

  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Reload",
    "Reload", new_pixmap (DEFAULT_RELOAD_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_reload_callback, bwindow);

  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));
  
#if 0
  button = gtk_button_new_with_label("Edit...");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Edit source with default editor");
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(bwindow_edit_callback), bwindow);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Edit...",
    "Reload", new_pixmap (DEFAULT_RELOAD_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_edit_callback, bwindow);
  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));
  
#if 0
  button = gtk_button_new_with_label("Pipe...");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Pipe source through shell commmand");
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(bwindow_pipe_callback), bwindow);
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Pipe",
    "Pipe source through shell command", new_pixmap (DEFAULT_PIPE_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_pipe_callback, bwindow);

#if SUCK 
  button = gtk_button_new_with_label("Open...");
#if 0
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(load_button_pressed), NULL);
#endif
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
#if 0
  button = gtk_button_new_with_label("Print...");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Print source");
#if 0
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(load_button_pressed), NULL);
#endif
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Print...",
    "Print source", new_pixmap (DEFAULT_PRINT_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_reload_callback, bwindow);
  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));
  
#if 0
  button = gtk_button_new_with_label("Find...");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Find in current page");
#if 0
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(load_button_pressed), NULL);
#endif
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Find...",
    "Find in current page", new_pixmap (DEFAULT_FIND_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_reload_callback, bwindow);
  gtk_toolbar_append_space(GTK_TOOLBAR(bwindow->tb1));
  
#if 0
  button = gtk_button_new_with_label("Stop");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Stop loading immediately");
#if 0
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(load_button_pressed), NULL);
#endif
  gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
  gtk_widget_show(button);
#endif
  
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb1), "Stop",
    "Stop loading immediately", new_pixmap (DEFAULT_STOP_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_reload_callback, bwindow);

  gtk_widget_show(bwindow->tb1);
  gtk_widget_show(handle_box);

  style = gtk_widget_get_style(GTK_WIDGET(bwindow));

#if 0
  pixmap = gdk_pixmap_create_from_xpm_d(window->window,  &mask,
                                        &style->bg[GTK_STATE_NORMAL],
                                        (gchar **)muletiny);

  /* a pixmap widget to contain the pixmap */
  mule = gtk_pixmap_new(pixmap, mask);
  gtk_box_pack_start(GTK_BOX(hbox), mule, TRUE, TRUE, 0);
  gtk_widget_show(mule);
#endif

  /*gtk_widget_show(hbox);*/

  handle_box = gtk_handle_box_new();
  gtk_container_enable_resize(GTK_CONTAINER(handle_box));
  gtk_box_pack_start(GTK_BOX(vbox), handle_box, FALSE, FALSE, 0);

  bwindow->tb2 = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH);

  gtk_container_add(GTK_CONTAINER(handle_box), bwindow->tb2);

  bwindow->urlentry = gtk_entry_new();
  /*gtk_entry_set_text(GTK_ENTRY(bwindow->urlentry), url);*/
  gtk_signal_connect(GTK_OBJECT(bwindow->urlentry), "key_press_event",
                     GTK_SIGNAL_FUNC(urlentry_changed), bwindow);
  /*gtk_box_pack_start(GTK_BOX(handle_box), bwindow->urlentry, TRUE, TRUE, 0);*/
  /*gtk_container_add(GTK_CONTAINER(handle_box), bwindow->urlentry);*/
  gtk_toolbar_append_widget(GTK_TOOLBAR(bwindow->tb2), bwindow->urlentry,
                     "URL");
  gtk_widget_show(bwindow->urlentry);

#if 0
  button = gtk_button_new_with_label("Browse...");
  tooltips = gtk_tooltips_new();
  gtk_tooltips_set_tips(tooltips, button, "Browse local files");
  gtk_signal_connect(GTK_OBJECT(button), "clicked",
		      GTK_SIGNAL_FUNC(bwindow_browse_callback), bwindow);
  /*gtk_box_pack_start(GTK_BOX(handle_box), button, FALSE, TRUE, 0);*/
  gtk_container_add(GTK_CONTAINER(handle_box),button);
  gtk_widget_show(button);
#endif
  gtk_toolbar_append_item(GTK_TOOLBAR(bwindow->tb2), "Browse...",
    "Browse local files", new_pixmap (DEFAULT_OPEN_PIXMAP, GTK_WIDGET(bwindow)),
    (GtkSignalFunc) bwindow_browse_callback, bwindow);

  gtk_widget_show(bwindow->tb2);
  gtk_widget_show(handle_box);

#if 0
  bwindow->hdrtext = gtk_text_new(NULL, NULL);
  gtk_text_set_editable(GTK_TEXT(bwindow->hdrtext), FALSE);
  gtk_box_pack_start(GTK_BOX(vbox), bwindow->hdrtext, FALSE, FALSE, 0);
  gtk_widget_show(bwindow->urlentry);
  gtk_widget_show(bwindow->hdrtext);
#endif

  scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_set_usize(GTK_WIDGET(scrolled_window), WIDTH+23, HEIGHT+23);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, FALSE, FALSE, 0);
  gtk_widget_show(scrolled_window);

  bwindow->browser = browser_new();
  gtk_container_add(GTK_CONTAINER(scrolled_window), bwindow->browser);
  gtk_widget_show(bwindow->browser);
#if 0
  gtk_signal_connect(GTK_OBJECT(bwindow->browser), "url_changed",
                    GTK_SIGNAL_FUNC(browser_url_changed), bwindow);
#endif


  bwindow->status = gtk_label_new("Express Yourself");
  gtk_box_pack_start(GTK_BOX(vbox), bwindow->status, FALSE, TRUE, 0);
  gtk_widget_show(bwindow->status);

  gtk_widget_show(vbox);

  bwindow_set_status(bwindow, "Oh yeah!");

  /*num_bwindows++;*/
}

GtkWidget*
bwindow_new (void)
{
  return GTK_WIDGET ( gtk_type_new (bwindow_get_type ()));
}

void           
bwindow_clear (BWindow *b)
{
#if 0
       gtk_signal_handler_block_by_data (GTK_OBJECT(b->text), b);
       gtk_toggle_text_set_state (GTK_TOGGLE_BUTTON (b->text),
                                    FALSE);
       gtk_signal_handler_unblock_by_data (GTK_OBJECT(b->text), b);
#endif
}

void bwindow_set_status(BWindow *bwindow, char *str)
{
  gtk_label_set(GTK_LABEL(bwindow->status), str);
}

int bwindow_set_url(BWindow *bwindow, char *url)
{
  /*url_ds u;
  url_data loc;*/
  URL *u;

  if(url==NULL) {
    url = DEFAULT_HOME_URL;
  }

  g_print("Setting URL to -->%s<--\n", url);

  if((u=(URL *)open_url(bwindow, url)) != NULL) {
    free(bwindow->current);
    bwindow->current = u;
  } else {
    return FALSE;
  }

  fprintf(stderr, "in bwindow_set_url, just set current->url to %s\n", bwindow->current->url);
  browser_url_changed(bwindow);
#if 0
  /* emit the url_changed signal */
  gtk_signal_emit(GTK_OBJECT(b), browser_signals[URL_CHANGED_SIGNAL]);
}

  if(!browser_set_url(BROWSER(bwindow->browser), url)) {
    sprintf(msg, "Invalid URL: %s", url);
    make_alert(bwindow, msg);
    g_print("Invalid URL: -->%s<--\n", url);
  }
#endif

  g_print("about to browser_display_src()\n");
  browser_display_src(BROWSER(bwindow->browser), bwindow->current->src);

#if 0
  g_print("HDR:\n%s\n", bwindow->current->hdr);

  /* display header info */
  gtk_text_set_point(GTK_TEXT(bwindow->hdrtext), 0);
  gtk_text_forward_delete(GTK_TEXT(bwindow->hdrtext), gtk_text_get_length(GTK_TEXT(bwindow->hdrtext)));
  /*if(bwindow->current->hdr)*/
    gtk_text_insert(GTK_TEXT(bwindow->hdrtext), NULL, NULL, NULL, bwindow->current->hdr, strlen(bwindow->current->hdr));
#endif


  return(TRUE);
}

char *bwindow_get_url(BWindow *bwindow)
{
  return bwindow->current->url;
}


int history_change(BWindow *bwindow, HistoryNode *history)
{
  bwindow->history = history;

  return bwindow_set_url(bwindow, history->url);
}

void urlentry_changed(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
  if(event->keyval == GDK_Return) {
    if(!bwindow_set_url(BWINDOW(data), gtk_entry_get_text(GTK_ENTRY(widget)))) {
      gtk_entry_set_text(GTK_ENTRY(BWINDOW(data)->urlentry),
                         BWINDOW(data)->current->url);
    }
  }
}

void browser_url_changed(BWindow *bwindow)
{
#ifdef DO_HISTORY
  HistoryNode *h;
#endif

#if 0
  char *url;
#endif

  g_print("in browser_url_changed()\n");

#if 0
  url = browser_get_url(BROWSER(BWINDOW(data)->browser));
#endif

#ifdef DO_HISTORY
  if(!bwindow->history || strcmp(bwindow->current->url, bwindow->history->url) != 0) { 
    h = bwindow->history;
    bwindow->history = historynode_add_descendent(h, bwindow->current->url);
  }

  /* set back&forward buttons appropriately */
  if(bwindow->history->parent) {
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->backbutton), TRUE);
    gtk_tooltips_unref(bwindow->backtooltips);
    bwindow->backtooltips = gtk_tooltips_new();
    gtk_tooltips_set_tips(bwindow->backtooltips, GTK_WIDGET(bwindow->backbutton), bwindow->history->parent->url);
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->backmenu), TRUE);
  } else {
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->backbutton), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->backmenu), FALSE);
  }

  if(bwindow->history->descendent) {
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->forwardbutton), TRUE);
    gtk_tooltips_unref(bwindow->forwardtooltips);
    bwindow->forwardtooltips = gtk_tooltips_new();
    gtk_tooltips_set_tips(bwindow->forwardtooltips, GTK_WIDGET(bwindow->forwardbutton), bwindow->history->descendent->url);
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->forwardmenu), TRUE);
  } else {
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->forwardbutton), FALSE);
    gtk_widget_set_sensitive(GTK_WIDGET(bwindow->forwardmenu), FALSE);
  }
#endif

  g_print("about to set entry text\n");

  gtk_entry_set_text(GTK_ENTRY(bwindow->urlentry), bwindow->current->url);

  g_print("out browser_url_changed()\n");
}

gint delete_event(GtkWidget *widget, gpointer data)
{
   /* if you return TRUE in the "delete_event" signal handler,
    * GTK will emit the "destroy" signal. Returning FALSE means
    * you don't want the window to be destroyed.
    * This is useful for popping up "Are you sure you want to quit?"
    * type dialogs */

   /* Change FALSE to TRUE and the main window will be destroyed with
    * a "delete_event" */

   express_close_browser(BWINDOW(data));
   return(TRUE);

#if 0
   num_bwindows--;
   if(num_bwindows>0) {
     return(FALSE);
   } else {
     cleanexit(0);
     return(TRUE); /* :) */
   }
#endif
}

/* another callback */
void destroy(GtkWidget *widget, gpointer data)
{
   gtk_main_quit();
}                         

