/*
 * Program name:  equake
 * Version:	  1.03.8
 * Source file:	  equake_applet.c  
 * Description:	  Equake pulls data about earthquakes and displays it in interesting ways
 *
 * Copyright (C) 2012-2015 Jeroen van Aart
 *
 * 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.
 */


/*
 * get rid of warnings "incompatible implicit declaration of built-in function ‘strndup’"
 * also see http://cboard.cprogramming.com/c-programming/119875-using-strndup.html
 */
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pwd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

#include <config.h>

#include <gtk/gtk.h>
#include <glib-object.h>
#include <string.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <libxfce4panel/xfce-panel-plugin.h>
#include <libxfce4panel/xfce-hvbox.h>

/* GdkPixbuf image defines */
#include "equake_dat.h" /* contains all structures */
#include "equake_func.h" /* contains all function prototypes used in this program */
#include "equake_images.h"

void equake_setprefs(struct Equake_Data *equakedata)
{
  FILE *fp;

  /* lets try to open read only, if it succeeds we try to read the preferences */
  fp=fopen(equakedata->configfile, "r");
  if (fp!=NULL)
  {
    /* file exists so we read the preferences */
    fclose(fp);
    equake_getprefs(equakedata);
  }
  /* 
   * we will now save the preferences to the file, in case the file didn't exist yet it will be created with defaults
   * if it did exist it will be recreated with the user's saved settings, any newly created preferences that
   * didn't exist yet since a previous release will be added with a default
   */
  fp=fopen(equakedata->configfile, "w");
  equake_saveprefs(equakedata, fp);
  fclose(fp);
}

void equake_getprefs(struct Equake_Data *equakedata)
{
  FILE *fp;
  char *buf;
  size_t nbytes=100;
  int val;

  fp=fopen(equakedata->configfile, "r");
  if (fp==NULL)
    return ;

  buf=(char*)malloc(nbytes+1);
  if (buf==NULL)
    return;

  if (getline(&buf, &nbytes, fp)!=-1)
  {
    if (strncmp(buf,CONFIGHEADER,nbytes))
    {
      /* 
       * this is a valid config file 
       * read 2 lines, second line contains polltime
       */
      if (getline(&buf, &nbytes, fp)!=-1)
      {
	if (getline(&buf, &nbytes, fp)!=-1)
	{
	  /* here we expect polltime */
          val=atoi(buf);
	  /* we use switch/case in order to make sure poll exactly matches valid values */ 
          switch (val)
	  {
            case 120:
	      equakedata->poll_time=120; /* 2 minutes */
	      equakedata->properties_index[0]=0;
	      break;
	    case 180:
	      equakedata->poll_time=180;
              equakedata->properties_index[0]=1;
	      break;
	    case 240:
	      equakedata->poll_time=240;
              equakedata->properties_index[0]=2;
	      break;
	    case 300:
	      equakedata->poll_time=300;
              equakedata->properties_index[0]=3;
	      break;
	    case 600:
	      equakedata->poll_time=600;
              equakedata->properties_index[0]=4;
	      break;
	    case 900:
	      equakedata->poll_time=900;
              equakedata->properties_index[0]=5;
	      break;
	    case 1200:
	      equakedata->poll_time=1200;
              equakedata->properties_index[0]=6;
	      break;
	    case 1800:
	      equakedata->poll_time=1800;
              equakedata->properties_index[0]=7;
	      break;
	    default:
	      equakedata->poll_time=300; /* 5 minutes will be the default */
              equakedata->properties_index[0]=3;
	      break;
	  }    
	}
      }

      if (getline(&buf, &nbytes, fp)!=-1)
      {
        if (getline(&buf, &nbytes, fp)!=-1)
        {
	  /* will alert? */	  
          val=atoi(buf);
	  if (val==0)
	  {
	    equakedata->will_alert=0;
            equakedata->properties_index[1]=0;
	  }
	  else
	  {
            equakedata->will_alert=1;
            equakedata->properties_index[1]=1;
	  }
	}
      }
      
      if (getline(&buf, &nbytes, fp)!=-1)
      {
        if (getline(&buf, &nbytes, fp)!=-1)
        {
	  /* alert heavy */	  
          val=atoi(buf);
	  switch (val)
	  {
	    case 3:
	      equakedata->alert_heavy=3;
              equakedata->properties_index[2]=0;
	      break;
	    case 4:
              equakedata->alert_heavy=4;
              equakedata->properties_index[2]=1;
              break;
	    case 5:
              equakedata->alert_heavy=5;
              equakedata->properties_index[2]=2;
              break;
	    case 6:
              equakedata->alert_heavy=6;
              equakedata->properties_index[2]=3;
              break;
	    case 7:
              equakedata->alert_heavy=7;
              equakedata->properties_index[2]=4;
              break;
	    case 8:
              equakedata->alert_heavy=8;
              equakedata->properties_index[2]=5;
              break;
	    default:
              equakedata->alert_heavy=ALERTHEAVY;
              equakedata->properties_index[2]=3;
              break;
	  }
	}
      }

      if (getline(&buf, &nbytes, fp)!=-1)
      {
        if (getline(&buf, &nbytes, fp)!=-1)
        {
          /* sigfilemag */
          val=atoi(buf);
	  switch (val)
	  {
	    case 0:
	      equakedata->sigfilemag=0;
              equakedata->properties_index[3]=0;
	      break;
	    case 2:
	      equakedata->sigfilemag=2;
              equakedata->properties_index[3]=1;
	      break;
            case 3:
              equakedata->sigfilemag=3;
              equakedata->properties_index[3]=2;
              break;
            case 4:
              equakedata->sigfilemag=4;
              equakedata->properties_index[3]=3;
              break;
            case 5:
              equakedata->sigfilemag=5;
              equakedata->properties_index[3]=4;
              break;
            case 6:
              equakedata->sigfilemag=6;
              equakedata->properties_index[3]=5;
              break;
            case 7:
              equakedata->sigfilemag=7;
              equakedata->properties_index[3]=6;
              break;
            case 8:
              equakedata->sigfilemag=8;
              equakedata->properties_index[3]=7;
              break;
            default:
              equakedata->sigfilemag=SIGFILEMAG;
              equakedata->properties_index[3]=3;
              break;
	  }
	}
      }

      if (getline(&buf, &nbytes, fp)!=-1)
      {
        if (getline(&buf, &nbytes, fp)!=-1)
        {
          /* minimum magnitude to monitor */
          val=atoi(buf);
          switch (val)
	  {
	    case 2:
	      equakedata->monitormag=2;
              equakedata->properties_index[4]=1;
	      break;
	    case 3:
	      equakedata->monitormag=3;
              equakedata->properties_index[4]=2;
	      break;
	    default:
	      equakedata->monitormag=MONITORMAG;
              equakedata->properties_index[4]=0;
	      break;
	  }
	}
      }
    }
  }
  free(buf);
  fclose(fp);
  return;  
}

