/*!
 * \file
 * \ingroup elwindows
 * \brief EL window manager.
 */
#ifndef	__EL_WINDOWS_H
#define	__EL_WINDOWS_H

#include "keys.h"
#include "widgets.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
 * \name Title bar & other constants
 */
/*! @{ */
#define	ELW_TITLE_HEIGHT	16
#define	ELW_BOX_SIZE		20
#define ELW_TITLE_SIZE 35
#define ELW_CM_MENU_LEN		3
/*! @} */

/*!
 * A simple window handler setup to reduce the code needed to do windows
 *
 */
typedef	struct	{
	int	window_id;	/*!< the unique window id */
	int	order;		/*!< the order the windows are to be displayed (layering) */
	int	pos_id;		/*!< id of parent window, pos_id < 0 for normal windows */
	int	pos_loc;	/*!< where is it compared to the pos id?	NOT SUPPORTED YET */
	int	pos_x, pos_y;	/*!< logical location on screen */
	int	len_x, len_y;	/*!< the size of the window in pixels */
	int	orig_len_x, orig_len_y;	/*!< the size of the original window in pixels */
	int	min_len_x, min_len_y;	/*!< for resizable windows, the minimum width and height */
	int	cur_x, cur_y;	/*!< current location on screen */
	int scroll_id;		/*!< id of the scroll widget, if window is scrollable */

	Uint32	flags; /*!< window flags */

	float	back_color[4];		/*!< r,g,b,a for the background */
	float	border_color[4];	/*!< r,g,b,a for the border */
	float	line_color[4];		/*!< r,g,b,a for any internal lines */

	char	window_name[ELW_TITLE_SIZE];	/*!< should be a unique name suitable for display */

	char	displayed;	/*!< is the window currently being displayed? */
	//char	collapsed;	// is it collapsed or expanded?
	char	dragged;	/*!< are we dragging the window? */
	char	resized;	/*!< are we resizing the window? */
	char	drag_in;	/*!< are we dragging inside the window? */
	char	reinstate;	/*!< reinstate this window if the parent is shown again */
	int		opaque;		/*!< if non-zero, window is drawn opaque */
#ifdef MINIMAP2
	char	owner_drawn_title_bar; /*the title bar is drawn by the window itself*/
#endif //MINIMAP2
#ifdef CONTEXT_MENUS
	size_t	cm_id; 				/*!< optional context menu activated my left-clicking title */
#endif

    /*!
	 * \name the handlers
     */
    /*! @{ */
	int (*init_handler)();		/*!< init, scaling, etc */
	int (*display_handler)();	/*!< display the window */
	int (*click_handler)();		/*!< handle mouse clicks */
	int (*drag_handler)();		/*!< handle dragging inside windows */
	int (*mouseover_handler)();	/*!< handle mouseovers */
	int (*resize_handler)();	/*!< handle window resize events */
	int (*keypress_handler)();	/*!< handle key presses */
	int (*close_handler)();		/*!< executed after window is closed */
	int (*destroy_handler)();	/*!< executed upon window destruction */
	int (*show_handler)();		/*!< executed before the window is shown */
	int (*after_show_handler)();		/*!< executed after the window is shown */
	int (*hide_handler)();		/*!< executed after the window is hidden */
    /*! @} */

	/*
	// and optional list/data storage - future expansion??
	void	*list;
	int	list_size;	// width of list items
	int	num_list;	// number of items usable in list
	int	max_list;	// amount of space allocated in list
	int	data_value;	// a simple data value associated with this window
	*/
	void * data; /*!< data for this window */
	widget_list *widgetlist; /*!< list of widgets for this window */
} window_info;

/*!
 * \name property flags in create
 */
/*! @{ */
#define	ELW_TITLE_NONE	0x0000
#define	ELW_TITLE_BAR	0x0001
#define	ELW_TITLE_NAME	0x0002
#define	ELW_CLOSE_BOX	0x0004

#define	ELW_SHOW		0x0010
#define	ELW_DRAGGABLE	0x0020
//#define	ELW_COLLAPSABLE	0x0040
#define	ELW_SHOW_LAST	0x0080
#define ELW_RESIZEABLE	0x0100

