/*
 *  main_gtk.c -- portable gui library, GTK
 */

#include "gui.h"

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

char **gui_message;

struct gui_window_data *gui_window_list;       /* array of window details */
unsigned int gui_window_list_items;            /* length of windows list */
signed int gui_window_origin_x, gui_window_origin_y;

/* static void redraw_window_request(wimp_draw *redraw);
 * static void open_window_request(wimp_open *open);
 * static void close_window_request(wimp_close *close);
 * static void mouse_click(wimp_pointer *pointer);
 * static void key_pressed(wimp_key *key);
 * static void menu_selection(wimp_selection *selection);
 * static void user_message(wimp_message *message);
 * static void help_request(wimp_message *message, help_message_request *request);
 */


/****************************************************************************************/
/*  main()                                                                              */
/****************************************************************************************/

int main(int argc, char *argv[])
{
  gtk_set_locale();
  gtk_init(&argc, &argv);

  gui_initialise();
  task_initialise();

  gui_event_loop();

  task_finalise();

  gtk_exit(0);

  return 0;
}


/****************************************************************************************/
/*  Initialisation                                                                      */
/****************************************************************************************/

/*
 *  gui_initialise -- initialise the program with the os or window manager
 *
 *  => name -- program name to pass to the os if applicable
 *
 *  <= nothing
 */

void gui_initialise()
{
  char file_name[30];

  gui_log("gui_initialise: task_name = '%s'\n", task_name);

  if (setjmp(gui_error_jump))
  {
    gui_log("gui_initialise: *** error %i: %s ***\n", gui_error_line, gui_error_message);

    printf("%s (%i)\n", gui_error_message, gui_error_line);
    fflush(stdout);
    exit(1);
  }

  gui_window_list = NULL;
  gui_window_list_items = 0;

  sprintf(file_name, "%s_Messages", task_name);
  gui_message = gui_messages_read(getenv(file_name));

  gui_log("gui_initialise: finished\n");
}


/****************************************************************************************/
/*  Event handling                                                                      */
/****************************************************************************************/

/*
 *  gui_event_loop -- receive and handle os or window manager events
 *
 *  => nothing
 *
 *  <= does not return directly, except on exit
 */

static gui_window_id menu_window_id;

void gui_event_loop(void)
{
/*   if (setjmp(gui_error_jump))
 *   {
 *     gui_log("gui_event_loop: *** error %i: %s ***\n", gui_error_line, gui_error_message);
 *
 *     err.errnum = 1;
 *     sprintf(err.errmess, "%s (%i)\n", gui_error_message, gui_error_line);
 *     xwimp_report_error(&err, wimp_ERROR_BOX_OK_ICON, task_name, NULL);
 *   }
 */

  gtk_main();
}


/*
 *  redraw window request
 */

/* void redraw_window_request(wimp_draw *redraw)
 * {
 *   bool more;
 *   signed int invalid[4];
 *   gui_window_id window_id = gui_handle_to_window_id(redraw->w);
 *
 *   assert(window_id == gui_WINDOW_UNKNOWN ||
 *          (window_id < gui_window_list_items && gui_window_list[window_id].used));
 *
 *   gui_error = xwimp_redraw_window(redraw, &more);
 *   gui_check_error();
 *
 *   gui_window_origin_x = redraw->box.x0 - redraw->xscroll;
 *   gui_window_origin_y = redraw->box.y1 - redraw->yscroll;
 *
 *   gui_log("gui_event_loop: redraw origin %i %i\n", gui_window_origin_x, gui_window_origin_y);
 *
 *   while (more)
 *   {
 *     if (window_id != gui_WINDOW_UNKNOWN && gui_window_list[window_id].redraw_fn)
 *     {
 *       invalid[0] = redraw->clip.x0 - gui_window_origin_x;
 *       invalid[1] = gui_window_origin_y - redraw->clip.y1;
 *       invalid[2] = redraw->clip.x1 - gui_window_origin_x;
 *       invalid[3] = gui_window_origin_y - redraw->clip.y0;
 *
 *       gui_log("gui_event_loop: redraw invalid %i %i %i %i\n",
 *           invalid[0], invalid[1], invalid[2], invalid[3]);
 *
 *       gui_window_list[window_id].redraw_fn(window_id, invalid);
 *     }
 *     gui_error = xwimp_get_rectangle(redraw, &more);
 *     gui_check_error();
 *   }
 * }
 */


/*
 *  open window request
 */

/* void open_window_request(wimp_open *open)
 * {
 *   gui_window_id window_id = gui_handle_to_window_id(open->w);
 *
 *   gui_error = xwimp_open_window(open);
 *   gui_check_error();
 *
 *   if (window_id != gui_WINDOW_UNKNOWN)
 *   {
 *     assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
 *     if (open->visible.x1 - open->visible.x0 != gui_window_list[window_id].width ||
 *         open->visible.y1 - open->visible.y0 != gui_window_list[window_id].height)
 *     {
 *       gui_window_list[window_id].width = open->visible.x1 - open->visible.x0;
 *       gui_window_list[window_id].height = open->visible.y1 - open->visible.y0;
 *       if (gui_window_list[window_id].resize_fn)
 *         gui_window_list[window_id].resize_fn(window_id,
 *               gui_window_list[window_id].width, gui_window_list[window_id].height);
 *     }
 *   }
 * }
 */


