/*  gfocustimer
 *  Copyright (C) 1999 James Cameron, <quozl@us.netrek.org>
 *
 *  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.
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <gtk/gtk.h>

#include "interface.h"
#include "data.h"


/* main window */
extern struct mw mw;

/* preferences data */
extern struct pd pd;


/* copy of g_list_append, modified to return new list element */
GList* list_append (GList *list, gpointer data)
{
  GList *new_list;
  GList *last;
  
  new_list = g_list_alloc ();
  new_list->data = data;
  
  if (list) {
    last = g_list_last (list);
    last->next = new_list;
    new_list->prev = last;
  }

  return new_list;
}


/* silent version of the lookup_widget that was provided by glade */
GtkWidget *lookup (GtkWidget *widget, const gchar *widget_name)
{
  GtkWidget *parent, *found_widget;

  for (;;) {
    if (GTK_IS_MENU (widget))
      parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
    else
      parent = widget->parent;
    if (parent == NULL)
      break;
    widget = parent;
  }

  found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
                                                   widget_name);
  return found_widget;
}


/*
 * Message Window						********
 */


/* display a message window, which self deletes when user hits ok */
void message (char *title, char *text)
{
  GtkWidget *widget, *label;

  widget = create_message ();
  gtk_window_set_title (GTK_WINDOW (widget), title);
  label = lookup (widget, "message_label");
  gtk_label_set (GTK_LABEL(label), text);
  gtk_widget_show (widget);
}


gboolean
on_message_delete_event                (GtkWidget       *widget,
                                        GdkEvent        *event,
                                        gpointer         user_data)
{
  gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET(widget)));
  return FALSE;
}


void
on_message_ok_clicked                  (GtkButton       *button,
                                        gpointer         user_data)
{
  gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET(button)));
}


/* called if a user hits an unimplemented function */
/*
void unimplemented (char *name)
{
  gchar *text = g_strdup_printf("Humble apologies ...\n"
				"the function you have chosen,\n"
				"%s,\n"
				"is not yet implemented.", name);
  message ("gfocustimer function unimplemented", text);
}
*/




/* binary tree comparison function */
int compare (gconstpointer  a, gconstpointer  b)
{
  const Window *c, *d;

  c = a;
  d = b;

  if (*c == *d) return 0;
  if (*c < *d) return 1;
  return -1;
}


/* return a string which is the path to the files saved by us */
char *file_prefix()
{
  char *home;
  char *ours;

  home = g_getenv ("HOME");
  if (home == NULL) home = "";
  ours = g_strdup_printf ("%s/%s", home, FILEDIRECTORY);

  if (mkdir (ours, 0700) != 0) {
    if (errno != EEXIST) {
      char *text;

      text = g_strdup_printf ("Request failed,\n"
			      "Could not create directory %s,\n"
			      "%s.", ours, g_strerror (errno));
      message ("gfocustimer save mkdir() failed", text);
      g_free (text);
      g_free (ours);
      return NULL;
    }
  }

  return ours;
}


/* return a string which is the name of today's per-day save file */
char *file_suffix()
{
  time_t now = time ( NULL );
  struct tm *tm = localtime ( &now );
  char *name;
  
  name = g_strdup_printf ("%04d-%02d-%02d", tm->tm_year+1900, 
			  tm->tm_mon+1, tm->tm_mday);
  return name;
}

/* timestamp in text */
char *log_stamp(time_t now)
{
  struct tm *tm = localtime ( &now );
  char *name;
  
  name = g_strdup_printf ("%04d-%02d-%02d %02d:%02d:%02d",
			  tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 
			  tm->tm_hour, tm->tm_min, tm->tm_sec);
  return name;
}

/* translate a time to text */
char *time_to_text(time_t time)
{
  char *new;
  struct tm tm;

  switch (pd.format) {
  case FORMAT_HH_MM:
  case FORMAT_HH_MM_SS:
    tm.tm_sec  = time % 60;
    time = time / 60;
    tm.tm_min  = time % 60;
    time = time / 60;
    tm.tm_hour = time % 24;
    time = time / 24;
    tm.tm_mday = time;
  default:
    break;
  }

  switch (pd.format) {
  case FORMAT_HH_MM:
    new = g_strdup_printf ("%02d:%02d", tm.tm_mday * 24 + tm.tm_hour,
			    tm.tm_min);
    break;
  case FORMAT_HH_MM_SS:
    new = g_strdup_printf ("%02d:%02d:%02d", tm.tm_mday * 24 + tm.tm_hour,
			    tm.tm_min, tm.tm_sec);
    break;
  case FORMAT_H_HH:
    new = g_strdup_printf("%4.2f",(float)time/3600.0);
    break;
  case FORMAT_H_HHHH:
    new = g_strdup_printf("%6.4f",(float)time/3600.0);
    break;
  default:
    new = g_strdup("");
  }

  return new;
}


