/*
 * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
 * All rights reserved.
 *
 * 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.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <signal.h>

#include <gtk/gtk.h>

#include "traffic.h"

static GtkWidget *window, *drawing_area;

static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
	return FALSE;
}

static void destroy(GtkWidget *widget, gpointer data)
{
	gtk_main_quit();
}

static gboolean gui_draw_objects(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
	int width, height;
	struct car *c;
	struct light *l;
	GdkGC *gc_green = gdk_gc_new(widget->window);
	GdkGC *gc_red = gdk_gc_new(widget->window);
	GdkColor red = {0xff0000, 0, 0, 0};
	GdkColor green = {0x00ff00, 0, 0, 0};

	gdk_gc_set_foreground(gc_green, &green);
	gdk_gc_set_foreground(gc_red, &red);

	gdk_drawable_get_size(widget->window, &width, &height);

	list_for_each_entry(l, &light_list, light_entry) {
		if (l->state == LIGHT_RED)
			gdk_draw_arc(widget->window, gc_red, TRUE,
				l->x, height/2, 7, 7, 0, 360*64);
		else
			gdk_draw_arc(widget->window, gc_green, TRUE,
				l->x, height/2, 7, 7, 0, 360*64);
	}

	list_for_each_entry(c, &car_list, car_entry) {
		gdk_draw_arc(widget->window, widget->style->black_gc, TRUE,
				c->x, height/2, 2, 2, 0, 360*64);
	}
	
	gdk_gc_destroy(gc_green);
	gdk_gc_destroy(gc_red);

	return TRUE;
}

static void usage(char *p)
{
	g_print("Usage: %s -h\n", p);
}

static void alarm_signal(int signo)
{
	int width, height;

	gdk_drawable_get_size(drawing_area->window, &width, &height);
	car_update_all(width);

	gdk_window_invalidate_rect(drawing_area->window, NULL, FALSE);
}

static void timer_setup(void)
{
	struct itimerval it;
	struct sigaction sg;

	memset(&sg, 0, sizeof(sg));
	sg.sa_handler = alarm_signal;
	sigaction(SIGALRM, &sg, 0);
	it.it_interval.tv_sec = 0;
	it.it_interval.tv_usec = 50000;
	it.it_value.tv_sec = 0;
	it.it_value.tv_usec = 1;
	if (setitimer(ITIMER_REAL, &it, 0))
		perror("setitimer");
}


int main(int argc, char *argv[])
{
	int err;

	err = car_main(argc, argv);
	if (err)
		return err;

	gtk_init(&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_window_set_title(GTK_WINDOW(window), "Traffic simulator");

	g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
	g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);

	drawing_area = gtk_drawing_area_new();
	gtk_widget_set_size_request(drawing_area, 500, 100);

	g_signal_connect(G_OBJECT(drawing_area), "expose_event", G_CALLBACK(gui_draw_objects), NULL);

	gtk_container_add(GTK_CONTAINER(window), drawing_area);

	/* The final step is to display this newly created widget. */
	gtk_widget_show(drawing_area);
	gtk_widget_show(window);

	timer_setup();

	gtk_main();

	return 0;
}


