/*
 *  gui_gtk.h -- portable gui library, GTK header
 */

#include <gtk/gtk.h>

typedef gboolean bool;

struct gui_menu_data;

typedef unsigned int gui_window_id;
#define gui_WINDOW_UNKNOWN ((gui_window_id) 0xffffffff)
typedef GtkWidget *gui_gadget_id;
typedef struct gui_menu_data *gui_menu_id;

/*extern wimp_t gui_wimp_task;                          /* wimp task handle */
/*extern os_error *gui_error;                           /* last error block pointer */
extern const char *gui_error_message;                 /* last error message */
extern int gui_error_line;                            /* last error line */
extern jmp_buf gui_error_jump;                        /* longjmp buffer for error handling */

struct gui_window_data
{
  enum { UNUSED, WINDOW, DIALOG } used;
  GtkWindow *handle;
  char *title;
  void (*close_fn)(gui_window_id window_id);
  void (*redraw_fn)(gui_window_id window_id, unsigned int invalid[]);
  void (*click_fn)(gui_window_id window_id, unsigned int x, unsigned int y, unsigned int z);
  void (*resize_fn)(gui_window_id window_id, unsigned int width, unsigned int height);
  void (*key_fn)(gui_window_id window_id, unsigned int key);
  void (*input_fn)(gui_window_id window_id, wchar_t key);
  void (*menu_fn)(gui_window_id window_id, unsigned int items[]);
  unsigned int width, height;
  struct gui_menu_data *menu;
/*  wimp_menu *menu;
  wimp_w *bbar;*/
//  struct gui_dialog_icon *icon;
  const char *help;
  GtkDrawingArea *drawing_area;
};
extern struct gui_window_data *gui_window_list;           /* array of window details */
extern unsigned int gui_window_list_items;                /* length of windows list */

extern gui_window_id gui_get_free_window_id(void);
extern gui_window_id gui_handle_to_window_id(GtkWidget *handle);
extern gui_window_id menu_window_id;
extern signed int gui_window_origin_x, gui_window_origin_y;
extern GtkWidget *gui_redraw_widget;

#define WINDOW_LIST_CHUNK 20

struct gui_menu_data
{
  unsigned int size;
  GtkWidget *menu;
  GtkWidget **item;
  struct gui_menu_data *parent;
  unsigned int i;
};

struct gui_ta_style
{
  unsigned int xsize;
  unsigned int ysize;
  unsigned int fcolour;
  unsigned int bcolour;
  unsigned int space;
  GdkFont *handle;
  char font[1];
};

#define gui_SIZEOF_GUI_TA_STYLE(n) (offsetof(struct gui_ta_style, font) + (n) * sizeof(char))


#define KEY_BACKSPACE 1
#define KEY_RETURN 2
#define KEY_ESCAPE 3
#define KEY_HOME 4
#define KEY_DELETE 5
#define KEY_SHIFT 6
#define KEY_CONTROL 7
#define KEY_PRINT 8
#define KEY_F1 1
#define KEY_F2 2
#define KEY_F3 3
#define KEY_F4 4
#define KEY_F5 5
#define KEY_F6 6
#define KEY_F7 7
#define KEY_F8 8
#define KEY_F9 9
#define KEY_TAB 10
#define KEY_COPY 11
#define KEY_LEFT 12
#define KEY_RIGHT 13
#define KEY_LOGO 14
#define KEY_MENU 15
#define KEY_F10 16
#define KEY_F11 17
#define KEY_F12 18
#define KEY_INSERT 19
#define KEY_DOWN 20
#define KEY_UP 21
#define KEY_PAGE_DOWN 22
#define KEY_PAGE_UP 23



#define BGR_TO_GDK(colour, gdk_colour) gdk_colour.red = ((colour & 0xff) << 8) | (colour & 0xff); \
  gdk_colour.green = (colour & 0xff00) | ((colour & 0xff00) >> 8); \
  gdk_colour.blue = ((colour & 0xff0000) >> 8) | ((colour & 0xff0000) >> 16)




/*
 *  Error handling
 */

/*
 *  gui_check_error -- check for an error after a swi
 */

/* #define gui_check_error() if (gui_error) { gui_error_message = gui_error->errmess; gui_error_line = __LINE__; longjmp(gui_error_jump, 1); }  */

/*
 *  gui_raise_error -- generate an error
 */

#define gui_raise_error(message) { gui_error_message = (message); gui_error_line = __LINE__; longjmp(gui_error_jump, 1); }


/*
 *  assert
 */

#ifdef DEBUG
  #define assert(expression) ((void) ((expression) ? 0 : (printf("%s:%u: *** assert(" #expression ") failed ***\n", __FILE__, __LINE__), exit(EXIT_FAILURE), 0)))
#else
  #define assert(expression) ((void) 0)
#endif