void equake_saveprefs(struct Equake_Data *equakedata, FILE *fp)
{
  /* make sure fp is not NULL, even though it's should never be NULL at this point */
  if (fp==NULL)
    return;

  fprintf(fp, "%s\n", CONFIGHEADER);
  fprintf(fp, "%s\n", "# polltime in seconds, will only allow (2, 3, 4, 5, 10, 15, 20, 30) *60 seconds, any other value will default to 5*60 seconds");
  fprintf(fp, "%d\n", equakedata->poll_time);
  fprintf(fp, "%s\n", "# will alert about high magnitude earthquakes, 1=yes, 0=no (if not set or anything else=yes)");
  fprintf(fp, "%d\n", equakedata->will_alert);
  fprintf(fp, "%s\n", "# minimum magnitude to display alert dialog, default is 6 (can be 3, 4, 5, 6, 7, 8, anything else defaults to 6)");
  fprintf(fp, "%d\n", equakedata->alert_heavy);
  fprintf(fp, "%s\n", "# minimum alert to store in signature file (~/.equake_sigfile.eq), default is 4 (can be 2, 3, 4, 5, 6, 7, 8, anything else defaults to 4, 0 turns it off)");
  fprintf(fp, "%d\n", equakedata->sigfilemag);
  fprintf(fp, "%s\n", "# minimum magnitude earthquake to monitor, default is 1 (can be 1, 2 or 3, anything else defaults to 1)");
  fprintf(fp, "%d\n", equakedata->monitormag);
}

static int button_press_callback(GtkWidget *event_box, GdkEventButton *event, gpointer data)
{
  char url[512];
  
  /* only do something if left mouse button was released */
  if ((event->type==GDK_BUTTON_PRESS) && (event->button==1))
  {
    snprintf(url, URLSIZE, "%s", USGS_WEBSITE);
    display_url(url);

    return 0;
  }
  else
    return -1;
}

/*static void equake_applet_change_background(XfcePanelPlugin *applet, XfcePanelPluginBackgroundType type, GdkColor  *colour, GdkPixmap *pixmap)
{
  GtkRcStyle *rc_style;
  GtkStyle *style;

  /* reset style */
  /*gtk_widget_set_style (GTK_WIDGET (applet), NULL);
  rc_style = gtk_rc_style_new ();
  gtk_widget_modify_style (GTK_WIDGET (applet), rc_style);
  gtk_rc_style_unref (rc_style);

  switch (type)
  {
    case PANEL_NO_BACKGROUND:
      break;
  
    case PANEL_COLOR_BACKGROUND:
      gtk_widget_modify_bg(GTK_WIDGET (applet), GTK_STATE_NORMAL, colour);
      break;

    case PANEL_PIXMAP_BACKGROUND:
      style = gtk_style_copy (GTK_WIDGET (applet)->style);

      if (style->bg_pixmap[GTK_STATE_NORMAL])
        g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);

      style->bg_pixmap[GTK_STATE_NORMAL]=g_object_ref(pixmap);
      gtk_widget_set_style(GTK_WIDGET (applet), style);
      g_object_unref(style);
      break;
  }
}*/

static void equake_orientation_changed(XfcePanelPlugin *applet, GtkOrientation orientation, struct Equake_Data *equakedata)
{
  orientation=xfce_panel_plugin_get_orientation(applet);
  /* change the orienation of the box */
  xfce_hvbox_set_orientation(XFCE_HVBOX(equakedata->hbox), orientation);
}

static void equake_size_changed(XfcePanelPlugin *applet, int size, struct Equake_Data *equakedata)
{
  GtkOrientation orientation;

  /* get the orientation of the plugin */
  orientation=xfce_panel_plugin_get_orientation(applet);

  /* set the widget size */
  if (orientation==GTK_ORIENTATION_HORIZONTAL)
    gtk_widget_set_size_request(GTK_WIDGET(applet), -1, size);
  else
    gtk_widget_set_size_request(GTK_WIDGET(applet), size, -1);
}

/*
 * for lack of a main() this pretty much is where we start
 * the function is registered by the macro below
 */
