/***************************************************************
                           gui.h
 ***************************************************************/

module allegro.gui;

import allegro.gfx;
import allegro.internal.dversion;
import allegro.internal._export;


alias extern (C) int (*DIALOG_PROC)(int msg, DIALOG *d, int c);


struct DIALOG
{
   DIALOG_PROC proc;
   int x, y, w, h;               /* position and size of the object */
   int fg, bg;                   /* foreground and background colors */
   int key;                      /* keyboard shortcut (ASCII code) */
   int flags;                    /* flags about the object state */
   int d1, d2;                   /* any data the object might require */
   void* dp, dp2, dp3;           /* pointers to more object data */
}


/* a popup menu */
struct MENU
{
   stringz text;                 /* menu item text */
   extern (C) int (*proc)();     /* callback function */
   MENU *child;                  /* to allow nested menus */
   int flags;                    /* flags about the menu state */
   void *dp;                     /* any data the menu might require */
}


/* stored information about the state of an active GUI dialog */
struct DIALOG_PLAYER
{
   int obj;
   int res;
   int mouse_obj;
   int focus_obj;
   int joy_on;
   int click_wait;
   int mouse_ox, mouse_oy;
   int mouse_oz;
   int mouse_b;
   DIALOG *dialog;
}


/* stored information about the state of an active GUI menu */
struct MENU_PLAYER
{
   MENU *menu;                      /* the menu itself */
   int bar;                         /* set if it is a top level menu bar */
   int size;                        /* number of items in the menu */
   int sel;                         /* selected item */
   int x, y, w, h;                  /* screen position of the menu */
   extern (C) int (*proc)();        /* callback function */
   BITMAP *saved;                   /* saved what was underneath it */
   
   int mouse_button_was_pressed;    /* set if mouse button pressed on last iteration */
   int back_from_child;             /* set if a child was activated on last iteration */    
   int timestamp;                   /* timestamp for gui_timer events */
   int mouse_sel;                   /* item the mouse is currently over */
   int redraw;                      /* set if redrawing is required */
   int auto_open;                   /* set if menu auto-opening is activated */
   int ret;                         /* return value */
   
   DIALOG *dialog;                  /* d_menu_proc() parent dialog (if any) */
   
   MENU_PLAYER *parent;             /* the parent menu, or NULL for root */
   MENU_PLAYER *child;              /* the child menu, or NULL for none */
}


/* bits for the flags field */
enum {
   D_EXIT        = 1,        /* object makes the dialog exit */
   D_SELECTED    = 2,        /* object is selected */
   D_GOTFOCUS    = 4,        /* object has the input focus */
   D_GOTMOUSE    = 8,        /* mouse is on top of object */
   D_HIDDEN      = 16,       /* object is not visible */
   D_DISABLED    = 32,       /* object is visible but inactive */
   D_DIRTY       = 64,       /* object needs to be redrawn */
   D_INTERNAL    = 128,      /* reserved for internal use */
   D_USER        = 256,      /* from here on is free for your own use */
}

/* return values for the dialog procedures */
enum {
   D_O_K           = 0,      /* normal exit status */
   D_CLOSE         = 1,      /* request to close the dialog */
   D_REDRAW        = 2,      /* request to redraw the dialog */
   D_REDRAWME      = 4,      /* request to redraw this object */
   D_WANTFOCUS     = 8,      /* this object wants the input focus */
   D_USED_CHAR     = 16,     /* object has used the keypress */
   D_REDRAW_ALL    = 32,     /* request to redraw all active dialogs */
   D_DONTWANTMOUSE = 64,     /* this object does not want mouse focus */
}

/* messages for the dialog procedures */
enum {
   MSG_START     = 1,        /* start the dialog, initialise */
   MSG_END       = 2,        /* dialog is finished - cleanup */
   MSG_DRAW      = 3,        /* draw the object */
   MSG_CLICK     = 4,        /* mouse click on the object */
   MSG_DCLICK    = 5,        /* double click on the object */
   MSG_KEY       = 6,        /* keyboard shortcut */
   MSG_CHAR      = 7,        /* other keyboard input */
   MSG_UCHAR     = 8,        /* unicode keyboard input */
   MSG_XCHAR     = 9,        /* broadcast character to all objects */
   MSG_WANTFOCUS = 10,       /* does object want the input focus? */
   MSG_GOTFOCUS  = 11,       /* got the input focus */
   MSG_LOSTFOCUS = 12,       /* lost the input focus */
   MSG_GOTMOUSE  = 13,       /* mouse on top of object */
   MSG_LOSTMOUSE = 14,       /* mouse moved away from object */
   MSG_IDLE      = 15,       /* update any background stuff */
   MSG_RADIO     = 16,       /* clear radio buttons */
   MSG_WHEEL     = 17,       /* mouse wheel moved */
   MSG_LPRESS    = 18,       /* mouse left button pressed */
   MSG_LRELEASE  = 19,       /* mouse left button released */
   MSG_MPRESS    = 20,       /* mouse middle button pressed */
   MSG_MRELEASE  = 21,       /* mouse middle button released */
   MSG_RPRESS    = 22,       /* mouse right button pressed */
   MSG_RRELEASE  = 23,       /* mouse right button released */
   MSG_WANTMOUSE = 24,       /* does object want the mouse? */
   MSG_USER      = 25,       /* from here on are free... */
}