#define	ELW_USE_BACKGROUND	0x0200
#define	ELW_USE_BORDER		0x0400
//#define	ELW_USE_LINES		0x0800

#define ELW_CLICK_TRANSPARENT	0x1000

#define ELW_ALPHA_BORDER      0x2000
#define ELW_SWITCHABLE_OPAQUE 0x4000
#define ELW_SCROLLABLE        0x8000
/*! @} */

/*!
 * \name predefined window flags
 */
/*! @{ */
#define	ELW_WIN_DEFAULT (ELW_TITLE_BAR|ELW_CLOSE_BOX|ELW_DRAGGABLE|ELW_USE_BACKGROUND|ELW_USE_BORDER|ELW_SHOW|ELW_TITLE_NAME|ELW_ALPHA_BORDER|ELW_SWITCHABLE_OPAQUE)
#define	ELW_WIN_INVISIBLE	(ELW_TITLE_NONE|ELW_SHOW)
/*! @} */

/*!
 * \name window position flags
 */
/*! @{ */
#define	ELW_VUPPER	0x00
#define	ELW_VCENTER	0x04
#define	ELW_VLOWER	0x08
#define	ELW_VAUTO	0x0C	//reserved
#define	ELW_HLEFT	0x00
#define	ELW_HCENTER	0x01
#define	ELW_HRIGHT	0x02
#define	ELW_HAUTO	0x03	//reserved

#define	ELW_POS_UL	(ELW_VUPPER|ELW_HLEFT)
#define	ELW_POS_UC	(ELW_VUPPER|ELW_HCENTER)
#define	ELW_POS_UR	(ELW_VUPPER|ELW_HRIGHT)

#define	ELW_POS_CL	(ELW_VCENTER|ELW_HLEFT)
#define	ELW_POS_CC	(ELW_VCENTER|ELW_HCENTER)
#define	ELW_POS_CR	(ELW_VCENTER|ELW_HRIGHT)

#define	ELW_POS_LL	(ELW_VLOWER|ELW_HLEFT)
#define	ELW_POS_LC	(ELW_VLOWER|ELW_HCENTER)
#define	ELW_POS_LR	(ELW_VLOWER|ELW_HRIGHT)
/*! @} */

/*!
 * \name window alignment flags
 */
/*! @{ */
#define	ELW_ALIGN_UL	((ELW_VUPPER|ELW_HLEFT)<<8)
#define	ELW_ALIGN_UC	((ELW_VUPPER|ELW_HCENTER)<<8)
#define	ELW_ALIGN_UR	((ELW_VUPPER|ELW_RIGHT)<<8)

#define	ELW_ALIGN_CL	((ELW_VCENTER|ELW_HLEFT)<<8)
#define	ELW_ALIGN_CC	((ELW_VCENTER|ELW_HCENTER)<<8)
#define	ELW_ALIGN_CR	((ELW_VCENTER|ELW_HRIGHT)<<8)

#define	ELW_ALIGN_LL	((ELW_VLOWER|ELW_HLEFT)<<8)
#define	ELW_ALIGN_LC	((ELW_VLOWER|ELW_HCENTER)<<8)
#define	ELW_ALIGN_LR	((ELW_VLOWER|ELW_HRIGHT)<<8)
/*! @} */

/*!
 * \name predefined flags
 */
/*! @{ */
#define	ELW_POS		ELW_POS_UL
#define	ELW_ALIGN	ELW_ALIGN_UL
#define	ELW_RELATIVE	(ELW_POS|ELW_ALIGN)
/*! @} */

/*!
 * \name window color id's
 */
/*! @{ */
#define	ELW_COLOR_BACK	0
#define	ELW_COLOR_BORDER	1
#define	ELW_COLOR_LINE	2
/*! @} */

/*!
 * \name window handler id's
 */