static void equake_applet_fill(XfcePanelPlugin *applet)
{
  GtkWidget *label, *logo, *event_box;
  GtkWidget *menu_update, *menu_details, *menu_map, *menu_didyoufeelit, *menu_lasthour, *menu_lastday, *menu_lastweek;
  GdkPixbuf *quake_logo;
 
  struct Equake_Data *equakedata=g_malloc0(sizeof(struct Equake_Data));
  /* 
   * we exit when this alloc returns NULL, since without this continuing the program is pointless
   * in other cases the program doesn't depend on the alloc succeeding right then and there
   * in all other cases the function returns when alloc returns NULL
   * although an exit() is may be preferred I suspect a real out of memory is so rare these days that a quick exit() is excessive
   */
  if(equakedata==NULL)
    exit(-1);
 
  /* get equake logo from included file equake_images.h in pixbuf format */
  quake_logo=gdk_pixbuf_new_from_inline(-1, equake_icon, FALSE, NULL);
  /* create logo widget */
  logo=gtk_image_new_from_pixbuf(quake_logo);
  /* create eventbox, container and signal to deal with button presses on logo widget */
  event_box=gtk_event_box_new();
  gtk_container_add((GtkContainer *) event_box, logo);
  g_signal_connect(G_OBJECT (event_box), "button_press_event", G_CALLBACK (button_press_callback), logo);

  /* this is the initial value of the label text */
  label=gtk_label_new(LABELTXT);

  /* create a new hbox widget and pack the event_box and label in it */
  equakedata->hbox=gtk_hbox_new(FALSE, 4);
  gtk_box_pack_start((GtkBox *) equakedata->hbox, event_box, FALSE, FALSE, 0);
  gtk_box_pack_start((GtkBox *) equakedata->hbox, label, FALSE, FALSE, 0);
  /* then add it to the applet container */
  gtk_container_add(GTK_CONTAINER(applet), equakedata->hbox);

  gtk_widget_set_tooltip_text((GtkWidget *) event_box, BUTTONTXT);
  gtk_widget_set_tooltip_text((GtkWidget *) label, NODATA);

  /* show the panel's right-click menu on this ebox */
  xfce_panel_plugin_add_action_widget(applet, equakedata->hbox);

  g_signal_connect(G_OBJECT (applet), "size-changed", G_CALLBACK (equake_size_changed), equakedata);
  g_signal_connect(G_OBJECT (applet), "orientation-changed", G_CALLBACK (equake_orientation_changed), equakedata);

  /* show the configure menu item and connect signal */
  xfce_panel_plugin_menu_show_configure(applet);
  g_signal_connect(G_OBJECT(applet), "configure-plugin", G_CALLBACK(display_properties_dialog), equakedata);

  /* show the about menu item and connect signal */
  xfce_panel_plugin_menu_show_about(applet);
  g_signal_connect(G_OBJECT(applet), "about", G_CALLBACK(display_about_dialog), equakedata);

  menu_update=gtk_image_menu_item_new_from_stock("gtk-refresh", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_update, "_Update");
  gtk_widget_show(menu_update);
  g_signal_connect(G_OBJECT(menu_update), "activate", G_CALLBACK(do_update), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_update));

  menu_details=gtk_image_menu_item_new_from_stock("gtk-info", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_details, "_Details");
  gtk_widget_show(menu_details);
  g_signal_connect(G_OBJECT(menu_details), "activate", G_CALLBACK(load_details), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_details));

  menu_map=gtk_image_menu_item_new_from_stock("gtk-find", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_map, "_Map");
  gtk_widget_show(menu_map);
  g_signal_connect(G_OBJECT(menu_map), "activate", G_CALLBACK(load_map), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_map));

  menu_didyoufeelit=gtk_image_menu_item_new_from_stock("gtk-find", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_didyoufeelit, "Did you _feel it?");
  gtk_widget_show(menu_didyoufeelit);
  g_signal_connect(G_OBJECT(menu_didyoufeelit), "activate", G_CALLBACK(load_didyoufeelit), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_didyoufeelit));

  menu_lasthour=gtk_image_menu_item_new_from_stock("gtk-index", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_lasthour, "Last _hour");
  gtk_widget_show(menu_lasthour);
  g_signal_connect(G_OBJECT(menu_lasthour), "activate", G_CALLBACK(display_lasthour), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_lasthour));

  menu_lastday=gtk_image_menu_item_new_from_stock("gtk-index", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_lastday, "_Last day");
  gtk_widget_show(menu_lastday);
  g_signal_connect(G_OBJECT(menu_lastday), "activate", G_CALLBACK(display_lastday), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_lastday));

  menu_lastweek=gtk_image_menu_item_new_from_stock("gtk-index", NULL);
  gtk_menu_item_set_label((GtkMenuItem *)menu_lastweek, "Last _week (slow)");
  gtk_widget_show(menu_lastweek);
  g_signal_connect(G_OBJECT(menu_lastweek), "activate", G_CALLBACK(display_lastweek), equakedata);
  xfce_panel_plugin_menu_insert_item(applet, GTK_MENU_ITEM(menu_lastweek));

  gtk_widget_show_all(GTK_WIDGET(applet));

  startequake(applet, label, logo, equakedata);
}

/* register the xfce plugin */
XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL(equake_applet_fill);


/*********************************************
 **** WE MERGED THIS WITH equake_applet.c ****
 *********************************************
 *
 * Program name:  equake
 * Version:	  1.03.4
 * Source file:	  equake_menu.c  
 * Description:	  Equake pulls data about earthquakes and displays it in interesting ways
 *
 * Copyright (C) 2012-2014 Jeroen van Aart
 *
 * 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.
 */


/* function to update applet after menu item "Update" has been selected */
static void do_update(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  /* lets refresh preferences, if user has changed it, we will now use the new values */
  equake_getprefs(equakedata);

  if (getquakedata(equakedata, HOURLY)>0)
    if (processdata(equakedata, HOURLY)==-1)
      perror("Failed to process data"); /* non fatal error, hopefully */
}

static void load_details(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  char url[URLSIZE];

  if (equakedata->posperiod==HOURLY)
  {
    if (equakedata->quake_history_count>=0)
    {
      if (equakedata->equakeformat[equakedata->pos].src!="")
      {
	snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_ww, equakedata->equakeformat[equakedata->pos].eqid, QUAKEPATH_AF);
        display_url(url);
      }
    }
    else
      display_dialog("No data available at this time");

  }
  else
  {
    if (equakedata->quake_history_countdaily>=0)
    {
      if (equakedata->equakeformatday[equakedata->pos].src!="")
      {
        snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_ww, equakedata->equakeformatday[equakedata->pos].eqid, QUAKEPATH_AF);
        display_url(url);
      }
    }
    else
      display_dialog("No data available at this time");
  }
}