/*
 *  close window request
 */

/* void close_window_request(wimp_close *close)
 * {
 *   gui_window_id window_id = gui_handle_to_window_id(close->w);
 *
 *   gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
 *
 *   if (window_id != gui_WINDOW_UNKNOWN)
 *   {
 *     assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
 *     gui_window_list[window_id].close_fn(window_id);
 *   }
 * }
 */


/*
 *  mouse click
 */

/* void mouse_click(wimp_pointer *pointer)
 * {
 *   gui_window_id window_id = gui_handle_to_window_id(pointer->w);
 *
 *   gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
 *
 *   if (window_id != gui_WINDOW_UNKNOWN)
 *   {
 *     assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
 *     if (gui_window_list[window_id].menu && (pointer->buttons & wimp_CLICK_MENU))
 *     {
 *       gui_error = xwimp_create_menu(gui_window_list[window_id].menu,
 *                        pointer->pos.x - 64, pointer->pos.y);
 *       gui_check_error();
 *       menu_window_id = window_id;
 *     }
 *     else if (gui_window_list[window_id].click_fn)
 *     {
 *       unsigned int x, y, z;
 *       wimp_window_state state;
 *
 *       state.w = pointer->w;
 *       gui_error = xwimp_get_window_state(&state);
 *       gui_check_error();
 *
 *       x = pointer->pos.x - (state.visible.x0 - state.xscroll);
 *       y = (state.visible.y1 - state.yscroll) - pointer->pos.y;
 *       z = (pointer->buttons & wimp_CLICK_SELECT ? gui_CLICK :
 *           (pointer->buttons & wimp_CLICK_ADJUST ? gui_CLICK_RIGHT :
 *           (pointer->buttons & wimp_DRAG_SELECT  ? gui_DRAG :
 *           (pointer->buttons & wimp_DRAG_ADJUST  ? gui_DRAG_RIGHT : 0))));
 *       gui_window_list[window_id].click_fn(window_id, x, y, z);
 *     }
 *   }
 * }
 */


/*
 *  key pressed
 */

/* void key_pressed(wimp_key *key)
 * {
 *   gui_window_id window_id = gui_handle_to_window_id(key->w);
 *
 *   gui_log("gui_event_loop: window_id = 0x%x\n", window_id);
 *
 *   if (window_id != gui_WINDOW_UNKNOWN)
 *   {
 *     assert(window_id < gui_window_list_items && gui_window_list[window_id].used);
 *
 *     if ((key->c & (1<<31)) || (key->c < 256))
 *     {
 *       if (gui_window_list[window_id].input_fn)
 *         gui_window_list[window_id].input_fn(window_id, (wchar_t) (key->c & 0xffff));
 *     }
 *     else
 *     {
 *       if (gui_window_list[window_id].key_fn)
 *         gui_window_list[window_id].key_fn(window_id, (unsigned int) key->c);
 *     }
 *   }
 * }
 */


/*
 *  menu selection
 */

/* void menu_selection(wimp_selection *selection)
 * {
 *   wimp_pointer pointer;
 *
 *   gui_error = xwimp_get_pointer_info(&pointer);
 *   gui_check_error();
 *
 *   gui_window_list[menu_window_id].menu_fn(menu_window_id, selection->items);
 *
 *   if (pointer.buttons == wimp_CLICK_ADJUST)
 *   {
 *     gui_error = xwimp_create_menu(gui_window_list[menu_window_id].menu, 0, 0);
 *     gui_check_error();
 *   }
 * }
 */


/*
 *  user message, user message recorded
 */

/* void user_message(wimp_message *message)
 * {
 *   gui_log("gui_event_loop: block.message.action = 0x%x\n", message->action);
 *
 *   switch (message->action)
 *   {
 *     case message_QUIT:
 *       quit = 1;
 *       break;
 *     case message_HELP_REQUEST:
 *       help_request(message, (help_message_request *) &message->data);
 *       break;
 *   }
 * }
 */

/*
 *  interactive help request
 */

/* void help_request(wimp_message *message, help_message_request *request)
 * {
 *   const char *help;
 *   wimp_message reply;
 *   gui_window_id window_id = gui_handle_to_window_id(request->w);
 *
 *   if (window_id != gui_WINDOW_UNKNOWN)
 *   {
 *     if (gui_window_list[window_id].used == DIALOG && request->i >= 0)
 *       help = gui_window_list[window_id].icon[request->i].help;
 *     else
 *       help = gui_window_list[window_id].help;
 *
 *     gui_log(help);
 *     reply.size = (20 + strlen(help) + 3) & ~3;
 *     reply.your_ref = message->my_ref;
 *     reply.action = message_HELP_REPLY;
 *     strcpy(&reply.data.reserved, help);
 *     gui_error = xwimp_send_message(wimp_USER_MESSAGE, &reply, message->sender);
 *     gui_check_error();
 *   }
 * }
 */