/*! @{ */
#define	ELW_HANDLER_INIT	0
#define	ELW_HANDLER_DISPLAY	1
#define	ELW_HANDLER_CLICK	2
#define	ELW_HANDLER_DRAG	3
#define	ELW_HANDLER_MOUSEOVER	4
#define	ELW_HANDLER_RESIZE	5
#define	ELW_HANDLER_KEYPRESS	6
#define	ELW_HANDLER_CLOSE	7
#define	ELW_HANDLER_DESTROY	8
#define	ELW_HANDLER_SHOW	9
#define	ELW_HANDLER_HIDE	10
#define	ELW_HANDLER_AFTER_SHOW	11
/*! @} */

/*!
 * \name mouse click flags - first ones from events
 */
/*! @{ */
#define	ELW_SHIFT		SHIFT
#define	ELW_CTRL		CTRL
#define	ELW_ALT			ALT
#define ELW_META		KMOD_LMETA
#define ELW_RIGHT_MOUSE		(1<<28)
#define ELW_MID_MOUSE		(1<<27)	// future expansion
#define ELW_LEFT_MOUSE		(1<<26)
#define ELW_MOUSE_BUTTON	(ELW_RIGHT_MOUSE|ELW_MID_MOUSE|ELW_LEFT_MOUSE)
#define ELW_DBL_CLICK		(1<<25)	// future expansion
#define ELW_WHEEL_UP		(1<<24)
#define ELW_WHEEL_DOWN		(1<<23)
#define ELW_WHEEL               (ELW_WHEEL_UP|ELW_WHEEL_DOWN)
/*! @} */

/*!
 * structure containing data for all windows used.
 */
typedef	struct	{
	window_info	*window; /*!< an array of \ref window_info windows */
	int	num_windows;	/*!< highest item used */
	int max_windows;	/*!< number of windows allocated */
	int	display_level;
} windows_info;

extern	windows_info	windows_list; /*!< global variable defining the list of windows */
extern int windows_on_top; /*!< global variable for whether windows appear on top of the console */
extern int top_SWITCHABLE_OPAQUE_window_drawn; /*!< the id of the top opaque switchable window */
extern int opaque_window_backgrounds;

// windows manager function

/*!
 * \ingroup elwindows
 * \brief   Displays all active windows
 *
 *      Displays all active windows
 *
 * \param level     the display level to display
 * \callgraph
 */
void	display_windows(int level);

/*!
 * \ingroup elwindows
 * \brief   callback function used when a mouse click happens in a window.
 *
 *      This event handler gets called when a mouse click is reported in a window. The coordinates \a mx and \a my denotes the (x,y) position of the mouse within the window.
 *
 * \param mx        x coordinate of the mouse position where the click occurred
 * \param my        y coordinate of the mouse position where the click occurred
 * \param flags     mouseflags
 * \retval int
 * \callgraph
 */
int		click_in_windows(int mx, int my, Uint32 flags);

/*!
 * \ingroup elwindows
 * \brief   callback function used when a drag event happens in a window.
 *
 *      This drag event handler get called when a mouse drag event happens in a window. (\a mx, \a my) denotes the coordinates of the mouse, while \a dx and \a dy are the dragging distances in x- and y-direction.
 *
 * \param mx        x coordinate of the mouse position where the drag started
 * \param my        x coordinate of the mouse position where the drag started
 * \param flags     mouseflags
 * \param dx        dragging distance in x-direction
 * \param dy        dragging distance in y-direction
 * \retval int
 * \callgraph
 */
int		drag_in_windows(int mx, int my, Uint32 flags, int dx, int dy);

/*!
 * \ingroup elwindows
 * \brief   Handles dragging and resizing of a window
 *
 *      Checks all the windows for one that is currently seletec and moves or resizes this one resp.
 *
 * \param mx        x coordinate of the mouse position
 * \param my        y coordinate of the mouse position
 * \param dx        amount in x direction to drag or resize the window
 * \param dy        amount in y direction to drag or resize the window
 * \retval int      the id of the window being dragged or resized
 * \callgraph
 */
int		drag_windows(int mx, int my, int dx, int dy);