static void load_map(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  char url[URLSIZE];

  if (equakedata->posperiod==HOURLY)
  {
    if (equakedata->quake_history_count>=0)
    {
      snprintf(url, URLSIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "http://", MAPURL0, equakedata->equakeformat[equakedata->pos].lat, MAPURL2, equakedata->equakeformat[equakedata->pos].lon, MAPURL2, "Earthquake Magnitude: ", equakedata->equakeformat[equakedata->pos].magnitude, " Region: ", equakedata->equakeformat[equakedata->pos].region, MAPURL2, "Rendered by e-quake.org", MAPURL2, WEBSITE);
      display_url(url);
    }
    else
      display_dialog("No data available at this time");
  }
  else
  {
    if (equakedata->quake_history_countdaily>=0)
    {
      snprintf(url, URLSIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "http://", MAPURL0, equakedata->equakeformatday[equakedata->pos].lat, MAPURL2, equakedata->equakeformatday[equakedata->pos].lon, MAPURL2, "Earthquake Magnitude: ", equakedata->equakeformatday[equakedata->pos].magnitude, " Region: ", equakedata->equakeformatday[equakedata->pos].region, MAPURL2, "Rendered by e-quake.org", MAPURL2, WEBSITE);
      display_url(url);
    }
    else
      display_dialog("No data available at this time");
  }
}

static void load_didyoufeelit(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  char url[URLSIZE];

  if (equakedata->posperiod==HOURLY)
  {
    if (equakedata->quake_history_count>=0)
    {
      snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_dyfi_be, equakedata->equakeformat[equakedata->pos].eqid, equakedata->quakepath_dyfi_af);
      display_url(url);
    }
    else
      display_dialog("No data available at this time");
  }
  else
  {
    if (equakedata->quake_history_countdaily>=0)
    {
      snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_dyfi_be, equakedata->equakeformatday[equakedata->pos].eqid, equakedata->quakepath_dyfi_af);
      display_url(url);
    }
    else
      display_dialog("No data available at this time");
  }
}

/* we display a dialog to change preferences, because editing a text file is soo difficult */
static void display_properties_dialog(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  int polltime, willalert, alertheavy, sigfilemag, monitormag;
  FILE *fp;

  GtkWidget *polltime_select, *willalert_select, *alertheavy_select, *sigfilemag_select, *monitormag_select, *image_about;
  GtkWidget *labelpoll, *labelwillalert, *labelalertheavy, *labelsigfile, *labelmonitormag, *sep, *sep2;

 /* block menu from being used whilst properties dialog is open */
  xfce_panel_plugin_block_menu(applet);

  equakedata->prefsdialog=gtk_dialog_new_with_buttons(PREFSWINDOW, NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_HELP, GTK_RESPONSE_HELP, NULL);

  sep=gtk_hseparator_new();
  sep2=gtk_hseparator_new();

  labelpoll=gtk_label_new(PREFPOLLTEXT);
  labelwillalert=gtk_label_new(PREFALERTEXT);
  labelalertheavy=gtk_label_new(PREFALERTHEAVYTEXT);
  labelsigfile=gtk_label_new(PREFSIGFILETEXT);
  labelmonitormag=gtk_label_new(PREFMONITORMAGTEXT);

  image_about=gtk_image_new_from_pixbuf(equakedata->equake_about);

  polltime_select=gtk_combo_box_new_text();
  willalert_select=gtk_combo_box_new_text();
  alertheavy_select=gtk_combo_box_new_text();
  sigfilemag_select=gtk_combo_box_new_text();
  monitormag_select=gtk_combo_box_new_text();

  gtk_combo_box_set_title((GtkComboBox*)polltime_select, PREFPOLLTEXT);
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 0, "2");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 1, "3");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 2, "4");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 3, "5");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 4, "10");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 5, "15");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 6, "20");
  gtk_combo_box_insert_text((GtkComboBox*)polltime_select, 7, "30");

  /* properties_index[] holds default or previous combo box indexes */
  gtk_combo_box_set_active((GtkComboBox*)polltime_select, equakedata->properties_index[0]);

  gtk_combo_box_insert_text((GtkComboBox*)willalert_select, 0, "No");
  gtk_combo_box_insert_text((GtkComboBox*)willalert_select, 1, "Yes");

  gtk_combo_box_set_active((GtkComboBox*)willalert_select, equakedata->properties_index[1]);

  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 0, "3");
  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 1, "4");
  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 2, "5");
  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 3, "6");
  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 4, "7");
  gtk_combo_box_insert_text((GtkComboBox*)alertheavy_select, 5, "8");

  gtk_combo_box_set_active((GtkComboBox*)alertheavy_select, equakedata->properties_index[2]);

  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 0, "0");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 1, "2");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 2, "3");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 3, "4");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 4, "5");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 5, "6");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 6, "7");
  gtk_combo_box_insert_text((GtkComboBox*)sigfilemag_select, 7, "8");

  gtk_combo_box_set_active((GtkComboBox*)sigfilemag_select, equakedata->properties_index[3]);

  gtk_combo_box_insert_text((GtkComboBox*)monitormag_select, 0, "1");
  gtk_combo_box_insert_text((GtkComboBox*)monitormag_select, 1, "2");
  gtk_combo_box_insert_text((GtkComboBox*)monitormag_select, 2, "3");

  gtk_combo_box_set_active((GtkComboBox*)monitormag_select, equakedata->properties_index[4]);


  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), image_about, TRUE, TRUE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), sep, TRUE, TRUE, 4);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), labelpoll, TRUE, FALSE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), polltime_select, TRUE, FALSE, 8);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), labelwillalert, TRUE, TRUE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), willalert_select, TRUE, TRUE, 8);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), labelalertheavy, TRUE, TRUE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), alertheavy_select, TRUE, TRUE, 8);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), labelsigfile, TRUE, TRUE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), sigfilemag_select, TRUE, TRUE, 8);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), labelmonitormag, TRUE, TRUE, 4);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), monitormag_select, TRUE, TRUE, 8);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(equakedata->prefsdialog)->vbox), sep2, TRUE, TRUE, 4);


  gtk_widget_show(image_about);
  gtk_widget_show(sep);

  gtk_widget_show(labelpoll);
  gtk_widget_show(polltime_select);

  gtk_widget_show(labelwillalert);
  gtk_widget_show(willalert_select);

  gtk_widget_show(labelalertheavy);
  gtk_widget_show(alertheavy_select);

  gtk_widget_show(labelsigfile);
  gtk_widget_show(sigfilemag_select);

  gtk_widget_show(labelmonitormag);
  gtk_widget_show(monitormag_select);

  gtk_widget_show(sep2);


  while (1)
  {
    /* we enter a recursive loop to await dialog to return with user defined input */
    int result=gtk_dialog_run((GtkDialog*)equakedata->prefsdialog);

    switch (result)
    {
      case GTK_RESPONSE_OK:
        /* lets get the values the user chose */
        polltime=gtk_combo_box_get_active((GtkComboBox*)polltime_select);
        willalert=gtk_combo_box_get_active((GtkComboBox*)willalert_select);
        alertheavy=gtk_combo_box_get_active((GtkComboBox*)alertheavy_select);
        sigfilemag=gtk_combo_box_get_active((GtkComboBox*)sigfilemag_select);
        monitormag=gtk_combo_box_get_active((GtkComboBox*)monitormag_select);
        set_properties_from_dialog(polltime, willalert, alertheavy, sigfilemag, monitormag, equakedata);

        equakedata->properties_index[0]=polltime;
        equakedata->properties_index[1]=willalert;
        equakedata->properties_index[2]=alertheavy;
        equakedata->properties_index[3]=sigfilemag;
        equakedata->properties_index[4]=monitormag;

        /* save preferences */
        fp=fopen(equakedata->configfile, "w");
        equake_saveprefs(equakedata, fp);
        fclose(fp);
        /* unblock menu */
        xfce_panel_plugin_unblock_menu(applet);
        gtk_widget_destroy(equakedata->prefsdialog);
        return;
        break;

      case GTK_RESPONSE_HELP:
        gtk_widget_hide(equakedata->prefsdialog);
        /* lets display some help text for preferences */
        display_dialog(PREFSTEXT);
        gtk_widget_show(equakedata->prefsdialog);
        break;

      default:
        /* unblock menu */
        xfce_panel_plugin_unblock_menu(applet);
        gtk_widget_destroy(equakedata->prefsdialog);
        return;
    }
  }
  /* unblock menu */
  xfce_panel_plugin_unblock_menu(applet);
  gtk_widget_destroy(equakedata->prefsdialog);
}

