#include <gtk/gtk.h>
#include <gtk/gtktoolbar.h>

#include <gdk/gdkkeysyms.h>

#include <glib.h>
#include <glib-object.h>

#include "zft.h"

#define PRINT_SPOT printf("file: %s, line: %d\n", __FILE__, __LINE__)

#define ZFT_TOOLBAR_TYPE           	(zft_toolbar_get_type ())
#define ZFT_TOOLBAR(obj)           	(G_TYPE_CHECK_INSTANCE_CAST ((obj), ZFT_TOOLBAR_TYPE, ZftToolbar))
#define ZFT_TOOLBAR_CLASS(klass)   	(G_TYPE_CHECK_CLASS_CAST ((klass), ZFT_TOOLBAR_TYPE, ZftToolbarClass))
#define IS_ZFT_TOOLBAR(obj)        	(G_TYPE_CHECK_INSTANCE_TYPE ((obj), ZFT_TOOLBAR_TYPE))
#define IS_ZFT_TOOLBAR_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), ZFT_TOOLBAR_TYPE))

typedef struct _ZftToolbar       ZftToolbar;
typedef struct _ZftToolbarClass  ZftToolbarClass;

struct _ZftToolbar
{
    GtkToolbar toolbar;
    
    EditState edit_state; 
    
    /* flux */
    GtkWidget* add_control_point_button;

    /* static enemies */
    GtkWidget* add_hive_button;
    GtkWidget* add_landscape_object_button;
    GtkWidget* add_turret_button;
    GtkWidget* add_laser_turret_button;

    /* dynamic enemy spawn points */
    GtkWidget* add_wasp_button;
    GtkWidget* add_drone_button;
    GtkWidget* add_eel_button;

    /* remove button */
    GtkWidget* remove_button;
};

struct _ZftToolbarClass
{
    GtkToolbarClass parent_class;
    
    /* this has to do with the classes signels, not actually needed at the moment */
    void (* zft_toolbar) (ZftToolbar *zft_t);
};

/* declaration of the toolbar itself */
static ZftToolbar* zft_toolbar;

/* prototypes */
static void
zft_toolbar_class_init(ZftToolbarClass *klass);
 
static void
zft_toolbar_init(ZftToolbar* zft_toolbar);

/**
 * This function tells Glib about the zft_toolbar class and returns an ID that uniquely identifies the class.
 **/
GType
zft_toolbar_get_type(void)
{
    static GType zft_toolbar_type = 0;
    
    if(!zft_toolbar_type)
    {
	static const GTypeInfo zft_toolbar_info = 
	    {
		sizeof(ZftToolbarClass),
		NULL, /* base init */
		NULL, /* base finalize */
		(GClassInitFunc)zft_toolbar_class_init,
		NULL, /* class finalize */
		NULL, /* class data */
		sizeof(ZftToolbar),
		0, /* num preallocs */
		(GInstanceInitFunc)zft_toolbar_init,
	    };
	
	zft_toolbar_type = g_type_register_static(GTK_TYPE_TOOLBAR,
						  "ZftToolbar",
						  &zft_toolbar_info,
						  0);
    }
    
    return zft_toolbar_type;
}

/* set the activeness of a state button in the toolbar */
static void
set_state_button(unsigned int state, bool activeness)
{
    GtkToggleButton* state_button = 0;

    /* get a pointer to the right button based on state */
    switch(state)
    {
    case ADD_CONTROL_POINT:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_control_point_button);
	break;
	
    case ADD_HIVE:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_hive_button);
	break;

    case ADD_LANDSCAPE_OBJECT:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_landscape_object_button);
	break;
	
    case ADD_TURRET:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_turret_button);
	break;

    case ADD_LASER_TURRET:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_laser_turret_button);
	break;

    case ADD_WASP:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_wasp_button);
	break;

    case ADD_DRONE:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_drone_button);
	break;

    case ADD_EEL:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->add_eel_button);
	break;

    case REMOVE:
	state_button = GTK_TOGGLE_BUTTON(zft_toolbar->remove_button);
	break;
	
    default:
	printf("%s() : ERROR : unknown toolbar state\n", __FUNCTION__);
	break;
    }

    /* set button activeness */
    gtk_toggle_button_set_active(state_button, activeness);
}