/*!
 * \ingroup elwindows
 * \brief   callback function used when a key is pressed in a window.
 *
 *      This event handler gets called when a keypress is reported in a window. The coordinates \a mx and \a my denotes the (x,y) position of the mouse within the window.
 *
 * \param x         x coordinate of the mouse position where the click occurred
 * \param y         y coordinate of the mouse position where the click occurred
 * \param key       the key or key combination that is pressed
 * \param unikey    the unicode value of \a key
 * \retval int
 * \callgraph
 */
int		keypress_in_windows(int x, int y, Uint32 key, Uint32 unikey);

/*!
 * \ingroup elwindows
 * \brief   Resets the states of all windows which are related to dragging
 *
 *      Resets the dragged, resized and drag_in states of all windows.
 *
 */
void	end_drag_windows();

/*!
 * \ingroup elwindows
 * \brief   Selects the window given by \a win_id.
 *
 *      Selects the window given in \a win_id. The selected window and each of its childs, if applicable, is brought to front.
 *
 * \param win_id    the id of the window to select
 * \retval int  -1, if \a win_id is either <0 or greater than \ref windows_info::num_windows, or if \a win_id is not equal the \ref window_info::window_id stored for this \ref windows_info::window.
 *               0, if the \ref window_info::order of the \ref windows_info::window stored at this index is less than 0,
 *               else 1.
 *
 * \pre The parameter \a win_id must be both, greater or equal to 0 and less than \ref windows_info::num_windows
 * \pre The parameter \a win_id must be equal the \ref window_info::window_id which is currently stored in \ref windows_list.
 * \pre The \ref window_info::order of the \ref windows_info::window stored at the index \a win_id, must be greater than 0.
 */
int		select_window(int win_id);

// individual functions

/*!
 * \ingroup elwindows
 * \brief   Creates a new window and calls \ref init_window to place it.
 *
 *      Creates a new window with the given \a name and \a property_flags and then calls \ref init_window to place it accordingly.
 *
 * \param name              name of the window
 * \param pos_id            used to determine the visibility of this window, gets passed to \ref init_window
 * \param pos_loc           passed to \ref init_window
 * \param pos_x             passed to \ref init_window
 * \param pos_y             passed to \ref init_window
 * \param size_x            passed to \ref init_window
 * \param size_y            passed to \ref init_window
 * \param property_flags    the windows properties
 * \retval int              returns the window id as an index into the \ref windows_info::window array.
 * \callgraph
 *
 * \post    If this functions returns -1, it indicates an unhandled exception has occured.
 */
int		create_window(const char *name, int pos_id, Uint32 pos_loc, int pos_x, int pos_y, int size_x, int size_y, Uint32 property_flags);

/*!
 * \ingroup elwindows
 * \brief   Destroys the window with the given \a win_id.
 *
 *      Destroys the window with the given \a win_id and frees up memory.
 *
 * \param win_id    the index into the \ref windows_info::window array
 *
 * \pre If \a win_id is \<0 or \>\ref windows_info::num_windows this function returns without performing any actions.
 * \pre If the \ref window_info::window_id of the window stored at the index \a win_id into the \ref windows_list variable is not equal to \a win_id, this function returns without performing any actions.
 */
void	destroy_window(int win_id);

/*!
 * \ingroup elwindows
 * \brief   Initializes a new window.
 *
 *      Initializes a new window with the given \a win_id, position and size. Calls \ref move_window to place the window accordingly.
 *
 * \param win_id        the \ref window_info::window_id for the window
 * \param pos_id        the id of the position
 * \param pos_loc
 * \param pos_x         x coordinate of the upper left corner of the window
 * \param pos_y         y coordinate of the upper left corner of the window
 * \param size_x        width of the window
 * \param size_y        height of the window
 * \retval int
 * \sa move_window
 */
int		init_window(int win_id, int pos_id, Uint32 pos_loc, int pos_x, int pos_y, int size_x, int size_y);