static void set_properties_from_dialog(int polltime, int willalert, int alertheavy, int sigfilemag, int monitormag, struct Equake_Data *equakedata)
{
  switch (polltime)
  {
    case 0:
      equakedata->poll_time=120; /* 2 minutes */
      break;
    case 1:
      equakedata->poll_time=180;
      break;
    case 2:
      equakedata->poll_time=240;
      break;
    case 3:
      equakedata->poll_time=300;
      break;
    case 4:
      equakedata->poll_time=600;
      break;
    case 5:
      equakedata->poll_time=900;
      break;
    case 6:
      equakedata->poll_time=1200;
      break;
    case 7:
      equakedata->poll_time=1800;
      break;
    default:
      equakedata->poll_time=300; /* 5 minutes will be the default */
      break;
  }

  switch (willalert)
  {
    case 0:
      equakedata->will_alert=0;
      break;
    default:
      equakedata->will_alert=1;
      break;
  }

  switch (alertheavy)
  {
    case 0:
      equakedata->alert_heavy=3;
      break;
    case 1:
      equakedata->alert_heavy=4;
      break;
    case 2:
      equakedata->alert_heavy=5;
      break;
    case 3:
      equakedata->alert_heavy=6;
      break;
    case 4:
      equakedata->alert_heavy=7;
      break;
    case 5:
      equakedata->alert_heavy=8;
      break;
    default:
      equakedata->alert_heavy=ALERTHEAVY;
      break;
  }

  switch (sigfilemag)
  {
    case 0:
      equakedata->sigfilemag=0;
      break;
    case 1:
      equakedata->sigfilemag=2;
      break;
    case 2:
      equakedata->sigfilemag=3;
      break;
    case 3:
      equakedata->sigfilemag=4;
      break;
    case 4:
      equakedata->sigfilemag=5;
      break;
    case 5:
      equakedata->sigfilemag=6;
      break;
    case 6:
      equakedata->sigfilemag=7;
      break;
    case 7:
      equakedata->sigfilemag=8;
      break;
    default:
      equakedata->sigfilemag=SIGFILEMAG;
      break;
  }

  switch (monitormag)
  {
    case 1:
      equakedata->monitormag=2;
      break;
    case 2:
      equakedata->monitormag=3;
      break;
    default:
      equakedata->monitormag=MONITORMAG;
      break;
  }
}

static void display_about_dialog(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  GtkWidget *about;
  gchar *auth[]={AUTHOR, NULL};

  about=gtk_about_dialog_new();
  if(about!=NULL)
  {
    gtk_about_dialog_set_logo((GtkAboutDialog*)about, equakedata->equake_about);
    gtk_about_dialog_set_version((GtkAboutDialog*)about,EQVERSION);
    gtk_about_dialog_set_copyright((GtkAboutDialog*)about,COPYRIGHT);
    gtk_about_dialog_set_comments((GtkAboutDialog*)about,COMMENTS);
    gtk_about_dialog_set_license((GtkAboutDialog*)about,LICENSE);
    gtk_about_dialog_set_website((GtkAboutDialog*)about,WEBSITE);
    gtk_about_dialog_set_website_label((GtkAboutDialog*)about,WEBSITELABEL);
    gtk_about_dialog_set_authors((GtkAboutDialog*)about, (gchar*)auth);

    g_signal_connect_swapped(about, "response", G_CALLBACK (gtk_widget_destroy), about);
    gtk_widget_show_all((GtkWidget*)about);
  }
}

