#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <pthread.h>

gint number;
gboolean negative, timer;

void *counter(void *raw_status)
{
  GtkWidget *status = GTK_WIDGET(raw_status);
  gchar *message;
  glong counter;
  guint id;

  id = gtk_statusbar_get_context_id(GTK_STATUSBAR(status), "timer");
  message = malloc(2048*sizeof(gchar));

  for (counter = 0; ; counter++) {
    while (!timer) ;
    g_snprintf(message, 2048, "%ld", counter);
    printf("%ld\n", counter);
    gdk_threads_enter();
    gtk_statusbar_pop(GTK_STATUSBAR(status), id);
    gtk_statusbar_push(GTK_STATUSBAR(status), id, message);
    gdk_threads_leave();
    sleep(1);
  }

  return NULL;
}

void update_number(gint new_number, GtkWidget *new_entry)
{
  char *text;
  
  static GtkWidget *entry;
  if (new_entry != NULL)
    entry = new_entry;
  
  number = new_number;
  asprintf(&text, "%d", number);
  gtk_entry_set_text(GTK_ENTRY(entry), text);
  free(text);
}

void button_clicked(GtkWidget *button, gpointer data)
{
  gint new_number = GPOINTER_TO_INT(data);
  update_number(number + (new_number * (negative ? -1 : 1)), NULL);
}

void toggle_negative()
{
  negative = !negative;
}

void toggle_timer()
{
  timer = !timer;
}

int main(int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *table;
  GtkWidget *box, *hbox;
  GtkWidget *checkbox;
  GtkWidget *entry;
  GtkWidget *status;
  pthread_t thread;
  
  g_thread_init(NULL);
  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "Counter Whatzit");
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
		     GTK_SIGNAL_FUNC(gtk_exit), NULL);
  gtk_signal_connect(GTK_OBJECT(window), "destroy_event",
		     GTK_SIGNAL_FUNC(gtk_exit), NULL);

  box = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(window), box);
  gtk_widget_show(box);
  
  table = gtk_table_new(3, 3, 1);
  gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
  gtk_widget_show(table);

  {
    GtkWidget *button;
    gint i;
    char name[2];

    for (i = 0; i < 9; i++) {
      sprintf(name, "%d", i + 1);
      button = gtk_button_new_with_label(name);
      gtk_table_attach_defaults(GTK_TABLE(table), button,
				i % 3, (i % 3) + 1,
				i / 3, (i / 3) + 1);
      gtk_signal_connect(GTK_OBJECT(button), "clicked",
			 GTK_SIGNAL_FUNC(button_clicked), GINT_TO_POINTER(i + 1));
      gtk_widget_show(button);
    }
  }

  hbox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, TRUE, 0);
  gtk_widget_show(hbox);
  
  checkbox = gtk_check_button_new_with_label("Negative");
  gtk_signal_connect(GTK_OBJECT(checkbox), "toggled",
		     GTK_SIGNAL_FUNC(toggle_negative), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, TRUE, 0);
  gtk_widget_show(checkbox);

  checkbox = gtk_check_button_new_with_label("Timer");
  gtk_signal_connect(GTK_OBJECT(checkbox), "toggled",
		     GTK_SIGNAL_FUNC(toggle_timer), NULL);
  gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, TRUE, 0);
  gtk_widget_show(checkbox);
  
  entry = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
  gtk_box_pack_start(GTK_BOX(box), entry, FALSE, TRUE, 0);
  update_number(0, entry);
  gtk_widget_show(entry);

  status = gtk_statusbar_new();
  gtk_box_pack_end(GTK_BOX(box), status, FALSE, TRUE, 0);
  gtk_widget_show(status);

  gtk_widget_show(window);

  negative = timer = FALSE;

  pthread_create(&thread, NULL, counter, status);
  
  gdk_threads_enter();
  gtk_main();
  gdk_threads_leave();

  return 0;
}