/*!
 * \ingroup elwindows
 * \brief   Moves the window given by \a win_id
 *
 *      Moves the given window to the new position given.
 *
 * \param win_id        id for the window to move
 * \param pos_id        id of the new posisiotn
 * \param pos_loc
 * \param pos_x         x coordinate of the new position
 * \param pos_y         y coordinate of the new position
 * \retval int          -1, if \a win_id < 0 or \a win_id > \ref windows_info::num_windows,
 *                      or if the \ref window_info::window_id of the window at index \a win_id into \ref windows_list is not equal \a win_id,
 *                      else 1 is returned.
 *
 * \pre If \a win_id is less than 0, this functions returns -1 without performing any actions
 * \pre If \a win_id is greater than \ref windows_info::num_windows this function returns -1 without performing any actions
 * \pre If \a win_id is not equal \ref window_info::window_id of the window at the index \a win_id into \ref windows_list this functions returns -1, without performing any action.
 */
int		move_window(int win_id, int pos_id, Uint32 pos_loc, int pos_x, int pos_y);


/*!
 * \ingroup elwindows
 * \brief   Draws the window given by \a win_id
 *
 *      Draws the given window on the screen. Don't call this function directly,
 *	use the window manager instead. This declaration is only here for the
 *	loading window which bypasses the window manager since it cannot be
 *	drawn in the normal event loop.
 *
 * \param win_id        id for the window to move
 */
int display_window (int win_id);

//int	set_window_property(int win_id, Uint32 property_flag, int new_property);

/*!
 * \ingroup elwindows
 * \brief   Sets the window (background) color to the given values.
 *
 *      Sets the background color of the window given by \a win_id to the values given in \a r, \a g, \a b and \a a.
 *      \note This function is currently only used when displaying the options menu.
 *
 * \param win_id        the id of the window
 * \param color_id      an id for the color value
 * \param r             red value of the color (0<=r<=1)
 * \param g             green value of the color (0<=g<=1)
 * \param b             blue value of the color (0<=b<=1)
 * \param a             transparency of the color (0<=a<=1)
 * \retval int          0, if \a win_id is less than 0, or if \a win_id is greater than \ref windows_info::num_windows,
 *                      or if the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array is not equal to \a win_id,
 *                      or if no action was performed, else 1 is returned.
 *
 * \callgraph
 *
 * \pre If \a win_id < 0 this function returns 0 without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this functions returns 0 without performing any actions.
 * \pre If none of the above preconditions is true, but no action is performed else, this function returns 0.
 * \pre This functions only handles the \a color_id of \ref ELW_COLOR_BACK, \ref ELW_COLOR_BORDER and \ref ELW_COLOR_LINE.
 */
int	set_window_color(int win_id, Uint32 color_id, float r, float g, float b, float a);

/*!
 * \ingroup elwindows
 * \brief   Uses the color of the window \a win_id that is referred to by \a color_id.
 *
 *      The part of the window \a win_id given by \a color_id will be used further.
 *      \note This function is only used by the quickbar (\ref display_quickbar_handler)
 *
 * \param win_id        the id of the window to set the color
 * \param color_id      the color id to use
 * \retval int          0, if \a win_id is less than 0, or if \a win_id is greater than \ref windows_info::num_windows,
 *                      or if the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array is not equal to \a win_id,
 *                      or if no action was performed, else 1 is returned.
 *
 * \sa display_quickbar_handler
 *
 * \pre If \a win_id < 0 this function returns 0 without performing any actions.
 * \pre If \a win_id is greater than the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns 0 without performing any actions.
 * \pre If none of the above preconditions is true, but no action is performed else, this function returns 0.
 * \pre This function only handles the \a color_id of \ref ELW_COLOR_BACK, \ref ELW_COLOR_BORDER and \ref ELW_COLOR_LINE.
 */
int		use_window_color(int win_id, Uint32 color_id);

/*!
 * \ingroup elwindows
 * \brief Sets the window's minimum size
 *
 *      Sets the minimum \a width and \a height for the resizeable window given by \a win_id
 *
 * \param win_id the number of the window
 * \param width the new minimum width
 * \param height the new minimum height
 * \retval int 0 on failure, 1 on success
 *
 * \pre If \a win_id < 0 this function returns 0, without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows this function returns 0 without performing any actions.
 * \pre If either \a width or \a height is less than 0 this function returns 0 without performing any actions.
 */
int set_window_min_size (int win_id, int width, int height);