/* 
 * displays last hour/day/week, will first load data for last hour/day/week
 * then just runs display_lasthour/day/week to display it in a dialog
 */
static void display_lastweek(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  if (getquakedata(equakedata, WEEKLY)>0)
  {
    if (processdata(equakedata, WEEKLY)==-1)
    {
      perror("Failed to process data"); /* non fatal error, hopefully */
      display_dialog("No data available at this time");
      return;
    }
    display_lastperiod(equakedata, WEEKLY);
  }
}

static void display_lastday(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  if (getquakedata(equakedata, DAILY)>0)
  {
    if (processdata(equakedata, DAILY)==-1)
    {
      perror("Failed to process data"); /* non fatal error, hopefully */
      display_dialog("No data available at this time");
      return;
    }
    display_lastperiod(equakedata, DAILY);
  }
}
  
static void display_lasthour(XfcePanelPlugin *applet, struct Equake_Data *equakedata)
{
  if (getquakedata(equakedata, HOURLY)>0)
  {
    if (processdata(equakedata, HOURLY)==-1)
    {
      perror("Failed to process data"); /* non fatal error, hopefully */
      display_dialog("No data available at this time");
      return;
    }
    display_lastperiod(equakedata, HOURLY);
  }
}

/*
 * fill text to be display in window depending on the period
 * such as hourly or daily, hourly is the default 
 */