/* translate text back into time (design by oetiker@ee.ethz.ch) */
time_t text_to_time(char *text)
{
  struct tm tm;
  float hours;

  if (*text == '\0') return 0;

  if (sscanf (text, "%2d:%2d:%2d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 3) {
    return (tm.tm_hour * 60 + tm.tm_min) * 60 + tm.tm_sec;
  }

  if (sscanf (text, "%2d:%2d", &tm.tm_hour, &tm.tm_min) == 2) {
    return (tm.tm_hour * 60 + tm.tm_min) * 60;
  }

  if (sscanf (text, "%f", &hours) == 1) {
    return hours*3600.0;
  }

  return 0;
}


/* given a widget in an entry window, return the entry window pointer */
struct ew *entry_of_widget (GtkWidget *widget)
{
  GtkWidget *parent;
  struct ew *found;

  for (;;) {
    if (GTK_IS_MENU (widget))
      parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
    else
      parent = widget->parent;
    if (parent == NULL)
      break;
    widget = parent;
  }

  found = (struct ew *) gtk_object_get_data (GTK_OBJECT (widget), POINTER);
  return found;
}


/*

http://cvs.gnome.org/lxr/source/gnome-core/gnome-terminal/gnome-terminal.c#295

*/

/* This really should be in GTK+
 */
gint
option_menu_get_history (GtkOptionMenu *option_menu)
{
  GtkWidget *active_widget;
  
  g_return_val_if_fail (GTK_IS_OPTION_MENU (option_menu), -1);
  
  active_widget = gtk_menu_get_active (GTK_MENU (option_menu->menu));
  
  if (active_widget)
    return g_list_index (GTK_MENU_SHELL (option_menu->menu)->children,
			 active_widget);
  else
    return -1;
}


int widget_get_int (GtkWidget *parent, char *name)
{
  GtkWidget *widget;

  widget = lookup (parent, name);
  if (widget == NULL) {
    int i;

    for(i=0;i<10;i++) {
      char *ours;

      ours = g_strdup_printf ("%s_%d", name, i);
      widget = lookup (parent, ours);
      g_free (ours);
      if (widget == NULL) break;

      if (GTK_IS_TOGGLE_BUTTON(widget)) {
	GtkToggleButton *toggle = GTK_TOGGLE_BUTTON(widget);
	if (toggle->active) {
	  return i;
	}
      }
    }
    return 0;
  }

  if (GTK_IS_SCALE(widget)) {
    GtkAdjustment *adjustment;
    adjustment = gtk_range_get_adjustment(GTK_RANGE(widget));
    return adjustment->value * 1000;
  }

  if (GTK_IS_TOGGLE_BUTTON(widget)) {
    GtkToggleButton *x = GTK_TOGGLE_BUTTON(widget);
    return x->active ? 1 : 0;
  }
  
  if (GTK_IS_OPTION_MENU(widget)) {
    return option_menu_get_history (GTK_OPTION_MENU(widget));
  }
  
  printf("widget_get_int: ... %s is an unhandled GtkWidget\n", name);
  return 0;
}


void widget_set_int (GtkWidget *parent, char *name, int value)
{
  GtkWidget *widget;

  widget = lookup (parent, name);
  if (widget == NULL) {
    char *ours;

    ours = g_strdup_printf ("%s_%d", name, value);
    widget = lookup (parent, ours);
    g_free (ours);
    if (widget != NULL) {
      if (GTK_IS_TOGGLE_BUTTON(widget)) {
	gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), TRUE);
      }
    }
    return;
  }

  if (GTK_IS_SCALE(widget)) {
    GtkAdjustment *adjustment;
    adjustment = gtk_range_get_adjustment(GTK_RANGE(widget));
    gtk_adjustment_set_value (adjustment, (float) value / 1000.0 );
    gtk_range_set_adjustment(GTK_RANGE(widget), adjustment);
    return;
  }

  if (GTK_IS_OPTION_MENU(widget)) {
    gtk_option_menu_set_history(GTK_OPTION_MENU(widget), value);
    return;
  }

  return;
}


/*
 * Question Window						********
 */
/* display a question window, calls back our function on ok */
void question (char *title, char *text,
		      void (*yes)(GtkButton *button, gpointer user_data),
		      gpointer user_data)
{
  GtkWidget *widget, *label, *ok;

  widget = create_question ();
  gtk_window_set_title (GTK_WINDOW (widget), title);
  label = lookup (widget, "question_label");
  gtk_label_set (GTK_LABEL(label), text);

  ok = lookup (widget, "question_ok");
  gtk_signal_connect (GTK_OBJECT (ok), "clicked",
                      GTK_SIGNAL_FUNC (yes),
                      user_data);

  gtk_widget_show (widget);
}


void
on_question_ok_clicked                 (GtkButton       *button,
                                        gpointer         user_data)
{

}


gboolean
on_question_delete_event               (GtkWidget       *widget,
                                        GdkEvent        *event,
                                        gpointer         user_data)
{
  gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET(widget)));
  return FALSE;
}


void
on_question_cancel_clicked             (GtkButton       *button,
                                        gpointer         user_data)
{
  gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET(button)));
}