/*!
 * \ingroup elwindows
 * \brief Sets one or more window flags
 *
 *     Sets the window flags in \a flag
 *
 * \param win_id the number of the window
 * \param flag the flag(s) to set
 */
int set_window_flag (int win_id, Uint32 flag);

/*!
 * \ingroup elwindows
 * \brief   Sets a new window handler callback function to be used for the given window.
 *
 *      The given \a handler will be set to be the callback function to handle \a handler_id callbacks for the \a win_id window.
 *
 * \param win_id        the id of the window for which to set a callback function.
 * \param handler_id    the type of handler that will be set.
 * \param handler       a pointer to the callback function to use.
 * \retval void*        a pointer to the old handler, or NULL.
 *
 * \pre If \a win_id < 0 this function returns NULL without performing any actions.
 * \pre If \a win_id  is greater than \ref windows_info::num_windows, this function returns NULL without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns NULL without performing any actions.
 * \pre If \a handler_id is not one of \ref ELW_HANDLER_INIT, \ref ELW_HANDLER_DISPLAY, \ref ELW_HANDLER_CLICK, \ref ELW_HANDLER_DRAG, \ref ELW_HANDLER_MOUSEOVER, \ref ELW_HANDLER_RESIZE, \ref ELW_HANDLER_KEYPRESS or \ref ELW_HANDLER_DESTROY, this function returns NULL.
 *
 */
void	*set_window_handler(int win_id, int handler_id, int (*handler)() );

/*!
 * \ingroup elwindows
 * \brief   Selects and shows the given window
 *
 *      Selects and shows the window given by \a win_id and all it's child windows where applicable.
 *
 * \param win_id    the id of the window to show
 *
 * \sa select_window
 *
 * \pre If \a win_id < 0 this function returns without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions.
 */
void	show_window(int win_id);

/*!
 * \ingroup elwindows
 * \brief   Hides the given window.
 *
 *      Hides the window given by \a win_id and all its child windows where applicable.
 *
 * \param win_id    the id of the window to hide.
 *
 * \pre If \a win_id < 0 this function returns without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions.
 */
void	hide_window(int win_id);

/*!
 * \ingroup elwindows
 * \brief   Toggles the visibility of the given window.
 *
 *      Toggles the visibility of the window given by \a win_id, by either calling \ref hide_window or \ref show_window.
 *
 * \param win_id    the id of the window to toggle.
 *
 * \callgraph
 *
 * \pre If \a win_id < 0 this function returns without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions.
 */
void	toggle_window(int win_id);

/*!
 * \ingroup elwindows
 * \brief   Sets the new size of a resizable window.
 *
 *      Resizes the window given by \a win_id to given \a new_width and \a new_height, if the window is resizable. Whether a window is resizable or not is determined by looking if the \ref window_info::resize_handler equals NULL or not.
 *
 * \param win_id        the id of the window to resize
 * \param new_width     the new width of the window
 * \param new_height    the new height of the window
 *
 * \callgraph
 *
 * \pre If \a win_id < 0 this function returns without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns without performing any actions.
 * \pre If \a new_width is less than the minimum width (\ref window_info::min_len_x) it will be adjusted accordingly before applying.
 * \pre If \a new_height is less than the minimum height (\ref window_info::min_len_y) it will be adjusted acoordingly before applying.
 */
void resize_window (int win_id, int new_width, int new_height);

/*!
 * \ingroup elwindows
 * \brief   Checks whether a window is currently displayed and returns a proper boolean value.
 *
 *      Returns the visibility status of the window given by \a win_id in a boolean value.
 *
 * \param win_id    the id of the window to check
 * \retval int      0 (false) if the window is hidden, else 1 (true).
 *
 * \pre If \a win_id < 0, this function returns false (0), without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns false (0), without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns false (0), without performing any actions.
 */
int		get_show_window(int win_id);

/*!
 * \ingroup elwindows
 * \brief   Checks whether a window is currently displayable and returns a proper boolean value.
 *
 *      Checks if a window is either displayed or would be if its parent were visible
 *
 * \param win_id    the id of the window to check
 * \retval int      0 (false) if the window is hidden, else 1 (true).
 *
 * \pre If \a win_id < 0, this function returns false (0), without performing any actions.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns false (0), without performing any actions.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns false (0), without performing any actions.
 */