static void fill_text_period(struct Equake_Data *equakedata, char *running, char *periodtext, int period)
{
  int n;
  char url[URLSIZE], mapurl[URLSIZE];
  double mag;

  if (period==DAILY)
  {
    for (n=0;n<=equakedata->quake_history_countdaily;n++)
    {
      /* create url to be displayed */
      snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_ww, equakedata->equakeformatday[n].eqid, QUAKEPATH_AF);
      /* create map url */
      snprintf(mapurl, URLSIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "http://", MAPURL1, equakedata->equakeformatday[n].lat, MAPURL2, equakedata->equakeformatday[n].lon, MAPURL2, "Earthquake Magnitude: ", equakedata->equakeformatday[n].magnitude, " Region: ", equakedata->equakeformatday[n].region, MAPURL2, "Rendered by e-quake.org", MAPURL2, WEBSITE);

      /* convert magnitude to double */
      if(equakedata->equakeformatday[n].magnitude!=NULL)
        mag=atof(equakedata->equakeformatday[n].magnitude);
      else
        mag=0;

      if ((gtk_major_version>=2) && (gtk_minor_version>=18))
      {
        /* if magnitude is bigger or equal to DAILYHEAVY make magnitude bold */
        if (mag>=DAILYHEAVY)
          snprintf(running, strlen(equakedata->bufferdaily), "<b>Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a></b>\n\n", equakedata->equakeformatday[n].magnitude, equakedata->equakeformatday[n].datetime, equakedata->equakeformatday[n].datetime_local, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].lat, equakedata->equakeformatday[n].lon, equakedata->equakeformatday[n].depth, url, url, url, mapurl, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].region);
        else
          snprintf(running, strlen(equakedata->bufferdaily), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a>\n\n", equakedata->equakeformatday[n].magnitude, equakedata->equakeformatday[n].datetime, equakedata->equakeformatday[n].datetime_local, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].lat, equakedata->equakeformatday[n].lon, equakedata->equakeformatday[n].depth, url, url, url, mapurl, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].region);
      }
      else
      {
        /* if magnitude is bigger or equal to DAILYHEAVY make magnitude bold */
        if (mag>=DAILYHEAVY)
          snprintf(running, strlen(equakedata->bufferdaily), "<b>Earthquake Magnitude: %s</b>\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s</b>\n\n", equakedata->equakeformatday[n].magnitude, equakedata->equakeformatday[n].datetime, equakedata->equakeformatday[n].datetime_local, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].lat, equakedata->equakeformatday[n].lon, equakedata->equakeformatday[n].depth, url);
        else
          snprintf(running, strlen(equakedata->bufferdaily), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s\n\n", equakedata->equakeformatday[n].magnitude, equakedata->equakeformatday[n].datetime, equakedata->equakeformatday[n].datetime_local, equakedata->equakeformatday[n].region, equakedata->equakeformatday[n].lat, equakedata->equakeformatday[n].lon, equakedata->equakeformatday[n].depth, url);
      }
      strncat(periodtext, running, strlen(running));
    }
  }
  else
  {
    if (period==WEEKLY)
    {
      for (n=0;n<=equakedata->quake_history_countweekly;n++)
      {
        /* create url to be displayed */
        snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_ww, equakedata->equakeformatweek[n].eqid, QUAKEPATH_AF);
        /* create map url */
        snprintf(mapurl, URLSIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "http://", MAPURL1, equakedata->equakeformatweek[n].lat, MAPURL2, equakedata->equakeformatweek[n].lon, MAPURL2, "Earthquake Magnitude: ", equakedata->equakeformatweek[n].magnitude, " Region: ", equakedata->equakeformatweek[n].region, MAPURL2, "Rendered by e-quake.org", MAPURL2, WEBSITE);

        /* convert magnitude to double */
        if(equakedata->equakeformatweek[n].magnitude!=NULL)
          mag=atof(equakedata->equakeformatweek[n].magnitude);
        else
          mag=0;

        if ((gtk_major_version>=2) && (gtk_minor_version>=18))
        {
          /* if magnitude is bigger or equal to WEEKLYHEAVY make magnitude bold */
          if (mag>=DAILYHEAVY)
            snprintf(running, strlen(equakedata->bufferweekly), "<b>Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a></b>\n\n", equakedata->equakeformatweek[n].magnitude, equakedata->equakeformatweek[n].datetime, equakedata->equakeformatweek[n].datetime_local, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].lat, equakedata->equakeformatweek[n].lon, equakedata->equakeformatweek[n].depth, url, url, url, mapurl, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].region);
          else
            snprintf(running, strlen(equakedata->bufferweekly), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a>\n\n", equakedata->equakeformatweek[n].magnitude, equakedata->equakeformatweek[n].datetime, equakedata->equakeformatweek[n].datetime_local, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].lat, equakedata->equakeformatweek[n].lon, equakedata->equakeformatweek[n].depth, url, url, url, mapurl, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].region);
        }
        else
        {
          /* if magnitude is bigger or equal to WEEKLYHEAVY make magnitude bold */
          if (mag>=DAILYHEAVY)
            snprintf(running, strlen(equakedata->bufferweekly), "<b>Earthquake Magnitude: %s</b>\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s</b>\n\n", equakedata->equakeformatweek[n].magnitude, equakedata->equakeformatweek[n].datetime, equakedata->equakeformatweek[n].datetime_local, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].lat, equakedata->equakeformatweek[n].lon, equakedata->equakeformatweek[n].depth, url);
          else
            snprintf(running, strlen(equakedata->bufferweekly), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s\n\n", equakedata->equakeformatweek[n].magnitude, equakedata->equakeformatweek[n].datetime, equakedata->equakeformatweek[n].datetime_local, equakedata->equakeformatweek[n].region, equakedata->equakeformatweek[n].lat, equakedata->equakeformatweek[n].lon, equakedata->equakeformatweek[n].depth, url);
        }
        strncat(periodtext, running, strlen(running));
      }
    }
    else
    {
      for (n=0;n<=equakedata->quake_history_count;n++)
      {
        /* create url to be displayed */
        snprintf(url, URLSIZE, "%s%s%s%s%s", "http://", equakedata->quakeserver, equakedata->quakepath_ww, equakedata->equakeformat[n].eqid, QUAKEPATH_AF);
	/* create map url */
        snprintf(mapurl, URLSIZE, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "http://", MAPURL1, equakedata->equakeformat[n].lat, MAPURL2, equakedata->equakeformat[n].lon, MAPURL2, "Earthquake Magnitude: ", equakedata->equakeformat[n].magnitude, " Region: ", equakedata->equakeformat[n].region, MAPURL2, "Rendered by e-quake.org", MAPURL2, WEBSITE);

	/* convert magnitude to double */
        if(equakedata->equakeformat[n].magnitude!=NULL)
          mag=atof(equakedata->equakeformat[n].magnitude);
        else
          mag=0;

	if ((gtk_major_version>=2) && (gtk_minor_version>=18))
        {
          /* if magnitude is bigger or equal to DAILYHEAVY make magnitude bold */
          if (mag>=DAILYHEAVY)
	    snprintf(running, strlen(equakedata->buffer), "<b>Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a></b>\n\n", equakedata->equakeformat[n].magnitude, equakedata->equakeformat[n].datetime, equakedata->equakeformat[n].datetime_local, equakedata->equakeformat[n].region, equakedata->equakeformat[n].lat, equakedata->equakeformat[n].lon, equakedata->equakeformat[n].depth, url, url, url, mapurl, equakedata->equakeformat[n].region, equakedata->equakeformat[n].region);
	  else
	    snprintf(running, strlen(equakedata->buffer), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: <a href=\"%s\" title=\"%s\">%s</a>\n<a href=\"%s\" title=\"Detailed Map %s\">Detailed Map %s</a>\n\n", equakedata->equakeformat[n].magnitude, equakedata->equakeformat[n].datetime, equakedata->equakeformat[n].datetime_local, equakedata->equakeformat[n].region, equakedata->equakeformat[n].lat, equakedata->equakeformat[n].lon, equakedata->equakeformat[n].depth, url, url, url, mapurl, equakedata->equakeformat[n].region, equakedata->equakeformat[n].region);
        }
        else
        {
	  /* if magnitude is bigger or equal to DAILYHEAVY make magnitude bold */
	  if (mag>=DAILYHEAVY)
	    snprintf(running, strlen(equakedata->buffer), "<b>Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s</b>\n\n", equakedata->equakeformat[n].magnitude, equakedata->equakeformat[n].datetime, equakedata->equakeformat[n].datetime_local, equakedata->equakeformat[n].region, equakedata->equakeformat[n].lat, equakedata->equakeformat[n].lon, equakedata->equakeformat[n].depth, url);
          else
            snprintf(running, strlen(equakedata->buffer), "Earthquake Magnitude: %s\nDate: %s\nDate Local: %s\nLocation: %s\nLatitude: %s; Longitude: %s\nDepth: %s km\nurl: %s\n\n", equakedata->equakeformat[n].magnitude, equakedata->equakeformat[n].datetime, equakedata->equakeformat[n].datetime_local, equakedata->equakeformat[n].region, equakedata->equakeformat[n].lat, equakedata->equakeformat[n].lon, equakedata->equakeformat[n].depth, url);
        }
	strncat(periodtext, running, strlen(running));
      }
    }
  }
}