static void
button_pressed(GtkWidget* widget,
               gpointer data)               
{
    unsigned int new_state;
    unsigned int old_state;
    
    //printf("%s() : START\n", __FUNCTION__);
    
    /* debug */
    new_state = 0;

    old_state = zft_get_edit_state();

    if(widget == zft_toolbar->add_control_point_button)
    {
        new_state = ADD_CONTROL_POINT;
    }
    else if(widget == zft_toolbar->add_hive_button)
    {
        new_state = ADD_HIVE;
    }
    else if(widget == zft_toolbar->add_landscape_object_button)
    {
        new_state = ADD_LANDSCAPE_OBJECT;
    }
    else if(widget == zft_toolbar->add_turret_button)
    {
	new_state = ADD_TURRET;
    }
    else if(widget == zft_toolbar->add_laser_turret_button)
    {
	new_state = ADD_LASER_TURRET;
    }
    else if(widget == zft_toolbar->add_wasp_button)
    {
	new_state = ADD_WASP;
    }
    else if(widget == zft_toolbar->add_drone_button)
    {
        new_state = ADD_DRONE;
    }
    else if(widget == zft_toolbar->add_eel_button)
    {
	new_state = ADD_EEL;
    }
    else if(widget == zft_toolbar->remove_button)
    {
	new_state = REMOVE;
    }

    /* if new and old state are same, do nothing, turns out to be important */
    if (new_state == old_state)
    {
	//printf("%s() : END : same state\n", __FUNCTION__);
	return;
    }

    /* deactivate old_state button, set to new state and active new state button */
    set_state_button(old_state, false);
    zft_set_edit_state(new_state);
    set_state_button(new_state, true);

    //printf("%s() : END\n", __FUNCTION__);
}

/**
 * ZftToolbar class initialisation function. This does nothing but may need to be implemented
 * if this widget is to emit signals.
 **/
static void
zft_toolbar_class_init(ZftToolbarClass *klass)
{
}
 
/**
 * ZftToolbar widget initialisation function.
 **/
static void
zft_toolbar_init(ZftToolbar* zft_toolbar)
{
    zft_toolbar->edit_state = zft_get_edit_state();
    
    zft_toolbar->add_control_point_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
                                                                       GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
                                                                       NULL,
                                                                       "Add Control Point",
                                                                       "Changes the flux edit mode to add more control points",
                                                                       "Private",
                                                                       NULL,
                                                                       GTK_SIGNAL_FUNC(button_pressed),
                                                                       (gpointer)zft_toolbar);
    
    
    zft_toolbar->add_hive_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
							      GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
							      NULL,
							      "Add Hive",
							      "Changes edit mode to add a hive",
							      "Private",
							      NULL,
							      GTK_SIGNAL_FUNC(button_pressed),
							      (gpointer)zft_toolbar);

    zft_toolbar->add_landscape_object_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
									  GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
									  NULL,
									  "Add Landscape Object",
									  "Changes edit mode to add a landscape object",
									  "Private",
									  NULL,
									  GTK_SIGNAL_FUNC(button_pressed),
									  (gpointer)zft_toolbar);
    
    zft_toolbar->add_turret_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
								GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
								NULL,
								"Add Turret",
								"Changes edit mode to add a turret",
								"Private",
								NULL,
								GTK_SIGNAL_FUNC(button_pressed),
								(gpointer)zft_toolbar);
    
    zft_toolbar->add_laser_turret_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
								      GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
								      NULL,
								      "Add Laser Turret",
								      "Changes edit mode to add a laser turret",
								      "Private",
								      NULL,
								      GTK_SIGNAL_FUNC(button_pressed),
								      (gpointer)zft_toolbar);
    
    zft_toolbar->add_wasp_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
							      GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
							      NULL,
							      "Add Wasp",
							      "Changes edit mode to add a wasp ",
							      "Private",
							      NULL,
							      GTK_SIGNAL_FUNC(button_pressed),
							      (gpointer)zft_toolbar);
    
    zft_toolbar->add_drone_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
                                                               GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
                                                               NULL,
                                                               "Add Drone",
                                                               "Changes edit mode to add a drone ",
                                                               "Private",
                                                               NULL,
                                                               GTK_SIGNAL_FUNC(button_pressed),
                                                               (gpointer)zft_toolbar);
    
    zft_toolbar->add_eel_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
							     GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
							     NULL,
							     "Add Eel",
							     "Changes edit mode to add an eel",
							     "Private",
							     NULL,
							     GTK_SIGNAL_FUNC(button_pressed),
							     (gpointer)zft_toolbar);
    
    zft_toolbar->remove_button = gtk_toolbar_append_element(GTK_TOOLBAR(zft_toolbar),
							    GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
							    NULL,
							    "Remove",
							    "Changes edit mode to remove an element",
							    "Private",
							    NULL,
							    GTK_SIGNAL_FUNC(button_pressed),
							    (gpointer)zft_toolbar);
    
    gtk_toolbar_set_orientation(GTK_TOOLBAR(zft_toolbar), GTK_ORIENTATION_VERTICAL);
}

/**
 * Creates a new toolbar.
 **/
GtkWidget*
zft_toolbar_new()
{
    zft_toolbar = g_object_new(zft_toolbar_get_type(), NULL);

    set_state_button(ADD_CONTROL_POINT, true);

    return GTK_WIDGET(zft_toolbar);
}