int		get_window_showable(int win_id);

//void	collapse_window(int win_id);	// future expansion
//void	expand_window(int win_id);		// future expansion

/*!
 * \ingroup elwindows
 * \brief   Checks if the mouse coordinates are inside a window.
 *
 *      Checks whether the given mouse coordinates \a x and \a y are within the window given by \a win_id and returns either a boolean value or an error.
 *
 * \param win_id    the id of the window to check for the coordinates \a x and \a y
 * \param x         the x location of the mouse cursor to check
 * \param y         the y location of the mouse cursor to check
 * \retval int      -1, if either \a win_id < 0, or \a win_id is greater than \ref windows_info::num_windows,
 *                  or if \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array.
 *                  0 (false), if the coordinates \a x and \a y are outside the window given by \a win_id,
 *                  else 1 (true).
 *
 * \pre If \a win_id < 0, this function returns -1, without performing any actions, indicating an error.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns -1, without performing any actions, indicating an error.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns -1 without performing any actions, indicating an error.
 */
int		mouse_in_window(int win_id, int x, int y);	// is a coord in the window?

/*!
 * \ingroup elwindows
 * \brief   Checks if there is a click in a window at the given coordinates.
 *
 *      Checks whether a click occured inside the window given by \a win_id, at the coordinates \a x and \a y and returns a boolean value or an error.
 *
 * \param win_id    the id of the window to check
 * \param x         the x coordinate of the cursor position where the click occured
 * \param y         the y coordinate of the cursor position where the click occured
 * \param flags     the window flags of the window. They will be given to the \ref window_info::click_handler that handles the actual click event.
 * \retval int      -1, if either \a win_id < 0, or \a win_id is greater than \ref windows_info::num_windows,
 *                  of if \a win_id is not equal the \ref window_info::window_id of the given at index \a win_id into the \ref windows_list array.
 *                  1 (true), if the cursor is actualy inside the window, 
 *                  else 0 (false).
 * \callgraph
 *
 * \pre If \a win_id < 0, this function returns -1, without performing any actions, indicating an error.
 * \pre If \a win_id is greater than \ref windows_info::num_windows, this function returns -1, without performing any actions, indicating an error.
 * \pre If \a win_id is not equal the \ref window_info::window_id of the window at index \a win_id into the \ref windows_list array, this function returns -1, without performing any actions, indicating an error.
 */
int		click_in_window(int win_id, int x, int y, Uint32 flags);	// click in  a coord in the window

/*!
 * \ingroup elwindows
 * \brief   Sets the length of the window's scrollbar
 *
 *      Sets the length of the window's scrollbar, ie. how many pixels you want it to scroll down.
 *
 * \param win_id    The id of the scrollable window
 * \param bar_len   The amount of pixels you want the bar to scroll.
 */
void set_window_scroll_len(int win_id, int bar_len);

#ifdef CONTEXT_MENUS
/*!
 * \ingroup elwindows
 * \brief   The callback for context menu clicks
 *
 *      Called when an option is selected from the title context menu.  If
 *	the user window wants to use their own callback, they should still
 *  call this function to implement the title menu options. 
 *
 * \param win    	Pointer to the windows structure
 * \param widget_id	The id of the widget clicked to open the menu or -1.
 * \param mx		The x coordinate in window of where the user clicked to open the window
 * \param my		The y coordinate as above
 * \param option	The menu line clicked, first line is 0
 * \retval int      1 if action was taken otherwise 0
*/
int cm_title_handler(window_info *win, int widget_id, int mx, int my, int option);
#endif

// low level functions
//window_info	*get_window_info(int win_id);
//window_info	*get_window_by_name(const Uint8 *name);

// default handlers - VERY basic
//int	init_handler(window_info *win);
//int	display_handler(window_info *win);
//int	click_handler(window_info *win);
//int	mouseover_handler(window_info *win);

#ifdef __cplusplus
} // extern "C"
#endif

#endif	//__EL_WINDOWS_H