static void display_period_window(char *text, int period)
{
  int screenheight;
  GtkWidget *scrolled_window, *window, *label, *button;
  GdkScreen *screen;

  /* get screen height */
  screen=gdk_screen_get_default();
  screenheight=gdk_screen_get_height(screen);

  /* allocate memory for the GtkRequisition funtion below */
  GtkRequisition *requisition=alloca(sizeof(GtkRequisition));
  if (requisition==NULL)
    return;
  
  /*
   * we're creating a window in which we place a scrolled window with a label
   * the label displays the text, since the text can at times be long it makes sense
   * to use a scrolled window, using a label allows us to use clickable urls
   */

  /* create the window */
  window=gtk_dialog_new();
  
  if (period==DAILY)
    gtk_window_set_title(GTK_WINDOW (window), RECDAYTXT);
  else if (period==WEEKLY)
    gtk_window_set_title(GTK_WINDOW (window), RECWEEKTXT);
  else
    gtk_window_set_title(GTK_WINDOW (window), RECHOURTXT);

  gtk_container_set_border_width (GTK_CONTAINER (window), 0);

  /* scrolled window */
  scrolled_window=gtk_scrolled_window_new(NULL,NULL);
  gtk_container_set_border_width(GTK_CONTAINER (scrolled_window), 10);
  gtk_scrolled_window_set_shadow_type((GtkScrolledWindow *)scrolled_window, GTK_SHADOW_IN);
  gtk_scrolled_window_set_policy((GtkScrolledWindow *)scrolled_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  gtk_box_pack_start(GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window, TRUE, TRUE, 0);
  gtk_widget_show(scrolled_window);

  /* label */
  label=gtk_label_new(text);
  gtk_label_set_use_markup((GtkLabel *)label, TRUE);
  
  gtk_label_set_selectable((GtkLabel *)label, TRUE);
  gtk_label_set_line_wrap((GtkLabel *)label, FALSE);
  gtk_scrolled_window_add_with_viewport((GtkScrolledWindow *)scrolled_window, label);
  gtk_widget_show(label);

  button=gtk_button_new_with_label("close");
  g_signal_connect_swapped(button, "clicked", G_CALLBACK (gtk_widget_destroy), window);

  /* this makes it so the button is the default. */
  gtk_widget_set_can_default(button, TRUE);
  gtk_box_pack_start(GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);

  /* This grabs this button to be the default button. Simply hitting
   * the "Enter" key will cause this button to activate. */
  gtk_widget_grab_default(button);
  gtk_widget_show (button);

  gtk_widget_size_request(label, requisition);

  /* make window not larger than screen height and keep 50 pixels headroom in case of larger/multiple panels */
  if (period!=HOURLY)
    gtk_widget_set_size_request(window, requisition->width+60, screenheight-100);
  else if ((requisition->height+100)<(screenheight-100))
    gtk_widget_set_size_request(window, requisition->width+60, requisition->height+100);
  else
    gtk_widget_set_size_request(window, requisition->width+60, screenheight-100);

  gtk_widget_show(window);
}


static void display_lastperiod(struct Equake_Data *equakedata, int period)
{
  /* allocate memory depending on the period, hourly is default */
  char *lastday=alloca(sizeof(equakedata->bufferdaily)+1); /* there's not more memory needed than what's in the buffer and normally much less */
  if (lastday==NULL)
    return;
  char *runningday=alloca(sizeof(equakedata->bufferdaily)+1);
  if (runningday==NULL)
    return;

  char *lastweek=alloca(sizeof(equakedata->bufferweekly)+1);
  if (lastweek==NULL)
    return;
  char *runningweek=alloca(sizeof(equakedata->bufferweekly)+1);
  if (runningweek==NULL)
    return;

  memset(lastday, 0, strlen(lastday));
  memset(runningday, 0, strlen(runningday));
  memset(lastweek, 0, strlen(lastweek));
  memset(runningweek, 0, strlen(runningweek));
    
  char *lasthour=alloca(sizeof(equakedata->buffer)+1); /* there's not more memory needed than what's in the buffer and normally much less */
  if (lasthour==NULL)
    return;
  char *running=alloca(sizeof(equakedata->buffer)+1);
  if (running==NULL)
    return;

  memset(lasthour, 0, strlen(lasthour));
  memset(running, 0, strlen(running));
  
  if ((period==DAILY) && (equakedata->quake_history_countdaily<0))
  {
    display_dialog("No data available at this time");
    return;
  }
  else
  {
    if ((period==WEEKLY) && (equakedata->quake_history_countweekly<0))
    {
      display_dialog("No data available at this time");
      return;
    }
    else
    {
      if ((period!=WEEKLY) && (period!=DAILY) && (equakedata->quake_history_count<0))
      {
        display_dialog("No data available at this time");
        return;
      }
    }
  }

  if (period==DAILY)
  {
    fill_text_period(equakedata, runningday, lastday, period);
    display_period_window(lastday, period);
  }
  else
  {
    if (period==WEEKLY)
    {
      fill_text_period(equakedata, runningweek, lastweek, period);
      display_period_window(lastweek, period);
    }
    else
    {
      fill_text_period(equakedata, running, lasthour, period);
      display_period_window(lasthour, period);
    }
  }
}

static void display_dialog(char *t)
{
  GtkWidget *dialog;

  dialog=gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", t);
  if(dialog)
  {
    gtk_dialog_run(GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);
  }

}

/*
 * copied from http://git.xfce.org/xfce/libxfce4ui/tree/libxfce4ui/xfce-dialogs.c#n66
 * and slightly adapted
 * we'll use this as a somewhat failsafe way to try to open a web browser
 */
static void display_url(char *url)
{
  GError *error=NULL;
  gchar *path;
  gchar *cmd;
  gboolean result=FALSE;

  path=g_find_program_in_path("exo-open");
  if (G_LIKELY(path!=NULL))
  {
    cmd=g_strdup_printf("%s --launch WebBrowser '%s'", path, url);

    result=g_spawn_command_line_async(cmd, NULL);

    g_free (path);
    g_free (cmd);
  }
  else
  {
    /* 
     * not very likely to happen, but it is possible exo is not installed 
     * this may fail of gvfs is not present, which is likely when gnome was not installed or is not running
     */
    result=gtk_show_uri(NULL, url, gtk_get_current_event_time (), &error);
  }

  if (!result)
  {
    display_dialog(NOBROWSER);
    g_error_free(error);
  }
}
