/* -*- ObjC -*- */
#ifndef __included_gui_h
#define __included_gui_h

#include <objc/Object.h>

#define mouse_in(x, y, w, h)	((mouse_x >= x) && (mouse_x < x + w) &&	\
				 (mouse_y >= y) && (mouse_y < y + h))

@class Widget;
struct BITMAP;

/*------------------------------------------------------------*/
/* Protocols.                                                 */
/*------------------------------------------------------------*/

@protocol Container
- (void) receiveMessage:(int)msg :(int)data fromChild:(Widget *)child;
@end

/*------------------------------------------------------------*/
/* Colours.                                                   */
/*------------------------------------------------------------*/

extern int black, blue, green, red, white;
extern int cyan, magenta, yellow;
extern int pawblue, pawgreen, pawpink;

/*------------------------------------------------------------*/
/* Messages/Flags.                                            */
/*------------------------------------------------------------*/

enum {
    MSG_CANCEL = -2,
    MSG_OK = -1,
    MSG_REDRAW = 1,

    MSG_KEY_PRESSED = 10,		/* The key is stored in data. */
    MSG_KEY_HELD = 11,			/* The key is stored in data. */
    MSG_KEY_RELEASED = 12,		/* The key is stored in data. */

    MSG_MOUSE_PRESSED = 20,		/* Mouse button stored in data. */
    MSG_MOUSE_HELD = 21,		/* Mouse button stored in data. */
    MSG_MOUSE_RELEASED = 22,		/* Mouse button stored in data. */
    MSG_MOUSE_WHEEL = 23,		/* Change in wheel stored in data. */
    MSG_MOUSE_ENTER = 24,
    MSG_MOUSE_EXIT = 25,

    MSG_RADIO_UNTOGGLE = 50,		/* Button group stored in data. */
    MSG_HSLIDER = 51,
    MSG_VSLIDER = 52
};

enum {
    FLAG_GOT_FOCUS = 0x01,
    FLAG_SELECTED = 0x02,
    FLAG_DIRTY = 0x10
};


/*------------------------------------------------------------*/
/* Widget.                                                    */
/*------------------------------------------------------------*/


@interface Widget: Object
{
    /* Name of widget.  Only used for error messages. */
    char *name;

    /* The min/max width/height for this widget. */
    int min_width, min_height;
    int max_width, max_height;

    int fg, bg;
    int flags;

    int h_padding, v_padding;

    Widget<Container> *parent;

    /* Don't touch these manually.  These are to be calculated through
       'calculateChildrenDimensions' by packing boxes. */
    int x, y, w, h;
}
        /* Initialization functions. */
+ (id) newWithName:(const char *)name_;
- (id) initWithName:(const char *)name_;

- (id) setToMinDimensions;
- (id) setMinWidth:(int)w_;
- (id) setMinHeight:(int)h_;
- (id) setMaxWidth:(int)w_;
- (id) setMaxHeight:(int)h_;
- (id) setMinWidth:(int)w_ Height:(int)h_;
- (id) setMaxWidth:(int)w_ Height:(int)h_;

- (id) setFG:(int)fg_;
- (id) setBG:(int)bg_;
- (id) setFG:(int)fg_ BG:(int)bg_;
- (id) setFlag:(int)flag;
- (id) unsetFlag:(int)flag;

- (id) setHPadding:(int)hp VPadding:(int)vp;

- (id) setParentWidget:(Widget<Container> *)widget;

        /* Other stuff. */
- (BOOL) draw:(BITMAP *)bmp :(BOOL)marked_dirty;
- (void) receiveMessage:(int)msg;
- (void) receiveMessage:(int)msg :(int)data;

        /* Internal functions. */
- (int) width;
- (int) height;
- (int) minWidth;
- (int) minHeight;
- (int) maxWidth;
- (int) maxHeight;

- (int) getFlags;
- (Widget *) getWidgetBounding:(int)mx :(int)my;
- (id) getX:(int *)x_ Y:(int *)y_ W:(int *)w_ H:(int *)h_;
- (id) setX:(int)x_ Y:(int)y_ W:(int)w_ H:(int)h_;
- (int) incrementW:(int)w_;
- (int) incrementH:(int)h_;
@end


/*------------------------------------------------------------*/

@interface Frame: Object <Container>
{
    Widget *child;
    Widget *focus_object;

    int messages;
}
- (id) setChild:(Widget *)widget;
- (id) setX:(int)x_ Y:(int)y_ W:(int)w_ H:(int)h_;
- (void) draw:(BITMAP *)dest;
- (int) update;
- (void) receiveMessage:(int)msg :(int)data;
@end


/*------------------------------------------------------------*/
/* Common routines.                                           */
/*------------------------------------------------------------*/

int gui_init(void);
void gui_shutdown(void);

#endif