/* some dialog procedures */
extern (C) {

int d_yield_proc (int msg, DIALOG *d, int c);
int d_clear_proc (int msg, DIALOG *d, int c);
int d_box_proc (int msg, DIALOG *d, int c);
int d_shadow_box_proc (int msg, DIALOG *d, int c);
int d_bitmap_proc (int msg, DIALOG *d, int c);
int d_text_proc (int msg, DIALOG *d, int c);
int d_ctext_proc (int msg, DIALOG *d, int c);
int d_rtext_proc (int msg, DIALOG *d, int c);
int d_button_proc (int msg, DIALOG *d, int c);
int d_check_proc (int msg, DIALOG *d, int c);
int d_radio_proc (int msg, DIALOG *d, int c);
int d_icon_proc (int msg, DIALOG *d, int c);
int d_keyboard_proc (int msg, DIALOG *d, int c);
int d_edit_proc (int msg, DIALOG *d, int c);
int d_list_proc (int msg, DIALOG *d, int c);
int d_text_list_proc (int msg, DIALOG *d, int c);
int d_textbox_proc (int msg, DIALOG *d, int c);
int d_slider_proc (int msg, DIALOG *d, int c);
int d_menu_proc (int msg, DIALOG *d, int c);

} // extern (C)

mixin(_export!(`
   extern (C) {
      extern DIALOG_PROC gui_shadow_box_proc;
      extern DIALOG_PROC gui_ctext_proc;
      extern DIALOG_PROC gui_button_proc;
      extern DIALOG_PROC gui_edit_proc;
      extern DIALOG_PROC gui_list_proc;
      extern DIALOG_PROC gui_text_list_proc;
   }
`));

mixin(_export!(`
   extern (C) {
   
      extern void (*gui_menu_draw_menu) (int x, int y, int w, int h);
      extern void (*gui_menu_draw_menu_item) (MENU *m, int x, int y, int w, int h, int bar, int sel);
   
      extern DIALOG * active_dialog;
      extern MENU * active_menu;
   
      extern int gui_mouse_focus;
   
      extern int gui_fg_color;
      extern int gui_mg_color;
      extern int gui_bg_color;
   
      extern int gui_font_baseline;
   
      extern int (*gui_mouse_x) ();
      extern int (*gui_mouse_y) ();
      extern int (*gui_mouse_z) ();
      extern int (*gui_mouse_b) ();
   
   }  // extern (C)
`));


extern (C) {

void gui_set_screen (BITMAP *bmp);
BITMAP * gui_get_screen ();
int gui_textout_ex (BITMAP *bmp, in char *s, int x, int y, int color, int bg, int centre);
int gui_strlen (in char *s);
void position_dialog (DIALOG *dialog, int x, int y);
void centre_dialog (DIALOG *dialog);
void set_dialog_color (DIALOG *dialog, int fg, int bg);
int find_dialog_focus (DIALOG *dialog);
int offer_focus (DIALOG *dialog, int obj, int *focus_obj, int force);
int object_message (DIALOG *dialog, int msg, int c);
int dialog_message (DIALOG *dialog, int msg, int c, int *obj);
int broadcast_dialog_message (int msg, int c);
int do_dialog (DIALOG *dialog, int focus_obj);
int popup_dialog (DIALOG *dialog, int focus_obj);
DIALOG_PLAYER * init_dialog (DIALOG *dialog, int focus_obj);
int update_dialog (DIALOG_PLAYER *player);
int shutdown_dialog (DIALOG_PLAYER *player);
int do_menu (MENU *menu, int x, int y);
MENU_PLAYER * init_menu (MENU *menu, int x, int y);
int update_menu (MENU_PLAYER *player);
int shutdown_menu (MENU_PLAYER *player);
int alert (in char *s1, in char *s2, in char *s3, in char *b1, in char *b2, int c1, int c2);
int alert3 (in char *s1, in char *s2, in char *s3, in char *b1, in char *b2, in char *b3, int c1, int c2, int c3);
int file_select_ex (in char *message, char *path, in char *ext, int size, int w, int h);

int gfx_mode_select (int *card, int *w, int *h);
int gfx_mode_select_ex (int *card, int *w, int *h, int *color_depth);
int gfx_mode_select_filter (int *card, int *w, int *h, int *color_depth, int (*filter)(int, int, int, int));

}  // extern (C)
