#ifndef lbgui_h 
#define lbgui_h

typedef struct LBG_WBORDER_BMAPS
{
	BMAP* bmap_titlebar_left;
	BMAP* bmap_titlebar_middle;
	BMAP* bmap_titlebar_right;
	BMAP* bmap_border_left;
	BMAP* bmap_border_right;
	BMAP* bmap_border_bottomleft;
	BMAP* bmap_border_bottom;
	BMAP* bmap_border_bottomright;
} LBG_WBORDER_BMAPS;

typedef struct LBG_CBORDER_BMAPS
{
	BMAP* bmap_topleft;
	BMAP* bmap_top;
	BMAP* bmap_topright;
	BMAP* bmap_left;
	BMAP* bmap_right;
	BMAP* bmap_bottomleft;
	BMAP* bmap_bottom;
	BMAP* bmap_bottomright;
	BMAP* bmap_center;
} LBG_CBORDER_BMAPS;

typedef struct LBG_TBUTTON_BMAPS // titlebar buttons
{
	BMAP* bmap_x_default;
	BMAP* bmap_x_over;
	BMAP* bmap_x_clicked;
	BMAP* bmap_max_default;
	BMAP* bmap_max_over;
	BMAP* bmap_max_clicked;
	BMAP* bmap_res_default;
	BMAP* bmap_res_over;
	BMAP* bmap_res_clicked;
} LBG_TBUTTON_BMAPS;

typedef struct LBG_WINDOW
{
	long ssize;
	long stype;
	struct LBG_WINDOW* next;
	struct LBG_WINDOW* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	struct LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	void Destroy();
	var cpos_x, cpos_y; 	// Position des Inhalts, d.h. ohne Rahmen und Titelleiste
	var csize_x, csize_y; 	// Größe des Inhalts
	var minsize_x; // Minimum size when scaling
	var minsize_y;
	var maxsize_x; // Maximum size when scaling
	var maxsize_y;
	var mg_pos_x; // mouse grap
	var mg_pos_y; // OR backup size when maximized
	var bg_ver; // border grap (vertical)
	var bg_hor; // OR backup position when maximized
	var bkx; // backup positions when scaling from top or left
	var bky;
	long flags2;
	LBG_WBORDER_BMAPS bbmaps;
	LBG_CBORDER_BMAPS cbmaps;
	LBG_TBUTTON_BMAPS tbmaps;
	void* xbutton; // X button (close button) type:LBG_BUTTON
	void* maxbutton; // maximize button
	var xbutton_offx;
	var xbutton_offy;
	var lastsize_x;
	var lastsize_y;
	var ctype; // content type
	void* content;
	var hscroll_height;
	var vscroll_width;
	var hscrollamount;
	var vscrollamount;
	var scroll_minsize_x;
	var scroll_minsize_y;
	var scroll_bordersize_x;
	var scroll_bordersize_y;
	void Close();
	void Maximize();
	void Restore();
	void Resize();
	void Resizing();
	void Move();
	void Moving();
	
} LBG_WINDOW;

typedef struct LBG_BUTTON
{
	long ssize;
	long stype;
	struct LBG_BUTTON* next;
	struct LBG_BUTTON* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	void Destroy();
	var tpos_over_x; // relative to tpos_x
	var tpos_over_y;
	var tpos_clicked_x;
	var tpos_clicked_y;
	COLOR color_default;
	COLOR color_over;
	COLOR color_clicked;
	COLOR color_disabled;
	void Event();
	void Over();
	void Leave();
	int Condition();
	BMAP* bmap_default;
	BMAP* bmap_over;
	BMAP* bmap_clicked;
	BMAP* bmap_active;
	BMAP* bmap_overactive;
	BMAP* bmap_disabled;
} LBG_BUTTON;

typedef struct LBG_BUTTON_BMAPS
{
	BMAP* bmap_default;
	BMAP* bmap_over;
	BMAP* bmap_clicked;
	BMAP* bmap_active;
	BMAP* bmap_overactive;
	BMAP* bmap_disabled;
} LBG_BUTTON_BMAPS;




typedef struct LBG_PANEL
{
	long ssize;
	long stype;
	struct LBG_PANEL* next;
	struct LBG_PANEL* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	void Destroy();
} LBG_PANEL;


typedef struct LBG_TEXT
{
	long ssize;
	long stype;
	struct LBG_TEXT* next;
	struct LBG_TEXT* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	TEXT* text;
	void Destroy();
} LBG_TEXT;

typedef struct LBG_CHECKBOX
{
	long ssize;
	long stype;
	struct LBG_CHECKBOX* next;
	struct LBG_CHECKBOX* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	void Destroy();
	COLOR color_default;
	COLOR color_over;
	COLOR color_clicked;
	COLOR color_disabled;
	void ChangeState();
	void Over();
	void Leave();
	int Condition();
	var group; // group for radiobuttons
	BMAP* bmap_default;
	BMAP* bmap_over;
	BMAP* bmap_checked;
	BMAP* bmap_checked_over;
	BMAP* bmap_disabled;
	BMAP* bmap_checked_disabled;
	
} LBG_CHECKBOX;

typedef struct LBG_CHECKBOX_BMAPS
{
	BMAP* bmap_default;
	BMAP* bmap_over;
	BMAP* bmap_checked;
	BMAP* bmap_checked_over;
	BMAP* bmap_disabled;
	BMAP* bmap_checked_disabled;
} LBG_CHECKBOX_BMAPS;


typedef struct LBG_INFOBOX
{
	long ssize;
	long stype;
	struct LBG_INFOBOX* next;
	struct LBG_INFOBOX* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* target;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	void Destroy();
	LBG_CBORDER_BMAPS bmaps;
	var time;
	var counter;
	var minsize_x;
	var minsize_y;
	void Appear();
	void Disappear();
	int Condition();
} LBG_INFOBOX;


typedef struct LBG_PROGRESSBAR
{
	long ssize;
	long stype;
	struct LBG_PROGRESSBAR* next;
	struct LBG_PROGRESSBAR* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	void Destroy();
	PANEL* bar;
	BMAP* bmap_pan_left;
	BMAP* bmap_pan_middle;
	BMAP* bmap_pan_right;
	BMAP* bmap_bar;
	var maximum;
	var progress;
	STRING* format;
	var barpos_x;
	var barpos_y;
	var bar_width;
} LBG_PROGRESSBAR;

typedef struct LBG_PROGRESSBAR_BMAPS
{
	BMAP* bmap_pan_left;
	BMAP* bmap_pan_middle;
	BMAP* bmap_pan_right;
	BMAP* bmap_bar;
} LBG_PROGRESSBAR_BMAPS;



typedef struct LBG_HSCROLLBAR_BMAPS
{
	BMAP* bmap_left;
	BMAP* bmap_middle;
	BMAP* bmap_right;
	BMAP* bmap_bar;
	BMAP* bmap_corner;
} LBG_HSCROLLBAR_BMAPS;

typedef struct LBG_HSCROLLBAR
{
	long ssize;
	long stype;
	struct LBG_HSCROLLBAR* next;
	struct LBG_HSCROLLBAR* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* target;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	void Destroy();
	LBG_BUTTON* button_left; // scroll left button
	LBG_BUTTON* button_right; // scroll right button
	PANEL* scrollbar;
	PANEL* corner;
	LBG_HSCROLLBAR_BMAPS bmaps;
	var scrollamount;
	var scrollmax; // Maximum size (or scrollamount?) (or 0 for auto?)
	var ppa; // pixel per "amount unit"
	var wheelspeed;
	var mg; // mouse grap
	var buttonspeed;
	void Scrolling();
	int Condition();
} LBG_HSCROLLBAR;



typedef struct LBG_VSCROLLBAR_BMAPS
{
	BMAP* bmap_top;
	BMAP* bmap_middle;
	BMAP* bmap_bottom;
	BMAP* bmap_bar;
} LBG_VSCROLLBAR_BMAPS;

typedef struct LBG_VSCROLLBAR
{
	long ssize;
	long stype;
	struct LBG_VSCROLLBAR* next;
	struct LBG_VSCROLLBAR* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* target;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	void Destroy();
	LBG_BUTTON* button_top; // scroll left button
	LBG_BUTTON* button_bottom; // scroll right button
	PANEL* scrollbar;
	PANEL* corner;
	LBG_VSCROLLBAR_BMAPS bmaps;
	var scrollamount;
	var scrollmax; // Maximum size (or scrollamount?) (or 0 for auto?)
	var ppa; // pixel per "amount unit"
	var wheelspeed;
	var mg; // mouse grap
	var buttonspeed;
	void Scrolling();
	int Condition();
} LBG_VSCROLLBAR;



typedef struct LBG_SLIDER_BMAPS
{
	BMAP* bmap_left;
	BMAP* bmap_middle;
	BMAP* bmap_right;
	BMAP* bmap_knob_default;
	BMAP* bmap_knob_over;
	BMAP* bmap_knob_clicked;
} LBG_SLIDER_BMAPS;

typedef struct LBG_SLIDER
{
	long ssize;
	long stype;
	struct LBG_SLIDER* next;
	struct LBG_SLIDER* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	void Destroy();
	PANEL* knob;
	LBG_SLIDER_BMAPS bmaps;
	var minimum;
	var maximum;
	var value;
	var* v;
	var mg;
	void Sliding();
} LBG_SLIDER;



typedef struct LBG_LISTITEM_BMAPS
{
	BMAP* bmap_left;
	BMAP* bmap_middle;
	BMAP* bmap_right;
} LBG_LISTITEM_BMAPS;

typedef struct LBG_LISTITEM
{
	long ssize;
	long stype;
	struct LBG_LISTITEM* next;
	struct LBG_LISTITEM* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	STRING* caption;
	TEXT* text;
	void Destroy();
	void Select();
	void Unselect();
} LBG_LISTITEM;


typedef struct LBG_LISTBOX_BMAPS
{
	BMAP* bmap_topleft;
	BMAP* bmap_top;
	BMAP* bmap_topright;
	BMAP* bmap_left;
	BMAP* bmap_right;
	BMAP* bmap_bottomleft;
	BMAP* bmap_bottom;
	BMAP* bmap_bottomright;
	BMAP* bmap_center;
} LBG_LISTBOX_BMAPS;

typedef struct LBG_LISTBOX
{
	long ssize;
	long stype;
	struct LBG_LISTBOX* next;
	struct LBG_LISTBOX* previous;
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	PANEL* panel;
	var tpos_x;
	var tpos_y;
	void Destroy();
	LBG_LISTBOX_BMAPS bmaps;
	LBG_LISTITEM_BMAPS bmaps_default;
	LBG_LISTITEM_BMAPS bmaps_over;
	LBG_LISTITEM_BMAPS bmaps_marked;
	BMAP* bmap_default;
	BMAP* bmap_over;
	BMAP* bmap_marked;
	LBG_LISTITEM* item_first;
	LBG_LISTITEM* marked_item;
	var ipos_x, ipos_y; // defines the area of the list items
	var isize_x, isize_y; // (relative to pos_x,y)
	var lpos_x, lpos_y; // defines the "real" area of the list items (with the slider size deducted)
	var lsize_x, lsize_y; // and absolute instead of relative
	var vscroll_width;
	var vscrollamount;
	FONT* font;
	var itemheight;
	COLOR color_default;
	COLOR color_over;
	COLOR color_marked;
	void Select();
} LBG_LISTBOX;



typedef struct LBG_RIGHTCLICK
{
	long ssize;
	long stype;
	
	struct LBG_RIGHTCLICK* next;
	struct LBG_RIGHTCLICK* previous;
	
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	
	
	//FONT* font;
	LBG_WINDOW* target;
	var layer;
	long flags;
	
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	
	void Destroy();
	
	LBG_LISTBOX* menu;
	
	void Open();
	int Condition();
	
	
} LBG_RIGHTCLICK;


typedef struct LBG_DIGITS
{
	long ssize;
	long stype;
	
	struct LBG_DIGITS* next;
	struct LBG_DIGITS* previous;
	
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	
	
	//FONT* font;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	
	TEXT* text;
	STRING* caption;
	
	STRING* format;
	
	var value;
	var* v;
	
	void Destroy();
} LBG_DIGITS;


typedef struct LBG_EDITBOX_BMAPS
{
	BMAP* bmap_left;
	BMAP* bmap_middle;
	BMAP* bmap_right;
} LBG_EDITBOX_BMAPS;

typedef struct LBG_EDITBOX
{
	long ssize;
	long stype;
	
	struct LBG_EDITBOX* next;
	struct LBG_EDITBOX* previous;
	
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	
	
	//FONT* font;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	
	PANEL* panel;
	
	STRING* caption;
	TEXT* text;
	var tpos_x;
	var tpos_y;
	
	void Destroy();
	
	
	LBG_EDITBOX_BMAPS bmaps;
	
	STRING* vstring; // visible string
	STRING* vsleft; // visible string left of the cursor
	STRING* vsright; // visible string right of the cursor
	
	var hscrollamount;
	var cursor_pos;
	
	TEXT* cursor;
	
	var time;
	var counter;
	var max_length;
	
	int Mask(STRING* input);
	void Key();
	
	
	
} LBG_EDITBOX;


typedef struct LBG_COMBOBOX
{
	long ssize;
	long stype;
	
	struct LBG_COMBOBOX* next;
	struct LBG_COMBOBOX* previous;
	
	var skill_x; // Free to use for the user
	var skill_y;
	var skill_z;
	
	
	//FONT* font;
	LBG_WINDOW* parent;
	var layer;
	long flags;
	
	var pos_x, pos_y; 	// Position (bei Buttons etc. relativ zur Position des Parent-Windows (oder über flag?))
	var size_x, size_y; 	// Größe
	var scale_x,scale_y;
	
	STRING* caption;
	
	void Destroy();
	
	LBG_EDITBOX* editbox;
	LBG_LISTBOX* menu;
	LBG_BUTTON* button;
	
	LBG_LISTITEM* chosen_option;
	
	void Open();
	void Close();
	
	
} LBG_COMBOBOX;








LBG_WINDOW* LBG_WINDOW_FIRST = 0;
LBG_BUTTON* LBG_BUTTON_FIRST = 0;
LBG_PANEL* LBG_PANEL_FIRST = 0;
LBG_TEXT* LBG_TEXT_FIRST = 0;
//LBG_VIEW* LBG_VIEW_FIRST = 0;
LBG_CHECKBOX* LBG_CHECKBOX_FIRST = 0;
LBG_INFOBOX* LBG_INFOBOX_FIRST = 0;
LBG_PROGRESSBAR* LBG_PROGRESSBAR_FIRST = 0;
LBG_HSCROLLBAR* LBG_HSCROLLBAR_FIRST = 0;
LBG_VSCROLLBAR* LBG_VSCROLLBAR_FIRST = 0;
LBG_SLIDER* LBG_SLIDER_FIRST = 0;
LBG_LISTBOX* LBG_LISTBOX_FIRST = 0;
LBG_RIGHTCLICK* LBG_RIGHTCLICK_FIRST = 0;
LBG_COMBOBOX* LBG_COMBOBOX_FIRST = 0;
LBG_DIGITS* LBG_DIGITS_FIRST = 0;
LBG_EDITBOX* LBG_EDITBOX_FIRST = 0;

LBG_WINDOW* LBG_object_last (LBG_WINDOW* obj)
{
	if(!obj) return (NULL);
	while(obj->next)
	{
		obj = obj->next;
	}
	return(obj);
}

LBG_WINDOW* LBG_object_nr (LBG_WINDOW* obj,var nr)
{
	if(!obj) return (NULL);
	var i;
	for(i=0;i<nr;i++)
	{
		if(!obj->next) break;
		obj = obj->next;
	}
	return(obj);
}

var LBG_object_num (LBG_WINDOW* obj)
{
	if(!obj) return (0);
	var i = 1;
	while(obj->next)
	{
		obj = obj->next;
		i++;
	}
	return(i);
}

var LBG_object_getnum (LBG_WINDOW* obj1,LBG_WINDOW* obj2)
{
	if(!obj1) return (0);
	if(!obj2) return (0);
	var i = 0;
	while((obj1 != obj2) && obj1->next)
	{
		obj1 = obj1->next;
		i++;
	}
	return(i);
}




LBG_WINDOW* LBG_event_object;
LBG_WINDOW* LBG_event_window;
LBG_BUTTON* LBG_event_button;
LBG_PANEL* LBG_event_panel;
LBG_TEXT* LBG_event_text;
LBG_CHECKBOX* LBG_event_checkbox;
LBG_INFOBOX* LBG_event_infobox;
LBG_PROGRESSBAR* LBG_event_progressbar;
LBG_HSCROLLBAR* LBG_event_scrollbar;
LBG_HSCROLLBAR* LBG_event_hscrollbar;
LBG_VSCROLLBAR* LBG_event_vscrollbar;
LBG_SLIDER* LBG_event_slider;
LBG_LISTBOX* LBG_event_listbox;
LBG_LISTITEM* LBG_event_listitem;
LBG_RIGHTCLICK* LBG_event_rightclick;
LBG_COMBOBOX* LBG_event_combobox;
LBG_DIGITS* LBG_event_digits;
LBG_EDITBOX* LBG_event_editbox;





typedef struct LBG_HANDLE
{
	long ssize;
	long stype;
	
	struct LBG_HANDLE* next;
	struct LBG_HANDLE* previous;
	LBG_WINDOW* target;
	int valid;
	
} LBG_HANDLE;
LBG_HANDLE* LBG_HANDLE_FIRST = 0;



LBG_HANDLE* LBG_get_eventhandle (LBG_WINDOW* obj)
{
	LBG_HANDLE* h = malloc(sizeof(LBG_HANDLE));
	h->ssize = sizeof(LBG_HANDLE);
	h->stype = -1;
	
	h->target = obj;
	h->valid = 1;
	
	h->next = NULL;
	if(LBG_HANDLE_FIRST == NULL)
	{
		LBG_HANDLE_FIRST = h;
		h->previous = NULL;
	}
	else
	{
		h->previous = LBG_object_last(LBG_HANDLE_FIRST);
		h->previous->next = h;
	}
	return h;
}

void LBG_object_make_handles_invalid (LBG_WINDOW* obj)
{
	LBG_HANDLE* h = LBG_HANDLE_FIRST;
	while(h)
	{
		if(h->target == obj) h->valid = 0;
		h = h->next;
	}
}

LBG_HANDLE* LBG_destroy_handle (LBG_HANDLE* h)
{
	LBG_HANDLE* next = h->next;
	if(h->previous) h->previous->next = h->next;
	else LBG_HANDLE_FIRST = h->next;
	if(h->next) h->next->previous = h->previous;
	
	free(h);
	return(next);
}
// </lbgui_structs.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_flags.h>

// Window flags
#define WF_DISABLED		(1<<1)
#define WFi_NOTITLEBAR	(1<<2)
#define WFi_NOBORDER		(1<<3)
#define WF_XBUTTON		(1<<4)
#define WF_MAXBUTTON		(1<<5)

#define WF_RESIZEABLE	(1<<7)
#define WF_RESIZABLE	WF_RESIZEABLE
#define WF_MAXIMIZED		(1<<8)
#define WF_EXTERNSTRING	(1<<9) // Caption string not recreated, but pointer taken from parameter
#define WF_DONTDESTROY	(1<<10)
#define WF_DONTDESTROYCHILDS (1<<11) // Don't destroy any child when destroyed

#define WF_SHOW			(1<<14) // wie SHOW

#define WF_HSCROLLBAR	(1<<19) // horizontal scrollbar
#define WF_VSCROLLBAR	(1<<20) // vertical scrollbar
#define WF_AUTOHSCROLL	(1<<21) // create and destroy scrollbar when necessary
#define WF_AUTOVSCROLL	(1<<22)

#define WF_DONTSETTOTOP	(1<<25) // Don't set window to top when klicked on (e.g. if it's a background fullscreen window)
#define WF_DONTMOVE		(1<<26) // Can't move the window
#define WF_STAYONTOP		(1<<27) // Always stay on top
#define WF_DISABLEPARENT		(1<<28) // Like a dialog box or a MessageBox. Disables the parent window.
#define WF_DISABLEGUI		(1<<29) // Like a dialog box or a MessageBox. Disabled everything else.
#define WF_LOCKSIZE_X	(1<<30) // Can't be scaled horizontally
#define WF_LOCKSIZE_Y	(1<<31) // Can't be scaled vertically

#define WF2i_LYCLICK0	(1<<0)
#define WF2i_LYCLICK1	(1<<1)
#define WF2i_LYOVER		(1<<2)
#define WF2i_BTCLICK0	(1<<3)
#define WF2i_BTCLICK1	(1<<4)
#define WF2i_BTOVER		(1<<5)
#define WF2i_BLCLICK0	(1<<6)
#define WF2i_BLCLICK1	(1<<7)
#define WF2i_BLOVER		(1<<8)
#define WF2i_BRCLICK0	(1<<9)
#define WF2i_BRCLICK1	(1<<10)
#define WF2i_BROVER		(1<<11)
#define WF2i_BBCLICK0	(1<<12)
#define WF2i_BBCLICK1	(1<<13)
#define WF2i_BBOVER		(1<<14)
#define WF2i_CLICK0		(1<<15)
#define WF2i_CLICK1		(1<<16)
#define WF2i_OVER			(1<<17)
#define WF2i_ASETTOTOP	(1<<18) // already set to top


// Button flags
#define BF_ACTIVE		(1<<0)
#define BF_DISABLED	(1<<1)
#define BF_IGNOREKEYBOARD	(1<<2)

#define BFi_TITLEBAR	(1<<4) // an X, max, min or restore button
#define BFi_SCROLLBAR	(1<<5) // scrollbar button
#define BFi_ENTER		(1<<6) // enter button pressed, don't trigger event again
#define BFi_SPACE		(1<<7) // enter button pressed, don't trigger event again
#define BFi_BLOCKSPACE		(1<<8) // don't trigger event with space after if was triggered with enter
#define BF_EXTERNSTRING	(1<<9) // Caption string not recreated, but pointer taken from parameter
#define BF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed
#define BFi_COMBOBOX (1<<11) // Button of a combobox

#define BF_SHOW		(1<<14) // wie SHOW

#define BF_EVENT		(1<<27)
#define BF_CLICKED	(1<<28)
#define BFi_CLICK0	(1<<29)
#define BFi_CLICK1	(1<<30)
#define BFi_OVER		(1<<31)




// Panel flags
#define PF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed
#define PF_DONTDESTROYPANEL (1<<11) // Don't destroy panel when the object is destroyed
#define PF_HIDE		 (1<<12) // Hide panel when object is destroyed

#define PF_SHOW		(1<<14) // wie SHOW




// Text flags
#define TF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed
#define TF_DONTDESTROYTEXT (1<<11) // Don't destroy text when the object is destroyed
#define TF_HIDE		 (1<<12) // Hide panel when object is destroyed

#define TF_SHOW		(1<<14) // wie SHOW



// Checkbox flags
#define CF_DISABLED	(1<<1)


#define CF_EXTERNSTRING	(1<<9) // Caption string not recreated, but pointer taken from parameter

#define CF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed


#define CF_SHOW		(1<<14) // wie SHOW


#define CF_RADIO		(1<<25) // The checkbox is a radiobutton
#define CF_CHECKED	(1<<26)
#define CF_EVENT		(1<<27)
#define CF_CLICKED	(1<<28)
#define CFi_CLICK0	(1<<29)
#define CFi_CLICK1	(1<<30)
#define CFi_OVER		(1<<31)




// Infobox flags
#define IF_DISABLED	(1<<1)


#define IF_EXTERNSTRING	(1<<9) // Caption string not recreated, but pointer taken from parameter

#define IF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed


#define IF_SHOW		(1<<14) // wie SHOW

#define IF_SHOWING	(1<<31) // wenn es gerade sichbar ist




// Progress bar flags
#define PBF_EXTERNFORMAT	(1<<9) // Caption string not recreated, but pointer taken from parameter

#define PBF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed


#define PBF_SHOW		(1<<14) // wie SHOW

#define PBF_SCALE		(1<<31)




// Horizontal scrollbar flags
#define HSF_DISABLED	(1<<1)

#define HSF_SHOW		(1<<14) // wie SHOW

#define HSF_AUTODISABLED	(1<<21) // Disabled by WF_AUTOHSCROLL (not used anymore!)

#define HSF_CORNER	(1<<25) // show corner

#define HSFi_CLICK0		(1<<29)
#define HSFi_CLICK1		(1<<30)
#define HSFi_OVER			(1<<31)



// Vertical scrollbar flags
#define VSF_DISABLED	(1<<1)

#define VSF_SHOW		(1<<14) // wie SHOW

#define VSF_AUTODISABLED	(1<<21) // Disabled by WF_AUTOVSCROLL (not used anymore!)

#define VSF_CORNER	(1<<25) // show corner

#define VSFi_CLICK0		(1<<29)
#define VSFi_CLICK1		(1<<30)
#define VSFi_OVER			(1<<31)



// Slider flags
#define SF_DISABLED	(1<<1)


#define SF_EXTERNVAR	(1<<8)

#define SF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed


#define SF_SHOW		(1<<14) // wie SHOW


#define SFi_CLICK0		(1<<29)
#define SFi_CLICK1		(1<<30)
#define SFi_OVER			(1<<31)



// Listbox flags
#define LF_DISABLED	(1<<1)
#define LF_MULTIPLE	(1<<2) // enables multiple selection
#define LF_UNSELECT	(1<<3) // enables unselecting
#define LFi_RIGHTCLICK	(1<<4) // rightclick menu

#define LF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed
#define LFi_COMBOBOX		(1<<11) // part of a combobox

#define LF_SHOW		(1<<14) // wie SHOW

#define LF_VSCROLLBAR	(1<<20) // vertical scrollbar

#define LF_AUTOVSCROLL	(1<<22)


// List item flags
#define LIF_EXTERNSTRING	(1<<9) // Caption string not recreated, but pointer taken from parameter

#define LIF_SHOW		(1<<14) // wie SHOW

#define LIF_MARKED	(1<<26)

#define LIF_EVENT		(1<<27)
#define LIF_CLICKED	(1<<28)
#define LIFi_CLICK0		(1<<29)
#define LIFi_CLICK1		(1<<30)
#define LIFi_OVER			(1<<31)


// Rightclick menu flags
#define RF_ACTIVE	(1<<0)
#define RF_DISABLED	(1<<1)

#define RF_SHOW		(1<<14) // wie SHOW

#define RF_EVENT		(1<<27)
#define RF_CLICKED	(1<<28)
#define RFi_CLICK0		(1<<29)
#define RFi_CLICK1		(1<<30)
#define RFi_OVER			(1<<31)


// Combobox flags
#define CBF_DISABLED	(1<<1)

#define CBF_EXTERNSTRING	(1<<9)
#define CBF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed

#define CBF_SHOW		(1<<14) // wie SHOW




// Digits flags
#define DF_EXTERNVAR		(1<<8)
#define DF_EXTERNFORMAT	(1<<9)
#define DF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed

#define DF_SHOW		(1<<14) // wie SHOW




// Editbox flags
#define EF_ACTIVE	(1<<0)
#define EF_DISABLED	(1<<1)
#define EF_READONLY	(1<<2)

#define EF_PASSWORD	(1<<4)
#define EF_NUMBERS	(1<<5)
#define EF_ALPHANUMERIC	(1<<6)
#define EF_NOSPACE	(1<<7)
#define EF_NOUNDERSCORE	(1<<8)
#define EF_EXTERNSTRING	(1<<9)
#define EF_DONTDESTROY (1<<10) // Don't destroy when parent is destroyed

#define EF_SHOW		(1<<14) // wie SHOW

#define EF_EVENT		(1<<27)
#define EF_CLICKED	(1<<28)
#define EFi_CLICK0		(1<<29)
#define EFi_CLICK1		(1<<30)
#define EFi_OVER			(1<<31)






long LBG_flags = 0;

#define LBGUI_RUNNING		(1<<0)
#define LBGUI_DISABLED		(1<<1)
#define LBGUI_PROTECTMOUSE	(1<<2)
#define LBGUI_STOPACTION	(1<<3)
// </lbgui_flags.h>
//-------------------------------------------------------------------------------------------------------


FONT* LBG_window_font = "Courier#14b";
FONT* LBG_button_font = "Arial#14b";
FONT* LBG_checkbox_font = "Arial#14b";
FONT* LBG_infobox_font = "Courier#14";
FONT* LBG_progressbar_font = "Courier#14b";
FONT* LBG_listitem_font = "Courier#14b";
FONT* LBG_editbox_font = "Arial#14b";
FONT* LBG_digits_font = "Courier#14b";

#ifndef LBG_lowest_layer
	#define LBG_lowest_layer 10
#endif
#ifndef LBG_highest_layer
	#define LBG_highest_layer 1000
#endif
#ifndef LBG_winlayer
	#define LBG_winlayer 10
#endif
#ifndef LBG_layer_step
	#define LBG_layer_step 10
#endif
#ifndef LBG_butlayer_step
	#define LBG_butlayer_step 2
#endif

#ifndef LBG_screenpos_x
	#define LBG_screenpos_x 0
#endif
#ifndef LBG_screenpos_y
	#define LBG_screenpos_y 0
#endif
#ifndef LBG_screensize_x
	#define LBG_screensize_x screen_size.x
#endif
#ifndef LBG_screensize_y
	#define LBG_screensize_y screen_size.y
#endif





void LBG_event();
int LBG_condition();

var LBG_mouse_lastpos_x;
var LBG_mouse_lastpos_y;

#define LBG_mouse_moved ((LBG_mouse_lastpos_x != mouse_pos.x) || (LBG_mouse_lastpos_y != mouse_pos.y))
#define LBG_mouse_didnt_move ((LBG_mouse_lastpos_x == mouse_pos.x) && (LBG_mouse_lastpos_y == mouse_pos.y))


STRING* LBG_str_temp = "";

BMAP* LBG_empty_bmap;


var LBG_mouse_cursor = 0;
// 0 = standard
// 1 = over button
// 2 = horizontal scale
// 3 = vertical scale
// 4 = diagonal topleft-buttonright scale
// 5 = diagonal topright-buttonleft scale
// 6 = over an editbox

void LBG_stop_action ()
{
	LBG_flags |= LBGUI_STOPACTION;
}



var LBG_mouse_pos_x ()
{
	if(LBG_flags & LBGUI_PROTECTMOUSE) return(maxv(minv(mouse_pos.x,LBG_screenpos_x+LBG_screensize_x-1),LBG_screenpos_x));
	return mouse_pos.x;
}
var LBG_mouse_pos_y ()
{
	if(LBG_flags & LBGUI_PROTECTMOUSE) return(maxv(minv(mouse_pos.y,LBG_screenpos_y+LBG_screensize_y-1),LBG_screenpos_y));
	return mouse_pos.y;
}


var LBG_str_num_lines (STRING* str)
{
	var ret = 1;
	var x;
	str_cpy(LBG_str_temp,str);
	while(1)
	{
		if(!str_len(LBG_str_temp)) break;
		x = str_stri(LBG_str_temp,"\n");
		if(!x) break;
		ret++;
		str_clip(LBG_str_temp,x);
	}
	return(ret);
}






//-------------------------------------------------------------------------------------------------------
// <lbgui_objfunc.h>
var LBG_object_realpos_x (LBG_WINDOW* obj)
{
	switch (obj->stype)
	{
		case 1:
		return(obj->pos_x);
		break;
		
		case 2:
		if(obj->flags & BFi_COMBOBOX) if(obj->parent->parent) return(obj->parent->parent->cpos_x + obj->pos_x - obj->parent->parent->hscrollamount + obj->parent->pos_x);
		if(!obj->parent) return(obj->pos_x);
		else if(!((obj->flags & BFi_TITLEBAR) || (obj->flags & BFi_SCROLLBAR) || (obj->flags & BFi_COMBOBOX))) return(obj->parent->cpos_x + obj->pos_x - obj->parent->hscrollamount);
		else return(obj->parent->pos_x + obj->pos_x);
		break;
		
		case 3: case 4: case 6: case 11: case 13: case 18:
		if ((obj->stype == 13) && ((obj->flags & LFi_RIGHTCLICK) || (obj->flags & LFi_COMBOBOX))) return obj->pos_x;
		if(!obj->parent) return(obj->pos_x);
		else return(obj->parent->cpos_x + obj->pos_x - obj->parent->hscrollamount);
		break;
		
		case 14:
		return(obj->panel->pos_x);
		break;
		
		
		default:
		return(obj->pos_x);
		break;
	}
}

var LBG_object_realpos_y (LBG_WINDOW* obj)
{
	switch (obj->stype)
	{
		case 1:
		return(obj->pos_y);
		break;
		
		case 2:
		if(obj->flags & BFi_COMBOBOX) if(obj->parent->parent) return(obj->parent->parent->cpos_y + obj->pos_y - obj->parent->parent->vscrollamount + obj->parent->pos_y);
		if(!obj->parent) return(obj->pos_y);
		else if(!((obj->flags & BFi_TITLEBAR) || (obj->flags & BFi_SCROLLBAR) || (obj->flags & BFi_COMBOBOX))) return(obj->parent->cpos_y + obj->pos_y - obj->parent->vscrollamount);
		else return(obj->parent->pos_y + obj->pos_y);
		break;
		
		case 3: case 4: case 6: case 11: case 13: case 18:
		if ((obj->stype == 13) && ((obj->flags & LFi_RIGHTCLICK) || (obj->flags & LFi_COMBOBOX))) return obj->pos_y;
		if(!obj->parent) return(obj->pos_y);
		else return(obj->parent->cpos_y + obj->pos_y - obj->parent->vscrollamount);
		break;
		
		case 14:
		return(obj->panel->pos_y);
		break;
		
		
		default:
		return(obj->pos_y);
		break;
	}
}

var LBG_txt_size_x (TEXT* text)
{
	if(text->size_x) return text->size_x;
	return(65535);
}
var LBG_txt_size_y (TEXT* text)
{
	if(text->size_y) return minv(text->size_y,4096);
	return text->font->dy;
}

int LBG_button_condition (LBG_BUTTON* but, void* func);
int LBG_mouse_over_object (LBG_WINDOW* obj)
{
	if((obj->stype == 2) && (obj->flags & BFi_COMBOBOX)) return (LBG_mouse_pos_x () >= ((LBG_COMBOBOX*)(obj->parent))->editbox->panel->pos_x) && (LBG_mouse_pos_x () < obj->panel->pos_x + obj->panel->size_x*obj->panel->scale_x) && (LBG_mouse_pos_y () >= obj->panel->pos_y) && (LBG_mouse_pos_y () < obj->panel->pos_y + obj->panel->size_y*obj->panel->scale_y);
	if(obj->stype == 3) return (LBG_mouse_pos_x () >= LBG_object_realpos_x(obj)) && (LBG_mouse_pos_x () < LBG_object_realpos_x(obj) + ((LBG_PANEL*)(obj))->panel->size_x) && (LBG_mouse_pos_y () >= LBG_object_realpos_y(obj)) && (LBG_mouse_pos_y () < LBG_object_realpos_y(obj) + ((LBG_PANEL*)(obj))->panel->size_y);
	if((obj->stype == 4) || (obj->stype == 17)) return (LBG_mouse_pos_x () >= LBG_object_realpos_x(obj)) && (LBG_mouse_pos_x () < LBG_object_realpos_x(obj) + LBG_txt_size_x(((LBG_TEXT*)(obj))->text)) && (LBG_mouse_pos_y () >= LBG_object_realpos_y(obj)) && (LBG_mouse_pos_y () < LBG_object_realpos_y(obj) + LBG_txt_size_y(((LBG_TEXT*)(obj))->text));
	return (LBG_mouse_pos_x () >= LBG_object_realpos_x(obj)) && (LBG_mouse_pos_x () < LBG_object_realpos_x(obj) + obj->size_x*obj->scale_x) && (LBG_mouse_pos_y () >= LBG_object_realpos_y(obj)) && (LBG_mouse_pos_y () < LBG_object_realpos_y(obj) + obj->size_y*obj->scale_y);
}


var LBG_object_ppos_x (LBG_WINDOW* obj)
{
	if(!obj->parent) return (0);
	if((obj->stype == 2) && (obj->flags & BFi_COMBOBOX)) return(LBG_object_realpos_x(((LBG_COMBOBOX*)(obj->parent))->editbox) + ((LBG_COMBOBOX*)(obj->parent))->editbox->size_x - obj->pos_x);
	if(!(((obj->flags & BFi_TITLEBAR) || (obj->flags & BFi_SCROLLBAR)) && (obj->stype == 2))) return(obj->parent->cpos_x - obj->parent->hscrollamount);
	else return(obj->parent->pos_x);
}

var LBG_object_ppos_y (LBG_WINDOW* obj)
{
	if(!obj->parent) return (0);
	if((obj->stype == 2) && (obj->flags & BFi_COMBOBOX)) return(LBG_object_realpos_y(((LBG_COMBOBOX*)(obj->parent))->editbox) - obj->pos_y);
	if(!(((obj->flags & BFi_TITLEBAR) || (obj->flags & BFi_SCROLLBAR)) && (obj->stype == 2))) return(obj->parent->cpos_y - obj->parent->vscrollamount);
	else return(obj->parent->pos_y);
}

void LBG_object_update_pos (LBG_WINDOW* obj)
{
	if ((obj->stype == 2) || (obj->stype == 3) || (obj->stype == 6) || (obj->stype == 8) || (obj->stype == 11) || (obj->stype == 18))
	{
		obj->panel->pos_x = obj->pos_x + LBG_object_ppos_x(obj);
		obj->panel->pos_y = obj->pos_y + LBG_object_ppos_y(obj);
		
		
	}
	if ((obj->stype == 2) || (obj->stype == 6) || (obj->stype == 8) || (obj->stype == 18))
	{
		obj->text->pos_x = obj->pos_x + obj->tpos_x + LBG_object_ppos_x(obj);
		obj->text->pos_y = obj->pos_y + obj->tpos_y + LBG_object_ppos_y(obj);
	}
	if ((obj->stype == 4) || (obj->stype == 17))
	{
		((LBG_TEXT*)(obj))->text->pos_x = obj->pos_x + LBG_object_ppos_x(obj);
		((LBG_TEXT*)(obj))->text->pos_y = obj->pos_y + LBG_object_ppos_y(obj);
	}
	if (obj->stype == 8)
	{
		((LBG_PROGRESSBAR*)(obj))->bar->pos_x = obj->pos_x + LBG_object_ppos_x(obj) + ((LBG_PROGRESSBAR*)(obj))->barpos_x;
		((LBG_PROGRESSBAR*)(obj))->bar->pos_y = obj->pos_y + LBG_object_ppos_y(obj) + ((LBG_PROGRESSBAR*)(obj))->barpos_y;
	}
	
	if(obj->stype == 13)
	{
		if(obj->parent)
		if((obj->parent->stype == 15) || (obj->parent->stype == 16))
		{
			obj->panel->pos_x = obj->pos_x;
			obj->panel->pos_y = obj->pos_y;
			return;
		}
		obj->panel->pos_x = obj->pos_x + LBG_object_ppos_x(obj);
		obj->panel->pos_y = obj->pos_y + LBG_object_ppos_y(obj);
	}
	
	if(obj->stype == 14)
	{
		obj->panel->pos_x = obj->pos_x;
		obj->panel->pos_y = obj->pos_y;
		obj->text->pos_x = obj->panel->pos_x + ((LBG_LISTBOX*)(obj->parent))->tpos_x;
		obj->text->pos_y = obj->panel->pos_y + ((LBG_LISTBOX*)(obj->parent))->tpos_y;
	}
	
	if(obj->stype == 17)
	{
		((LBG_DIGITS*)(obj))->text->pos_x = obj->pos_x + LBG_object_ppos_x(obj);
		((LBG_DIGITS*)(obj))->text->pos_y = obj->pos_y + LBG_object_ppos_y(obj);
	}
	
}


var LBG_window_calc_panel_layer (var wlayer);
var LBG_object_calc_panel_layer (LBG_WINDOW* obj)
{
	var layer = obj->layer*LBG_butlayer_step;
	
	
	if(obj->parent)
	{
		switch(obj->parent->stype)
		{
			case 1:
			layer += LBG_window_calc_panel_layer(obj->parent->layer)+3;
			break;
			
			case 9: case 10:
			layer += LBG_window_calc_panel_layer(obj->parent->parent->layer)+3;
			if(obj->stype == 2) layer++;
			break;
		}
		
	}
	else layer += LBG_lowest_layer+1;
	
	if(obj->parent) if((obj->parent->stype == 9) || (obj->parent->stype == 10))
	{
		layer++;
		if(obj->parent->parent) if(obj->parent->parent->stype == 13) layer+= obj->parent->panel->layer+3;
	}
	if(obj->parent) if((obj->stype == 9) || (obj->stype == 10))
	{
		if(obj->parent->stype == 13) layer+= obj->parent->panel->layer+3;
	}
	
	
	
	return(layer);
}

var LBG_object_calc_text_layer (LBG_WINDOW* obj)
{
	var layer = obj->layer*LBG_butlayer_step;
	if(obj->parent) layer += LBG_window_calc_panel_layer(obj->parent->layer)+5;
	else layer += LBG_lowest_layer+2;
	return(layer);
}

int LBG_object_update_size_sb (LBG_BUTTON* obj)
{
	if(obj->stype != 2) return 0;
	if(obj->flags & BFi_TITLEBAR) return 1;
	if(obj->flags & BFi_SCROLLBAR)
	{
		if(obj->parent)
		if((obj->parent->stype == 9) || (obj->parent->stype == 10))
		if(obj->parent->parent)
		if(obj->parent->parent->stype == 13)
		return 0;
		return 1;
	}
	else return 0;
	if(obj->flags & BFi_COMBOBOX)
	{
		if(!obj->parent->parent)
		return 1;
		return 0;
	}
}

void LBG_object_update_size (LBG_WINDOW* obj)
{
	if ((obj->stype == 2) || (obj->stype == 3) || (obj->stype == 6) || (obj->stype == 7) || (obj->stype == 8)  || (obj->stype == 9) || (obj->stype == 10) || (obj->stype == 11) || (obj->stype == 13)  || (obj->stype == 14)  || (obj->stype == 15) || (obj->stype == 18))
	{
		obj->panel->scale_x = obj->scale_x;
		obj->panel->scale_y = obj->scale_y;
	}
	
	if((!obj->parent) || LBG_object_update_size_sb(obj) || ((obj->stype == 13) && ((obj->flags & LFi_RIGHTCLICK) || (obj->flags & LFi_COMBOBOX))))
	{
		if ((obj->stype == 2) || (obj->stype == 6) || (obj->stype == 8) || (obj->stype == 11) || (obj->stype == 13) || (obj->stype == 18))
		{
			obj->panel->size_x = bmap_width(obj->panel->bmap);
			obj->panel->size_y = bmap_height(obj->panel->bmap);
		}
		else if(obj->stype == 3)
		{
			obj->panel->size_x = obj->size_x;
			obj->panel->size_y = obj->size_y;
		}
		
		if ((obj->stype == 2) || (obj->stype == 8))
		{
			obj->text->size_x = bmap_width(obj->panel->bmap)-obj->tpos_x/2;
			obj->text->size_y = bmap_height(obj->panel->bmap)-obj->tpos_y;
		}
		else if((obj->stype == 4) || (obj->stype == 17))
		{
			((LBG_TEXT*)(obj))->text->size_x = obj->size_x;
			((LBG_TEXT*)(obj))->text->size_y = obj->size_y;
		}
		else if(obj->stype == 6)
		{
			obj->text->size_x = 65535;
			obj->text->size_y = 65535;
		}
		
		
		if(obj->stype == 11)
		{
			((LBG_SLIDER*)(obj))->knob->size_x = bmap_width(((LBG_SLIDER*)(obj))->knob->bmap);
			((LBG_SLIDER*)(obj))->knob->size_y = bmap_height(((LBG_SLIDER*)(obj))->knob->bmap);
		}
		
		if(obj->stype == 18)
		{
			obj->text->size_x = bmap_width(obj->panel->bmap)-obj->tpos_x*2;
			obj->text->size_y = bmap_height(obj->panel->bmap)-obj->tpos_y;
			
			((LBG_EDITBOX*)(obj))->cursor->size_x = 65535;
			((LBG_EDITBOX*)(obj))->cursor->size_y = 65535;
		}
		
	}
	else
	{
		if((obj->stype == 2) && (obj->flags & BFi_COMBOBOX))
		{
			if(obj->parent->parent)
			{
				obj->panel->size_x = maxv(0.1,minv(bmap_width(obj->panel->bmap),obj->parent->parent->cpos_x+obj->parent->parent->csize_x-obj->panel->pos_x)+0.1);
				obj->panel->size_y = maxv(0.1,minv(bmap_height(obj->panel->bmap),obj->parent->parent->cpos_y+obj->parent->parent->csize_y-obj->panel->pos_y)+0.1);
			}
		}
		else if((obj->stype == 2) || (obj->stype == 6) || (obj->stype == 8) || (obj->stype == 11) || (obj->stype == 13) || (obj->stype == 18))
		{
			obj->panel->size_x = maxv(0.1,minv(bmap_width(obj->panel->bmap),obj->parent->cpos_x+obj->parent->csize_x-obj->panel->pos_x)+0.1);
			obj->panel->size_y = maxv(0.1,minv(bmap_height(obj->panel->bmap),obj->parent->cpos_y+obj->parent->csize_y-obj->panel->pos_y)+0.1);
			
			switch(obj->parent->stype)
			{
				case 1:
				if ((obj->panel->pos_x < obj->parent->cpos_x) || (obj->panel->pos_y < obj->parent->cpos_y)) obj->panel->size_x = 0.1;
				break;
				case 9: case 10:
				if ((obj->panel->pos_x < obj->parent->parent->cpos_x) || (obj->panel->pos_y < obj->parent->parent->cpos_y)) obj->panel->size_x = 0.1;
				
				if(obj->parent->parent) if(obj->parent->parent->stype == 13)
				{
					obj->panel->size_x = maxv(0.1,minv(bmap_width(obj->panel->bmap),((LBG_LISTBOX*)(obj->parent->parent))->panel->pos_x+((LBG_LISTBOX*)(obj->parent->parent))->panel->size_x-obj->panel->pos_x)+0.1);
					obj->panel->size_y = maxv(0.1,minv(obj->size_y,((LBG_LISTBOX*)(obj->parent->parent))->panel->pos_y+((LBG_LISTBOX*)(obj->parent->parent))->panel->size_y-obj->panel->pos_y)+0.1);
				}
				
				break;
			}
			
		}
		if(obj->stype == 3)
		{
			obj->panel->size_x = maxv(0.1,minv(obj->size_x,obj->parent->cpos_x+obj->parent->csize_x-obj->panel->pos_x)+0.1);
			obj->panel->size_y = maxv(0.1,minv(obj->size_y,obj->parent->cpos_y+obj->parent->csize_y-obj->panel->pos_y)+0.1);
			
			if ((obj->panel->pos_x < obj->parent->cpos_x) || (obj->panel->pos_y < obj->parent->cpos_y)) obj->panel->size_x = 0.1;
			
			
		}
		
		if ((obj->stype == 2) || (obj->stype == 8))
		{
			obj->text->size_x = maxv(1,minv(bmap_width(obj->panel->bmap)-obj->tpos_x/2,obj->parent->cpos_x+obj->parent->csize_x-obj->text->pos_x)+1);
			obj->text->size_y = maxv(1,minv(bmap_height(obj->panel->bmap)-obj->tpos_y,obj->parent->cpos_y+obj->parent->csize_y-obj->text->pos_y)+1);
			
			switch(obj->parent->stype)
			{
				case 1:
				if ((obj->panel->pos_x < obj->parent->cpos_x) || (obj->panel->pos_y < obj->parent->cpos_y)) obj->text->size_x = 1;
				break;
				case 9: case 10:
				if ((obj->text->pos_x < obj->parent->parent->cpos_x) || (obj->text->pos_y < obj->parent->parent->cpos_y)) obj->text->size_x = 1;
				break;
			}
		}
		else if((obj->stype == 4) || (obj->stype == 17))
		{
			if(obj->size_x != 0) ((LBG_TEXT*)(obj))->text->size_x = maxv(1,minv(obj->size_x,obj->parent->cpos_x + obj->parent->csize_x - ((LBG_TEXT*)(obj))->text->pos_x)+1);
			else ((LBG_TEXT*)(obj))->text->size_x = maxv(1,obj->parent->cpos_x + obj->parent->csize_x - ((LBG_TEXT*)(obj))->text->pos_x+1);
			
			if(obj->size_y != 0) ((LBG_TEXT*)(obj))->text->size_y = maxv(1,minv(obj->size_y,obj->parent->cpos_y + obj->parent->csize_y - ((LBG_TEXT*)(obj))->text->pos_y)+1);
			else ((LBG_TEXT*)(obj))->text->size_y = maxv(1,obj->parent->cpos_y + obj->parent->csize_y - ((LBG_TEXT*)(obj))->text->pos_y+1);
			
			if ((((LBG_TEXT*)(obj))->text->pos_x < ((LBG_TEXT*)(obj))->parent->cpos_x) || (((LBG_TEXT*)(obj))->text->pos_y < ((LBG_TEXT*)(obj))->parent->cpos_y)) ((LBG_TEXT*)(obj))->text->size_x = 1;
		}
		else if(obj->stype == 6)
		{
			obj->text->size_x = maxv(1,minv(65535,obj->parent->cpos_x+obj->parent->csize_x-obj->text->pos_x)+1);
			obj->text->size_y = maxv(1,minv(65535,obj->parent->cpos_y+obj->parent->csize_y-obj->text->pos_y)+1);
			if ((obj->text->pos_x < obj->parent->cpos_x) || (obj->text->pos_y < obj->parent->cpos_y)) obj->text->size_x = 1;
		}
		else if (obj->stype == 18)
		{
			obj->text->size_x = maxv(1,minv(bmap_width(obj->panel->bmap)-obj->tpos_x*2,obj->parent->cpos_x+obj->parent->csize_x-obj->text->pos_x)+1);
			obj->text->size_y = maxv(1,minv(bmap_height(obj->panel->bmap)-obj->tpos_y,obj->parent->cpos_y+obj->parent->csize_y-obj->text->pos_y)+1);
			
			((LBG_EDITBOX*)(obj))->cursor->size_x = maxv(1,minv(65535,obj->parent->cpos_x+obj->parent->csize_x-((LBG_EDITBOX*)(obj))->cursor->pos_x)+1);
			((LBG_EDITBOX*)(obj))->cursor->size_y = maxv(1,minv(65535,obj->parent->cpos_y+obj->parent->csize_y-((LBG_EDITBOX*)(obj))->cursor->pos_y)+1);
		}
		
		
		if(obj->stype == 11)
		{
			((LBG_SLIDER*)(obj))->knob->size_x = maxv(0.1,minv(bmap_width(((LBG_SLIDER*)(obj))->knob->bmap),((LBG_SLIDER*)(obj))->parent->cpos_x+((LBG_SLIDER*)(obj))->parent->csize_x-((LBG_SLIDER*)(obj))->knob->pos_x)+0.1);
			((LBG_SLIDER*)(obj))->knob->size_y = maxv(0.1,minv(bmap_height(((LBG_SLIDER*)(obj))->knob->bmap),((LBG_SLIDER*)(obj))->parent->cpos_y+((LBG_SLIDER*)(obj))->parent->csize_y-((LBG_SLIDER*)(obj))->knob->pos_y)+0.1);
			if ((obj->panel->pos_x < obj->parent->cpos_x) || (obj->panel->pos_y < obj->parent->cpos_y)) ((LBG_SLIDER*)(obj))->knob->size_x = 0.1;
		}
		
		if(obj->stype == 14)
		{
			obj->panel->size_x = maxv(0.1,minv(((LBG_LISTBOX*)(obj->parent))->lsize_x,obj->parent->panel->pos_x+obj->parent->panel->size_x-obj->panel->pos_x)+0.1);
			obj->panel->size_y = maxv(0.1,minv(minv(obj->size_y,((LBG_LISTBOX*)(obj->parent))->lpos_y+((LBG_LISTBOX*)(obj->parent))->lsize_y-obj->panel->pos_y),obj->parent->panel->pos_y+obj->parent->panel->size_y-obj->panel->pos_y)+0.1);
			
			
			if((obj->parent->flags & LFi_RIGHTCLICK) || (obj->parent->flags & LFi_COMBOBOX))
			{
				obj->panel->size_x = obj->size_x;
				obj->panel->size_y = obj->size_y;
			}
			
			
			if ((obj->panel->pos_x < ((LBG_LISTBOX*)(obj->parent))->lpos_x) || (obj->panel->pos_y < ((LBG_LISTBOX*)(obj->parent))->lpos_y)) obj->panel->size_x = 0.1;
			
			
			
			obj->text->size_x = obj->panel->size_x - ((LBG_LISTBOX*)(obj->parent))->tpos_x;
			obj->text->size_y = obj->panel->size_y - ((LBG_LISTBOX*)(obj->parent))->tpos_y;
		}
	}
	
}


LBG_WINDOW* LBG_search_disablegui ();
int LBG_find_window_in_parents (LBG_WINDOW* obj,LBG_WINDOW* win);
int LBG_not_disabled_by_disablegui (LBG_WINDOW* obj)
{
	LBG_WINDOW* win = LBG_search_disablegui ();
	if(!win) return 1;
	return LBG_find_window_in_parents(obj,win);
}

LBG_WINDOW* LBG_search_disableparent (LBG_WINDOW* obj);
int LBG_not_disabled_by_disableparent (LBG_WINDOW* obj)
{
	LBG_WINDOW* win = LBG_search_disableparent (obj);
	if(!win) return 1;
	if(win == obj) return 1;
	return LBG_find_window_in_parents(obj,win);
}

int LBG_no_parent_disabled (LBG_WINDOW* obj)
{
	if(!obj) return 1;
	while(obj)
	{
		if(obj->flags & WF_DISABLED) return 0;
		obj = obj->parent;
	}
	return 1;
}


int LBG_not_disabled_by_disableflag (LBG_WINDOW* obj)
{
	if(LBG_flags & LBGUI_DISABLED) return 0;
	return (LBG_not_disabled_by_disablegui(obj) && LBG_not_disabled_by_disableparent(obj) && LBG_no_parent_disabled(obj));
}


#define LBG_object_upate_pos LBG_object_update_pos
#define LBG_object_upate_size LBG_object_update_size


LBG_INFOBOX* LBG_destroy_infobox (LBG_INFOBOX* ifo);
void LBG_object_destroy_infoboxes (LBG_WINDOW* obj)
{
	LBG_INFOBOX* ifo = LBG_INFOBOX_FIRST;
	ifo = LBG_INFOBOX_FIRST;
	while(ifo)
	{
		if(ifo->target == obj)
		{
			if (!(ifo->flags & IF_DONTDESTROY)) ifo = LBG_destroy_infobox (ifo);
			else
			{
				ifo->target = 0;
				ifo = ifo->next;
			}
		}
		else ifo = ifo->next;
	}
}

LBG_RIGHTCLICK* LBG_destroy_rightclick (LBG_RIGHTCLICK* rcl);
void LBG_object_destroy_rightclicks (LBG_WINDOW* obj)
{
	LBG_RIGHTCLICK* rcl = LBG_RIGHTCLICK_FIRST;
	rcl = LBG_RIGHTCLICK_FIRST;
	while(rcl)
	{
		if(rcl->target == obj)
		{
			rcl = LBG_destroy_rightclick (rcl);
		}
		else rcl = rcl->next;
	}
}
// </lbgui_objfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_buttonfunc.h>
LBG_BUTTON* LBG_create_button (LBG_WINDOW* _parent, var pos_x, var pos_y, var tpos_x, var tpos_y, STRING* caption, LBG_BUTTON_BMAPS* bmaps, void *Event, long flags)
{
	LBG_BUTTON* but = malloc(sizeof(LBG_BUTTON));
	but->ssize = sizeof(LBG_BUTTON);
	but->stype = 2;
	
	if(flags & BF_EXTERNSTRING)
	{
		but->caption = caption;
	}
	else
	{
		but->caption = str_create("");
		str_cpy(but->caption,caption);
	}
	
	
	but->parent = _parent;
	but->layer = 0;
	but->flags = flags;
	
	but->text = txt_create(1,LBG_object_calc_text_layer(but));
	ptr_remove((but->text->pstring)[0]);
	(but->text->pstring)[0] = but->caption;
	
	but->text->font = LBG_button_font;
	
	but->tpos_x = tpos_x;
	but->tpos_y = tpos_y;
	
	but->tpos_over_x = 0;
	but->tpos_over_y = 0;
	but->tpos_clicked_x = 0;
	but->tpos_clicked_y = 0;
	
	but->color_default.red = 255;
	but->color_default.green = 255;
	but->color_default.blue = 255;
	
	but->color_over.red = 255;
	but->color_over.green = 255;
	but->color_over.blue = 255;
	
	but->color_clicked.red = 255;
	but->color_clicked.green = 255;
	but->color_clicked.blue = 255;
	
	but->color_disabled.red = 255;
	but->color_disabled.green = 255;
	but->color_disabled.blue = 255;
	
	
	
	but->pos_x = pos_x;
	but->pos_y = pos_y;
	
	but->scale_x = 1;
	but->scale_y = 1;
	
	but->panel = pan_create("",LBG_object_calc_panel_layer(but));
	but->bmap_default = bmaps->bmap_default;
	but->bmap_over = bmaps->bmap_over;
	but->bmap_clicked = bmaps->bmap_clicked;
	but->bmap_active = bmaps->bmap_active;
	but->bmap_overactive = bmaps->bmap_overactive;
	but->bmap_disabled = bmaps->bmap_disabled;
	
	but->size_x = bmap_width(but->bmap_default);
	but->size_y = bmap_height(but->bmap_default);
	
	
	but->panel->bmap = but->bmap_default;
	but->panel->pos_x = but->pos_x;
	but->panel->pos_y = but->pos_y;
	but->panel->size_x = but->size_x;
	but->panel->size_y = but->size_y;
	
	but->text->pos_x = but->pos_x + but->tpos_x;
	but->text->pos_y = but->pos_y + but->tpos_y;
	
	if(but->flags & BF_SHOW)
	{
		but->panel->flags |= SHOW;
		but->text->flags |= SHOW;
	}
	
	but->text.size_x = but.size_x;
	
	
	but->next = NULL;
	if(LBG_BUTTON_FIRST == NULL)
	{
		LBG_BUTTON_FIRST = but;
		but->previous = NULL;
	}
	else
	{
		but->previous = LBG_object_last(LBG_BUTTON_FIRST);
		but->previous->next = but;
	}
	
	
	LBG_object_upate_size (but);
	
	but->Destroy = NULL;
	but->Event = Event;
	but->Over = NULL;
	but->Leave = NULL;
	but->Condition = NULL;
	
	
	return (but);
}

void LBG_button_autoalign_text (LBG_BUTTON* but)
{
	but->tpos_x = integer((but->size_x - minv(but->text->size_x,str_width((but->text->pstring)[0],but->text->font)))/2);
	but->text->pos_x = but->pos_x + but->tpos_x;
}


void LBG_button_execute (LBG_BUTTON* but, void* func)
{
	if(func != 0)
	{
		LBG_event_object = but;
		LBG_event_button = but;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_button_condition (LBG_BUTTON* but, void* func)
{
	if(func != 0)
	{
		LBG_event_object = but;
		LBG_event_button = but;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}


void LBG_button_event (LBG_BUTTON* but)
{
	but.flags &= ~BF_EVENT;
	if(!key_pressed(280)) return;
	LBG_HANDLE* h = LBG_get_eventhandle(but);
	wait(1);
	if(!h->valid)
	{
		LBG_destroy_handle(h);
		return;
	}
	if(!key_pressed(280))
	{
		but->flags |= BF_EVENT;
		LBG_button_execute(but,but->Event);
		wait(1);
		if(!h->valid)
		{
			LBG_destroy_handle(h);
			return;
		}
		but->flags &= ~BF_EVENT;
	}
	LBG_destroy_handle(h);
}

LBG_WINDOW* LBG_mouse_window ();
int LBG_button_mouse_window (LBG_BUTTON* but)
{
	if(but->parent) if ((but->parent->stype == 9) || (but->parent->stype == 10))
	{
		if(but->parent->parent) if(but->parent->parent->stype == 13) return (but->parent->parent->parent == LBG_mouse_window());
		return (but->parent->parent == LBG_mouse_window());
	}
	if(but->flags & BFi_COMBOBOX) return (but->parent->parent == LBG_mouse_window());
	return (but->parent == LBG_mouse_window());
}

void LBG_update_button_layer (LBG_BUTTON* but)
{
	var x;
	
	if(but->flags & BFi_SCROLLBAR)
	if(but->parent)
	if(but->parent->parent)
	if(but->parent->parent->stype == 13)
	{
		x = but->parent->panel->layer+1;
		if(but->panel->layer != x) layer_sort(but->panel,x);
		return;
	}
	
	if(but->flags & BFi_COMBOBOX)
	{
		x = ((LBG_COMBOBOX*)(but->parent))->editbox->panel->layer;
		if(but->panel->layer != x) layer_sort(but->panel,x);
		return;
	}
	
	
	
	x = LBG_object_calc_panel_layer(but);
	if(but->panel->layer != x) layer_sort(but->panel,x);
	x = LBG_object_calc_text_layer(but);
	if(but->text->layer != x) layer_sort(but->text,x);
}


int LBG_window_mouse_over_content (LBG_WINDOW* win);
int LBG_button_scrollbar_condition (LBG_BUTTON* but)
{
	if(!but->parent) return 1;
	if((but->parent->stype != 9) && (but->parent->stype != 10)) return 1;
	if(!but->parent->parent) return 1;
	if(but->parent->parent->stype != 13) return 1;
	if(but->parent->parent->parent)
	{
		return LBG_window_mouse_over_content (but->parent->parent->parent);
	}
	return 1;
}


LBG_WINDOW* LBG_button_parent_window (LBG_BUTTON* but)
{
	if(but->flags & BFi_COMBOBOX) return but->parent->parent;
	else return but->parent;
}


LBG_BUTTON* LBG_manage_button (LBG_BUTTON* but)
{
	LBG_object_update_pos(but);
	LBG_object_update_size(but);
	LBG_update_button_layer(but);
	
	vec_set(but->text->blue,but->color_default);
	
	if (!(but->flags & BF_DISABLED))
	{
		
		
		if(LBG_not_disabled_by_disableflag(but) && (!key_space) && (but->flags & BFi_SPACE))
		{
			if (!(but->flags & BFi_BLOCKSPACE)) LBG_button_execute(but,but->Event);
			else but->flags &= ~BFi_BLOCKSPACE;
			but->flags &= ~BFi_SPACE;
		}
		
		if (LBG_not_disabled_by_disableflag(but) && (but->flags & BF_ACTIVE) && (!(but->flags & BF_IGNOREKEYBOARD)) && (!(but->flags & BFi_SPACE)) && key_space && (!((but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR) || (but->flags & BFi_COMBOBOX))))
		{
			but->flags |= BFi_SPACE;
		}
		
		if (LBG_not_disabled_by_disableflag(but) && (but->flags & BF_ACTIVE) && (!(but->flags & BF_IGNOREKEYBOARD)) && (!(but->flags & BFi_ENTER)) && key_enter && (!((but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR) || (but->flags & BFi_COMBOBOX))))
		{
			LBG_button_execute(but,but->Event);
			but->flags |= BFi_ENTER;
			if(key_space) but->flags |= BFi_BLOCKSPACE;
		}
		if(!key_enter) but->flags &= ~BFi_ENTER;
		
		
		
		if (!(key_pressed(280)))
		{
			but->flags &= ~BFi_CLICK0;
			but->flags &= ~BFi_CLICK1;
			but->flags &= ~BF_CLICKED;
		}
		
		if (LBG_not_disabled_by_disableflag(but) && LBG_button_condition(but,but->Condition) && LBG_mouse_over_object(but) && LBG_button_mouse_window(but) && (LBG_window_mouse_over_content (LBG_button_parent_window(but)) || (but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR) || (but->flags & BFi_COMBOBOX)) && LBG_button_scrollbar_condition(but) && (((!(but->flags & BFi_CLICK0)) && (!(but->flags & BFi_CLICK1))) || ((!(but->flags & BFi_CLICK0)) && ((but->flags & BFi_CLICK1)))))
		{
			LBG_mouse_cursor = 1;
			if(!(but->flags & BFi_OVER)) LBG_button_execute(but,but->Over);
			but->flags |= BFi_OVER;
			if(but->flags & BF_ACTIVE) but->panel.bmap = but->bmap_overactive;
			else but->panel.bmap = but->bmap_over;
			but->text->pos_x += but->tpos_over_x;
			but->text->pos_y += but->tpos_over_y;
			vec_set(but->text->blue,but->color_over);
			if (key_pressed(280))
			{
				but->flags &= ~BFi_CLICK0;
				but->flags |= BFi_CLICK1;
				but->flags |= BF_CLICKED;
				but->panel.bmap = but->bmap_clicked;
				but->text->pos_x += but->tpos_clicked_x-but->tpos_over_x;
				but->text->pos_y += but->tpos_clicked_y-but->tpos_over_y;
				vec_set(but->text->blue,but->color_clicked);
				LBG_button_event(but);
				
				if(!((but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR) || (but->flags & BFi_COMBOBOX)))
				but->flags |= BF_ACTIVE;
				
			}
		}
		else
		{
			if(but->flags & BF_ACTIVE) but->panel.bmap = but->bmap_active;
			else but->panel.bmap = but->bmap_default;
			but.flags &= ~BF_EVENT;
			
			if(but->flags & BFi_OVER) LBG_button_execute(but,but->Leave);
			but->flags &= ~BFi_OVER;
			but->flags &= ~BF_CLICKED;
		}
		if ((!(but->flags & BFi_CLICK0)) && (!(but->flags & BFi_CLICK1)) && (key_pressed(280)))
		{
			but->flags |= BFi_CLICK0;
			but->flags &= ~BFi_CLICK1;
			but->flags &= ~BF_CLICKED;
			
			but->flags &= ~BF_ACTIVE;
			but->flags &= ~BFi_SPACE;
		}
		
		
		if ((but->flags & BFi_SPACE) && (!(but->flags & BFi_BLOCKSPACE)))
		{
			but->panel->bmap = but->bmap_clicked;
			but->text->pos_x = but->pos_x + but->tpos_x + but->tpos_clicked_x + LBG_object_ppos_x(but);
			but->text->pos_y = but->pos_y + but->tpos_y + but->tpos_clicked_x + LBG_object_ppos_y(but);
		}
		
	}
	else
	{
		but->flags |= BFi_CLICK0;
		but->flags &= ~BFi_CLICK1;
		but->flags &= ~BFi_OVER;
		but->flags &= ~BF_CLICKED;
		but->panel->bmap = but->bmap_disabled;
		vec_set(but->text->blue,but->color_disabled);
	}
	
	
	
	
	
	
	
	if(but->flags & BF_SHOW)
	{
		but->panel->flags |= SHOW;
		but->text->flags |= SHOW;
	}
	else
	{
		but->panel->flags &= ~SHOW;
		but->text->flags &= ~SHOW;
	}
	
	
	
	return but->next;
}



LBG_BUTTON* LBG_destroy_button (LBG_BUTTON* but)
{
	
	LBG_button_execute(but,but->Destroy);
	
	if(!(but->flags & BF_EXTERNSTRING)) ptr_remove(but->caption);
	ptr_remove(but->text);
	ptr_remove(but->panel);
	
	LBG_object_destroy_infoboxes(but);
	LBG_object_destroy_rightclicks(but);
	
	
	LBG_BUTTON* next = but->next;
	if(but->previous) but->previous->next = but->next;
	else LBG_BUTTON_FIRST = but->next;
	if(but->next) but->next->previous = but->previous;
	
	free(but);
	LBG_object_make_handles_invalid(but);
	return(next);
}












void LBG_bbmaps_destroy_2frames (LBG_BUTTON_BMAPS* bmaps)
{
	wait(2);
	free(bmaps);
}

LBG_BUTTON_BMAPS* LBG_bbmaps (BMAP* bmap_default, BMAP* bmap_over, BMAP* bmap_clicked, BMAP* bmap_active, BMAP* bmap_overactive, BMAP* bmap_disabled)
{
	LBG_BUTTON_BMAPS* bmaps = malloc(sizeof(LBG_BUTTON_BMAPS));
	bmaps->bmap_default = bmap_default;
	bmaps->bmap_over = bmap_over;
	bmaps->bmap_clicked = bmap_clicked;
	bmaps->bmap_active = bmap_active;
	bmaps->bmap_overactive = bmap_overactive;
	bmaps->bmap_disabled = bmap_disabled;
	LBG_bbmaps_destroy_2frames(bmaps);
	return(bmaps);
}



void LBG_update_button (LBG_BUTTON* but)
{
	LBG_object_upate_pos(but);
	LBG_object_upate_size(but);
	LBG_update_button_layer(but);
}
// </lbgui_buttonfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_panelfunc.h>
LBG_PANEL* LBG_create_panel (LBG_WINDOW* _parent, var pos_x, var pos_y, PANEL* panel, long flags)
{
	LBG_PANEL* pan = malloc(sizeof(LBG_PANEL));
	pan->ssize = sizeof(LBG_PANEL);
	pan->stype = 3;
	
	pan->parent = _parent;
	pan->layer = 0;
	pan->flags = flags;
	
	
	pan->pos_x = pos_x;
	pan->pos_y = pos_y;
	
	pan->scale_x = 1;
	pan->scale_y = 1;
	
	pan->panel = panel;
	
	pan->size_x = pan->panel->size_x;
	pan->size_y = pan->panel->size_y;
	
	
	pan->panel->pos_x = pan->pos_x;
	pan->panel->pos_y = pan->pos_y;
	
	if(pan->flags & PF_SHOW)
	{
		if(pan->panel) pan->panel.flags |= SHOW;
	}
	
	
	
	pan->Destroy = 0;
	
	pan->next = NULL;
	if(LBG_PANEL_FIRST == NULL)
	{
		LBG_PANEL_FIRST = pan;
		pan->previous = NULL;
	}
	else
	{
		pan->previous = LBG_object_last(LBG_PANEL_FIRST);
		pan->previous->next = pan;
	}
	
	return (pan);
}




void LBG_update_panel_layer (LBG_PANEL* pan)
{
	var x;
	x = LBG_object_calc_panel_layer(pan);
	if(pan->panel->layer != x) layer_sort(pan->panel,x);
}

LBG_PANEL* LBG_manage_panel (LBG_PANEL* pan)
{
	LBG_object_upate_pos(pan);
	LBG_object_upate_size(pan);
	LBG_update_panel_layer(pan);
	
	
	if(pan->flags & PF_SHOW)
	{
		pan->panel->flags |= SHOW;
	}
	else
	{
		pan->panel->flags &= ~SHOW;
	}
	
	return pan->next;
}



void LBG_update_panel (LBG_PANEL* pan)
{
	LBG_object_upate_pos(pan);
	LBG_object_upate_size(pan);
	LBG_update_panel_layer(pan);
}

void LBG_panel_execute (LBG_PANEL* pan, void* func)
{
	if(func != 0)
	{
		LBG_event_object = pan;
		LBG_event_panel = pan;
		LBG_event = func;
		LBG_event();
	}
}


LBG_PANEL* LBG_destroy_panel (LBG_PANEL* pan)
{
	LBG_panel_execute(pan,pan->Destroy);
	
	if(pan->flags & PF_HIDE) pan->panel->flags &= ~SHOW;
	if(!(pan->flags & PF_DONTDESTROYPANEL)) ptr_remove(pan->panel);
	
	LBG_object_destroy_infoboxes(pan);
	LBG_object_destroy_rightclicks(pan);
	
	LBG_PANEL* next = pan->next;
	if(pan->previous) pan->previous->next = pan->next;
	else LBG_PANEL_FIRST = pan->next;
	if(pan->next) pan->next->previous = pan->previous;
	
	free(pan);
	LBG_object_make_handles_invalid(pan);
	return(next);
}

// </lbgui_panelfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_textfunc.h>
LBG_TEXT* LBG_create_text (LBG_WINDOW* _parent, var pos_x, var pos_y, TEXT* text, long flags)
{
	LBG_TEXT* txt = malloc(sizeof(LBG_TEXT));
	txt->ssize = sizeof(LBG_TEXT);
	txt->stype = 4;
	
	txt->parent = _parent;
	txt->layer = 0;
	txt->flags = flags;
	
	
	txt->pos_x = pos_x;
	txt->pos_y = pos_y;
	
	txt->scale_x = 1;
	txt->scale_y = 1;
	
	txt->text = text;
	
	txt->size_x = txt->text->size_x;
	txt->size_y = txt->text->size_y;
	
	
	txt->text->pos_x = txt->pos_x;
	txt->text->pos_y = txt->pos_y;
	
	if(txt->flags & TF_SHOW)
	{
		if(txt->text) txt->text.flags |= SHOW;
	}
	
	
	txt->Destroy = 0;
	
	
	txt->next = NULL;
	if(LBG_TEXT_FIRST == NULL)
	{
		LBG_TEXT_FIRST = txt;
		txt->previous = NULL;
	}
	else
	{
		txt->previous = LBG_object_last(LBG_TEXT_FIRST);
		txt->previous->next = txt;
	}
	
	return (txt);
}




void LBG_update_text_layer (LBG_TEXT* txt)
{
	var x;
	x = LBG_object_calc_text_layer(txt);
	if(txt->text->layer != x) layer_sort(txt->text,x);
}

LBG_PANEL* LBG_manage_text (LBG_TEXT* txt)
{
	LBG_object_upate_pos(txt);
	LBG_object_upate_size(txt);
	LBG_update_text_layer(txt);
	
	if(txt->flags & TF_SHOW)
	{
		txt->text->flags |= SHOW;
	}
	else
	{
		txt->text->flags &= ~SHOW;
	}
	
	return txt->next;
}



void LBG_update_text (LBG_TEXT* txt)
{
	LBG_object_upate_pos(txt);
	LBG_object_upate_size(txt);
	LBG_update_text_layer(txt);
}

void LBG_text_execute (LBG_TEXT* txt, void* func)
{
	if(func != 0)
	{
		LBG_event_object = txt;
		LBG_event_text = txt;
		LBG_event = func;
		LBG_event();
	}
}



LBG_TEXT* LBG_destroy_text (LBG_TEXT* txt)
{
	LBG_text_execute(txt,txt->Destroy);
	
	if(txt->flags & TF_HIDE) txt->text->flags &= ~SHOW;
	if(!(txt->flags & TF_DONTDESTROYTEXT)) ptr_remove(txt->text);
	
	LBG_object_destroy_infoboxes(txt);
	LBG_object_destroy_rightclicks(txt);
	
	LBG_TEXT* next = txt->next;
	if(txt->previous) txt->previous->next = txt->next;
	else LBG_TEXT_FIRST = txt->next;
	if(txt->next) txt->next->previous = txt->previous;
	
	free(txt);
	LBG_object_make_handles_invalid(txt);
	return(next);
}

// </lbgui_textfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_checkfunc.h>
void LBG_checkbox_reset_size_x (LBG_CHECKBOX* cbx)
{
	cbx.size_x = maxv(bmap_width(cbx->panel->bmap),cbx->tpos_x + str_width(cbx->caption,cbx->text->font));
}

LBG_CHECKBOX* LBG_create_checkbox (LBG_WINDOW* _parent, var pos_x, var pos_y, var tpos_x, var tpos_y, STRING* caption, LBG_CHECKBOX_BMAPS* bmaps, long flags)
{
	LBG_CHECKBOX* cbx = malloc(sizeof(LBG_CHECKBOX));
	cbx->ssize = sizeof(LBG_CHECKBOX);
	cbx->stype = 6;
	
	if(flags & CF_EXTERNSTRING)
	{
		cbx->caption = caption;
	}
	else
	{
		cbx->caption = str_create("");
		str_cpy(cbx->caption,caption);
	}
	
	
	cbx->parent = _parent;
	cbx->layer = 0;
	cbx->flags = flags;
	
	cbx->text = txt_create(1,LBG_object_calc_text_layer(cbx));
	ptr_remove((cbx->text->pstring)[0]);
	(cbx->text->pstring)[0] = cbx->caption;
	
	cbx->text->font = LBG_checkbox_font;
	
	
	cbx->tpos_x = tpos_x;
	cbx->tpos_y = tpos_y;
	
	cbx->color_default.red = 255;
	cbx->color_default.green = 255;
	cbx->color_default.blue = 255;
	
	cbx->color_over.red = 255;
	cbx->color_over.green = 255;
	cbx->color_over.blue = 255;
	
	cbx->color_clicked.red = 255;
	cbx->color_clicked.green = 255;
	cbx->color_clicked.blue = 255;
	
	cbx->color_disabled.red = 255;
	cbx->color_disabled.green = 255;
	cbx->color_disabled.blue = 255;
	
	
	cbx->pos_x = pos_x;
	cbx->pos_y = pos_y;
	
	cbx->scale_x = 1;
	cbx->scale_y = 1;
	
	cbx->panel = pan_create("",LBG_object_calc_panel_layer(cbx));
	cbx->bmap_default = bmaps->bmap_default;
	cbx->bmap_over = bmaps->bmap_over;
	cbx->bmap_checked = bmaps->bmap_checked;
	cbx->bmap_checked_over = bmaps->bmap_checked_over;
	cbx->bmap_disabled = bmaps->bmap_disabled;
	cbx->bmap_checked_disabled = bmaps->bmap_checked_disabled;
	
	cbx->size_y = bmap_height(cbx->bmap_default);
	
	
	cbx->panel->bmap = cbx->bmap_default;
	cbx->panel->pos_x = cbx->pos_x;
	cbx->panel->pos_y = cbx->pos_y;
	
	cbx->text->pos_x = cbx->pos_x + cbx->tpos_x;
	cbx->text->pos_y = cbx->pos_y + cbx->tpos_y;
	
	if(cbx->flags & CF_SHOW)
	{
		cbx->panel->flags |= SHOW;
		cbx->text->flags |= SHOW;
	}
	
	
	
	
	
	
	cbx->next = NULL;
	if(LBG_CHECKBOX_FIRST == NULL)
	{
		LBG_CHECKBOX_FIRST = cbx;
		cbx->previous = NULL;
	}
	else
	{
		cbx->previous = LBG_object_last(LBG_CHECKBOX_FIRST);
		cbx->previous->next = cbx;
	}
	
	
	LBG_object_upate_size (cbx);
	
	LBG_checkbox_reset_size_x(cbx);
	
	cbx->Destroy = 0;
	cbx->ChangeState = 0;
	cbx->Over = 0;
	cbx->Leave = 0;
	cbx->Condition = 0;
	
	cbx->group = 0;
	
	return (cbx);
}






void LBG_cbmaps_destroy_2frames (LBG_CHECKBOX_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_CHECKBOX_BMAPS* LBG_cbmaps (BMAP* bmap_default, BMAP* bmap_over, BMAP* bmap_checked, BMAP* bmap_checked_over, BMAP* bmap_disabled, BMAP* bmap_checked_disabled)
{
	LBG_CHECKBOX_BMAPS* bmaps = malloc(sizeof(LBG_CHECKBOX_BMAPS));
	bmaps->bmap_default = bmap_default;
	bmaps->bmap_over = bmap_over;
	bmaps->bmap_checked = bmap_checked;
	bmaps->bmap_checked_over = bmap_checked_over;
	bmaps->bmap_disabled = bmap_disabled;
	bmaps->bmap_checked_disabled = bmap_checked_disabled;
	LBG_cbmaps_destroy_2frames(bmaps);
	return(bmaps);
}


void LBG_update_checkbox_layer (LBG_CHECKBOX* cbx)
{
	var x;
	x = LBG_object_calc_panel_layer(cbx);
	if(cbx->panel->layer != x) layer_sort(cbx->panel,x);
	x = LBG_object_calc_text_layer(cbx);
	if(cbx->text->layer != x) layer_sort(cbx->text,x);
}




void LBG_checkbox_execute (LBG_CHECKBOX* cbx, void* func)
{
	if(func != 0)
	{
		LBG_event_object = cbx;
		LBG_event_checkbox = cbx;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_checkbox_condition (LBG_BUTTON* cbx, void* func)
{
	if(func != 0)
	{
		LBG_event_object = cbx;
		LBG_event_checkbox = cbx;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}

void LBG_checkbox_event (LBG_CHECKBOX* cbx)
{
	cbx.flags &= ~CF_EVENT;
	if(!key_pressed(280)) return;
	LBG_HANDLE* h = LBG_get_eventhandle(cbx);
	wait(1);
	if(!h->valid)
	{
		LBG_destroy_handle(h);
		return;
	}
	if(!key_pressed(280))
	{
		cbx->flags |= CF_EVENT;
		if((cbx->flags & CF_CHECKED) && (!(cbx->flags & CF_RADIO))) cbx->flags &= ~CF_CHECKED;
		else
		{
			cbx->flags |= CF_CHECKED;
			if(cbx->flags & CF_RADIO)
			{
				
				LBG_CHECKBOX* cbx1 = LBG_CHECKBOX_FIRST;
				while(cbx1)
				{
					if ((cbx1->parent == cbx->parent) && (cbx1->group == cbx->group) && (cbx1 != cbx) && (cbx1->flags & CF_RADIO)) cbx1->flags &= ~CF_CHECKED;
					cbx1 = cbx1->next;
				}
			}
		}
		LBG_checkbox_execute(cbx,cbx->ChangeState);
		wait(1);
		if(!h->valid)
		{
			LBG_destroy_handle(h);
			return;
		}
		cbx->flags &= ~CF_EVENT;
	}
	LBG_destroy_handle(h);
}




LBG_CHECKBOX* LBG_manage_checkbox (LBG_CHECKBOX* cbx)
{
	LBG_object_upate_pos(cbx);
	LBG_object_upate_size(cbx);
	LBG_update_checkbox_layer(cbx);
	
	
	vec_set(cbx->text->blue,cbx->color_default);
	
	if (!(cbx->flags & CF_DISABLED))
	{
		if (!(key_pressed(280)))
		{
			cbx->flags &= ~CFi_CLICK0;
			cbx->flags &= ~CFi_CLICK1;
			cbx->flags &= ~CF_CLICKED;
		}
		
		if (LBG_not_disabled_by_disableflag(cbx) && LBG_checkbox_condition(cbx,cbx->Condition) && LBG_mouse_over_object(cbx) && (cbx->parent == LBG_mouse_window()) && LBG_window_mouse_over_content (cbx->parent) && (((!(cbx->flags & CFi_CLICK0)) && (!(cbx->flags & CFi_CLICK1))) || ((!(cbx->flags & CFi_CLICK0)) && ((cbx->flags & CFi_CLICK1))))) // ((cbx_click == 0) || (cbx_click == 2))
		{
			if(!(cbx->flags & CFi_OVER)) LBG_checkbox_execute(cbx,cbx->Over);
			cbx->flags |= CFi_OVER;
			if(cbx->flags & CF_CHECKED) cbx->panel.bmap = cbx->bmap_checked_over;
			else cbx->panel.bmap = cbx->bmap_over;
			vec_set(cbx->text->blue,cbx->color_over);
			if (key_pressed(280))
			{
				cbx->flags &= ~CFi_CLICK0;
				cbx->flags |= CFi_CLICK1;
				cbx->flags |= CF_CLICKED;
				if((cbx->flags & CF_CHECKED) && (!(cbx->flags & CF_RADIO))) cbx->panel.bmap = cbx->bmap_over;
				else cbx->panel.bmap = cbx->bmap_checked_over;
				vec_set(cbx->text->blue,cbx->color_clicked);
				LBG_checkbox_event(cbx);
			}
		}
		else
		{
			if(cbx->flags & CF_CHECKED) cbx->panel.bmap = cbx->bmap_checked;
			else cbx->panel.bmap = cbx->bmap_default;
			cbx.flags &= ~CF_EVENT;
			if(cbx->flags & CFi_OVER) LBG_checkbox_execute(cbx,cbx->Leave);
			cbx->flags &= ~CFi_OVER;
			cbx->flags &= ~CF_CLICKED;
		}
		if ((!(cbx->flags & CFi_CLICK0)) && (!(cbx->flags & CFi_CLICK1)) && (key_pressed(280)))
		{
			cbx->flags |= CFi_CLICK0;
			cbx->flags &= ~CFi_CLICK1;
			cbx->flags &= ~CF_CLICKED;
		}
		
	}
	else
	{
		cbx->flags |= CFi_CLICK0;
		cbx->flags &= ~CFi_CLICK1;
		cbx->flags &= ~CFi_OVER;
		cbx->flags &= ~CF_CLICKED;
		if(cbx->flags & CF_CHECKED) cbx->panel.bmap = cbx->bmap_checked_disabled;
		else cbx->panel.bmap = cbx->bmap_disabled;
		vec_set(cbx->text->blue,cbx->color_disabled);
	}
	
	
	if(cbx->flags & CF_SHOW)
	{
		cbx->panel->flags |= SHOW;
		cbx->text->flags |= SHOW;
	}
	else
	{
		cbx->panel->flags &= ~SHOW;
		cbx->text->flags &= ~SHOW;
	}
	
	
	return cbx->next;
}





LBG_CHECKBOX* LBG_destroy_checkbox (LBG_CHECKBOX* cbx)
{
	LBG_checkbox_execute(cbx,cbx->Destroy);
	
	if(!(cbx->flags & CF_EXTERNSTRING)) ptr_remove(cbx->caption);
	ptr_remove(cbx->text);
	ptr_remove(cbx->panel);
	
	LBG_object_destroy_infoboxes(cbx);
	LBG_object_destroy_rightclicks(cbx);
	
	LBG_CHECKBOX* next = cbx->next;
	if(cbx->previous) cbx->previous->next = cbx->next;
	else LBG_CHECKBOX_FIRST = cbx->next;
	if(cbx->next) cbx->next->previous = cbx->previous;
	
	LBG_object_make_handles_invalid(cbx);
	free(cbx);
	return(next);
}


void LBG_update_checkbox (LBG_CHECKBOX* cbx)
{
	LBG_object_upate_pos(cbx);
	LBG_object_upate_size(cbx);
	LBG_update_checkbox_layer(cbx);
}
// </lbgui_checkfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_infofunc.h>

void LBG_window_content_bitmap (BMAP* _bmap, LBG_CBORDER_BMAPS* bmaps, var size_x, var size_y);

LBG_INFOBOX* LBG_create_infobox (LBG_WINDOW* _target, var time, var pos_x, var pos_y, var tpos_x, var tpos_y, STRING* caption, LBG_CBORDER_BMAPS* bmaps, long flags)
{
	LBG_INFOBOX* ifo = malloc(sizeof(LBG_INFOBOX));
	ifo->ssize = sizeof(LBG_INFOBOX);
	ifo->stype = 7;
	
	if(flags & IF_EXTERNSTRING)
	{
		ifo->caption = caption;
	}
	else
	{
		ifo->caption = str_create("");
		str_cpy(ifo->caption,caption);
	}
	
	
	ifo->target = _target;
	ifo->layer = 0;
	ifo->flags = flags;
	
	ifo->text = txt_create(1,LBG_object_calc_text_layer(ifo));
	ptr_remove((ifo->text->pstring)[0]);
	(ifo->text->pstring)[0] = ifo->caption;
	
	ifo->text->font = LBG_infobox_font;
	
	ifo->tpos_x = tpos_x;
	ifo->tpos_y = tpos_y;
	
	ifo->pos_x = pos_x;
	ifo->pos_y = pos_y;
	
	
	
	ifo->scale_x = 1;
	ifo->scale_y = 1;
	
	
	ifo->bmaps.bmap_topleft = bmaps->bmap_topleft;
	ifo->bmaps.bmap_top = bmaps->bmap_top;
	ifo->bmaps.bmap_topright = bmaps->bmap_topright;
	ifo->bmaps.bmap_left = bmaps->bmap_left;
	ifo->bmaps.bmap_right = bmaps->bmap_right;
	ifo->bmaps.bmap_bottomleft = bmaps->bmap_bottomleft;
	ifo->bmaps.bmap_bottom = bmaps->bmap_bottom;
	ifo->bmaps.bmap_bottomright = bmaps->bmap_bottomright;
	ifo->bmaps.bmap_center = bmaps->bmap_center;
	
	
	
	ifo->panel = pan_create("",LBG_object_calc_panel_layer(ifo));
	ifo->panel->bmap = bmap_createblack(str_width(ifo->caption,ifo->text->font) + ifo->tpos_x*2,ifo->text->font->dy + ifo->tpos_y*2,32);
	LBG_window_content_bitmap(ifo->panel->bmap,bmaps,bmap_width(ifo->panel->bmap),bmap_height(ifo->panel->bmap));
	
	
	
	ifo->minsize_x = 0;
	ifo->minsize_y = 0;
	
	ifo->time = time;
	ifo->counter = 0;
	
	ifo->next = NULL;
	if(LBG_INFOBOX_FIRST == NULL)
	{
		LBG_INFOBOX_FIRST = ifo;
		ifo->previous = NULL;
	}
	else
	{
		ifo->previous = LBG_object_last(LBG_INFOBOX_FIRST);
		ifo->previous->next = ifo;
	}
	
	ifo->Destroy = 0;
	ifo->Appear = 0;
	ifo->Disappear = 0;
	ifo->Condition = 0;
	
	
	LBG_object_upate_size (ifo);
	
	
	return (ifo);
}



void LBG_update_infobox_layer (LBG_INFOBOX* ifo)
{
	var x;
	x = LBG_highest_layer-1;
	if(ifo->panel->layer != x) layer_sort(ifo->panel,x);
	x = LBG_highest_layer;
	if(ifo->text->layer != x) layer_sort(ifo->text,x);
}


void LBG_infobox_execute (LBG_INFOBOX* ifo, void* func)
{
	if(func != 0)
	{
		LBG_event_object = ifo;
		LBG_event_infobox = ifo;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_infobox_condition (LBG_INFOBOX* ifo, void* func)
{
	if(func != 0)
	{
		LBG_event_object = ifo;
		LBG_event_infobox = ifo;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}


LBG_INFOBOX* LBG_manage_infobox (LBG_INFOBOX* ifo)
{
	if(ifo->target) if(LBG_not_disabled_by_disableflag(ifo) && (!(ifo->flags & IF_DISABLED)) && LBG_infobox_condition(ifo,ifo->Condition) && LBG_mouse_over_object(ifo->target) && (ifo->target->parent == LBG_mouse_window()) && LBG_window_mouse_over_content (ifo->target->parent) && LBG_mouse_didnt_move && (!key_pressed(280)) && (!key_pressed(281)) && (!key_pressed(282)) && ((ifo->target->stype != 2) || ((ifo->target->flags & BFi_OVER))))
	{
		if(ifo->counter != -1) ifo->counter += time_step/16;
		if(ifo->counter >= ifo->time)
		{
			ifo->flags |= IF_SHOWING;
			LBG_infobox_execute(ifo,ifo->Appear);
			ifo->counter = -1;
			ptr_remove(ifo->panel->bmap);
			ifo->panel->bmap = bmap_createblack(maxv(str_width(ifo->caption,ifo->text->font) + ifo->tpos_x*2,ifo->minsize_x),maxv(ifo->text->font->dy*LBG_str_num_lines(ifo->caption) + ifo->tpos_y*2,ifo->minsize_y),32);
			ifo->panel->size_x = bmap_width(ifo->panel->bmap);
			ifo->panel->size_y = bmap_height(ifo->panel->bmap);
			LBG_window_content_bitmap(ifo->panel->bmap,ifo->bmaps,bmap_width(ifo->panel->bmap),bmap_height(ifo->panel->bmap));
			if(ifo->flags & IF_SHOW)
			{
				ifo->panel->flags |= SHOW;
				ifo->text->flags |= SHOW;
			}
			ifo->panel->pos_x = mouse_pos.x + ifo->pos_x;
			ifo->panel->pos_y = mouse_pos.y + ifo->pos_y;
			
			if(ifo->panel->pos_x < LBG_screenpos_x) ifo->panel->pos_x = 0;
			else if(ifo->panel->pos_x > LBG_screenpos_x + LBG_screensize_x - ifo->panel->size_x) ifo->panel->pos_x = LBG_screenpos_x + LBG_screensize_x - ifo->panel->size_x;
			if(ifo->panel->pos_y < LBG_screenpos_y) ifo->panel->pos_y = 0;
			else if(ifo->panel->pos_y > LBG_screenpos_y + LBG_screensize_y - ifo->panel->size_y) ifo->panel->pos_y = LBG_screenpos_y + LBG_screensize_y - ifo->panel->size_y;
			
			
			ifo->text->pos_x = ifo->panel->pos_x + ifo->tpos_x;
			ifo->text->pos_y = ifo->panel->pos_y + ifo->tpos_y;
			LBG_update_infobox_layer(ifo);
		}
	}
	else
	{
		ifo->counter = 0;
		ifo->panel->flags &= ~SHOW;
		ifo->text->flags &= ~SHOW;
		if(ifo->flags & IF_SHOWING)
		{
			LBG_infobox_execute(ifo,ifo->Disappear);
		}
		ifo->flags &= ~IF_SHOWING;
	}
	else
	{
		ifo->counter = 0;
		ifo->panel->flags &= ~SHOW;
		ifo->text->flags &= ~SHOW;
		if(ifo->flags & IF_SHOWING)
		{
			LBG_infobox_execute(ifo,ifo->Disappear);
		}
		ifo->flags &= ~IF_SHOWING;
	}
	
	return ifo->next;
}





LBG_INFOBOX* LBG_destroy_infobox (LBG_INFOBOX* ifo)
{
	LBG_infobox_execute(ifo,ifo->Destroy);
	if(!(ifo->flags & IF_EXTERNSTRING)) ptr_remove(ifo->caption);
	ptr_remove(ifo->text);
	ptr_remove(ifo->panel);
	
	LBG_INFOBOX* next = ifo->next;
	if(ifo->previous) ifo->previous->next = ifo->next;
	else LBG_INFOBOX_FIRST = ifo->next;
	if(ifo->next) ifo->next->previous = ifo->previous;
	
	free(ifo);
	LBG_object_make_handles_invalid(ifo);
	return(next);
}

// </lbgui_infofunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_progressfunc.h>


void LBG_progressbar_bitmap (BMAP* _bmap, LBG_PROGRESSBAR_BMAPS* bmaps, var size_x, var size_y) // For internal use
{
	bmap_blit(_bmap,bmaps->bmap_pan_left,vector(0,0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_pan_right,vector(size_x-bmap_width(bmaps->bmap_pan_right),0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_pan_middle,vector(bmap_width(bmaps->bmap_pan_left),0,0),vector(size_x-bmap_width(bmaps->bmap_pan_left)-bmap_width(bmaps->bmap_pan_right),bmap_height(bmaps->bmap_pan_middle),0));
}




LBG_PROGRESSBAR* LBG_create_progressbar (LBG_WINDOW* _parent, var pos_x, var pos_y, var width, var barpos_x, var barpos_y, var tpos_x, var tpos_y, STRING* format, LBG_PROGRESSBAR_BMAPS* bmaps, long flags, var maximum, var progress)
{
	LBG_PROGRESSBAR* prg = malloc(sizeof(LBG_PROGRESSBAR));
	prg->ssize = sizeof(LBG_PROGRESSBAR);
	prg->stype = 8;
	
	if(flags & PBF_EXTERNFORMAT)
	{
		prg->format = format;
	}
	else
	{
		prg->format = str_create("");
		str_cpy(prg->format,format);
	}
	prg->caption = str_create("");
	
	
	prg->parent = _parent;
	prg->layer = 0;
	prg->flags = flags;
	
	prg->text = txt_create(1,LBG_object_calc_text_layer(prg));
	ptr_remove((prg->text->pstring)[0]);
	(prg->text->pstring)[0] = prg->caption;
	
	prg->text->font = LBG_progressbar_font;
	
	prg->tpos_x = tpos_x;
	prg->tpos_y = tpos_y;
	
	
	prg->pos_x = pos_x;
	prg->pos_y = pos_y;
	
	prg->scale_x = 1;
	prg->scale_y = 1;
	
	prg->panel = pan_create("",LBG_object_calc_panel_layer(prg));
	prg->bmap_pan_left = bmaps->bmap_pan_left;
	prg->bmap_pan_middle = bmaps->bmap_pan_middle;
	prg->bmap_pan_right = bmaps->bmap_pan_right;
	prg->bmap_bar = bmaps->bmap_bar;
	
	
	prg->size_x = width;
	prg->size_y = bmap_height(prg->bmap_pan_left);
	
	
	prg->panel->bmap = bmap_createblack(prg->size_x,prg->size_y,32);
	LBG_progressbar_bitmap(prg->panel->bmap,bmaps,prg->size_x,prg->size_y);
	prg->panel->pos_x = prg->pos_x;
	prg->panel->pos_y = prg->pos_y;
	prg->panel->size_x = prg->size_x;
	prg->panel->size_y = prg->size_y;
	
	prg->text->pos_x = prg->pos_x + prg->tpos_x;
	prg->text->pos_y = prg->pos_y + prg->tpos_y;
	
	prg->bar = pan_create("",LBG_object_calc_panel_layer(prg)+1);
	prg->bar->bmap = prg->bmap_bar;
	
	if(prg->flags & PBF_SHOW)
	{
		prg->panel->flags |= SHOW;
		prg->bar->flags |= SHOW;
		prg->text->flags |= SHOW;
	}
	
	
	
	
	
	prg->next = NULL;
	if(LBG_PROGRESSBAR_FIRST == NULL)
	{
		LBG_PROGRESSBAR_FIRST = prg;
		prg->previous = NULL;
	}
	else
	{
		prg->previous = LBG_object_last(LBG_PROGRESSBAR_FIRST);
		prg->previous->next = prg;
	}
	
	
	LBG_object_upate_size (prg);
	
	
	prg->maximum = maximum;
	prg->progress = progress;
	
	prg->barpos_x = barpos_x;
	prg->barpos_y = barpos_y;
	
	prg->bar_width = prg->size_x - prg->barpos_x*2;
	
	
	prg->Destroy = 0;
	
	return (prg);
}


void LBG_update_progressbar_layer (LBG_PROGRESSBAR* prg)
{
	var x;
	x = LBG_object_calc_panel_layer(prg);
	if(prg->panel->layer != x) layer_sort(prg->panel,x);
	x = LBG_object_calc_panel_layer(prg)+1;
	if(prg->bar->layer != x) layer_sort(prg->bar,x);
	x = LBG_object_calc_text_layer(prg);
	if(prg->text->layer != x) layer_sort(prg->text,x);
}

void LBG_update_progressbar_string (LBG_PROGRESSBAR* prg)
{
	str_printf(prg->caption, prg->format,(double)prg->progress);
}



LBG_PROGRESSBAR* LBG_manage_progressbar (LBG_PROGRESSBAR* prg)
{
	LBG_object_upate_pos(prg);
	LBG_object_upate_size(prg);
	LBG_update_progressbar_layer(prg);
	
	if(!(prg->flags & PBF_SCALE))
	{
		prg->bar->size_x = prg->bar_width*prg->progress/prg->maximum;
		prg->bar->size_y = bmap_height(prg->bar->bmap);
		
		if(prg->parent)
		{
			prg->bar->size_x = maxv(0.1,minv(prg->bar->size_x,prg->parent->cpos_x+prg->parent->csize_x-prg->bar->pos_x)+0.1);
			prg->bar->size_y = maxv(0.1,minv(prg->bar->size_y,prg->parent->cpos_y+prg->parent->csize_y-prg->bar->pos_y)+0.1);
		}
		else
		{
			prg->bar->size_x += 0.1;
			prg->bar->size_y += 0.1;
		}
	}
	else
	{
		prg->bar->size_x = bmap_width(prg->bar->bmap);
		prg->bar->size_y = bmap_height(prg->bar->bmap);
		if(prg->maximum && prg->bar->size_x) prg->bar->scale_x = prg->bar_width*prg->progress/prg->maximum/prg->bar->size_x;
		if(prg->parent)
		{
			if(prg->progress > 0)
			{
				if(prg->bar->scale_x) prg->bar->size_x = maxv(0.1,minv(prg->bar->size_x,(prg->parent->cpos_x+prg->parent->csize_x-prg->bar->pos_x)/prg->bar->scale_x)+0.1);
			}
			else prg->bar->size_x = 0.1;
			prg->bar->size_y = maxv(0.1,minv(prg->bar->size_y,prg->parent->cpos_y+prg->parent->csize_y-prg->bar->pos_y)+0.1);
		}
		else if(!prg->bar->scale_x) prg->bar->size_x = 0.1;
	}
	if((prg->bar->size_x < 0.5) || (prg->bar->scale_x < 0.003)) prg->bar->size_x = 0.1;
	if(prg->parent) if ((prg->panel->pos_x < prg->parent->cpos_x) || (prg->panel->pos_y < prg->parent->cpos_y)) prg->bar->size_x = 0.1;
	LBG_update_progressbar_string(prg);
	
	if(prg->flags & PBF_SHOW)
	{
		prg->panel->flags |= SHOW;
		prg->text->flags |= SHOW;
		prg->bar->flags |= SHOW;
	}
	else
	{
		prg->panel->flags &= ~SHOW;
		prg->text->flags &= ~SHOW;
		prg->bar->flags &= ~SHOW;
	}
	return prg->next;
}







void LBG_pbmaps_destroy_2frames (LBG_PROGRESSBAR_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_PROGRESSBAR_BMAPS* LBG_pbmaps (BMAP* bmap_pan_left, BMAP* bmap_pan_middle, BMAP* bmap_pan_right, BMAP* bmap_bar)
{
	LBG_PROGRESSBAR_BMAPS* bmaps = malloc(sizeof(LBG_PROGRESSBAR_BMAPS));
	bmaps->bmap_pan_left = bmap_pan_left;
	bmaps->bmap_pan_middle = bmap_pan_middle;
	bmaps->bmap_pan_right = bmap_pan_right;
	bmaps->bmap_bar = bmap_bar;
	LBG_pbmaps_destroy_2frames(bmaps);
	return(bmaps);
}


void LBG_progressbar_execute (LBG_PROGRESSBAR* prg, void* func)
{
	if(func != 0)
	{
		LBG_event_object = prg;
		LBG_event_progressbar = prg;
		LBG_event = func;
		LBG_event();
	}
}


LBG_PROGRESSBAR* LBG_destroy_progressbar (LBG_PROGRESSBAR* prg)
{
	LBG_progressbar_execute(prg,prg->Destroy);
	if(!(prg->flags & PBF_EXTERNFORMAT)) ptr_remove(prg->format);
	ptr_remove(prg->caption);
	ptr_remove(prg->text);
	ptr_remove(prg->panel);
	ptr_remove(prg->bar);
	
	LBG_object_destroy_infoboxes(prg);
	LBG_object_destroy_rightclicks(prg);
	
	LBG_PROGRESSBAR* next = prg->next;
	if(prg->previous) prg->previous->next = prg->next;
	else LBG_PROGRESSBAR_FIRST = prg->next;
	if(prg->next) prg->next->previous = prg->previous;
	
	free(prg);
	LBG_object_make_handles_invalid(prg);
	return(next);
}


void LBG_update_progressbar(LBG_PROGRESSBAR* prg)
{
	LBG_object_upate_pos(prg);
	LBG_object_upate_size(prg);
	LBG_update_progressbar_layer(prg);
	ptr_remove(prg->panel->bmap);
	prg->panel->bmap = bmap_createblack(prg->size_x,prg->size_y,32);
	LBG_progressbar_bitmap(prg->panel->bmap,&(prg->bmap_pan_left),prg->size_x,prg->size_y);
}
// </lbgui_progressfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_hscrollfunc.h>
void LBG_hscrollbar_bitmap (BMAP* _bmap, LBG_HSCROLLBAR_BMAPS* bmaps, var size_x, var size_y) // For internal use
{
	bmap_blit(_bmap,bmaps->bmap_left,vector(0,0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_right,vector(size_x-bmap_width(bmaps->bmap_right),0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_middle,vector(bmap_width(bmaps->bmap_left),0,0),vector(size_x-bmap_width(bmaps->bmap_left)-bmap_width(bmaps->bmap_right),bmap_height(bmaps->bmap_middle),0));
}



void LBG_update_window (LBG_WINDOW* win);
LBG_HSCROLLBAR* LBG_create_hscrollbar (LBG_WINDOW* _target, LBG_HSCROLLBAR_BMAPS* bmaps, LBG_BUTTON_BMAPS* blbmaps, LBG_BUTTON_BMAPS* brbmaps, long flags)
{
	LBG_HSCROLLBAR* hsb = malloc(sizeof(LBG_HSCROLLBAR));
	hsb->ssize = sizeof(LBG_HSCROLLBAR);
	hsb->stype = 9;
	
	
	
	
	hsb->target = _target;
	hsb->layer = 0;
	hsb->flags = flags;
	
	
	
	hsb->scale_x = 1;
	hsb->scale_y = 1;
	
	hsb->panel = pan_create("",LBG_object_calc_panel_layer(hsb));
	hsb->bmaps.bmap_left = bmaps->bmap_left;
	hsb->bmaps.bmap_middle = bmaps->bmap_middle;
	hsb->bmaps.bmap_right = bmaps->bmap_right;
	hsb->bmaps.bmap_bar = bmaps->bmap_bar;
	hsb->bmaps.bmap_corner = bmaps->bmap_corner;
	
	
	hsb->panel->bmap = hsb->bmaps.bmap_bar;
	
	
	if(hsb->target)
	switch(hsb->target->stype)
	{
		case 1:
			hsb->ppa = 0.2;
			hsb->wheelspeed = 5;
		break;
		
		default:
			hsb->ppa = 1;
			hsb->wheelspeed = 1;
		break;
	}
	
	
	hsb->size_x = 32;
	hsb->size_y = bmap_height(hsb->bmaps.bmap_bar);
	hsb->scrollbar = pan_create("",LBG_object_calc_panel_layer(hsb)+1);
	hsb->scrollbar->bmap = bmap_createblack(hsb->size_x,hsb->size_y,32);
	LBG_hscrollbar_bitmap(hsb->scrollbar->bmap,bmaps,hsb->size_x,hsb->size_y);
	
	hsb->corner = pan_create("",LBG_object_calc_panel_layer(hsb)+1);
	if(hsb->bmaps.bmap_corner) hsb->corner->bmap = hsb->bmaps.bmap_corner;
	else hsb->corner->bmap = hsb->bmaps.bmap_left;
	
	
	
	
	
	hsb->button_left = LBG_create_button(hsb,0,0,0,0,"",blbmaps,0,BF_SHOW | BFi_SCROLLBAR);
	hsb->button_right = LBG_create_button(hsb,0,0,0,0,"",brbmaps,0,BF_SHOW | BFi_SCROLLBAR);
	
	
	
	if(hsb->flags & PBF_SHOW)
	{
		hsb->panel->flags |= SHOW;
		hsb->scrollbar->flags |= SHOW;
		hsb->button_left->flags |= BF_SHOW;
	}
	
	
	hsb->scrollamount = 0;
	hsb->scrollmax = 0;
	hsb->buttonspeed = 5;
	
	
	
	hsb->next = NULL;
	if(LBG_HSCROLLBAR_FIRST == NULL)
	{
		LBG_HSCROLLBAR_FIRST = hsb;
		hsb->previous = NULL;
	}
	else
	{
		hsb->previous = LBG_object_last(LBG_HSCROLLBAR_FIRST);
		hsb->previous->next = hsb;
	}
	
	
	LBG_object_upate_size (hsb);
	
	switch(hsb->target->stype)
	{
		case 1:
		hsb->target->flags |= WF_HSCROLLBAR;
		LBG_update_window(hsb->target);
		break;
	}
	
	hsb->Destroy = 0;
	hsb->Scrolling = 0;
	hsb->Condition = 0;
	
	
	return (hsb);
}


void LBG_update_hscrollbar_layer (LBG_HSCROLLBAR* hsb)
{
	var x;
	x = LBG_object_calc_panel_layer(hsb);
	if(hsb->panel->layer != x) layer_sort(hsb->panel,x);
	x = LBG_object_calc_panel_layer(hsb)+1;
	if(hsb->scrollbar->layer != x) layer_sort(hsb->scrollbar,x);
	x = LBG_object_calc_panel_layer(hsb);
	if(hsb->corner->layer != x) layer_sort(hsb->corner,x);
	LBG_update_button_layer (hsb->button_left);
	LBG_update_button_layer (hsb->button_right);
}



var LBG_hscrollbar_get_minwidth(LBG_HSCROLLBAR* hsb)
{
	return(bmap_width(hsb->bmaps.bmap_left) + bmap_width(hsb->bmaps.bmap_middle) + bmap_width(hsb->bmaps.bmap_right));
}
var LBG_hscrollbar_get_maxwidth(LBG_HSCROLLBAR* hsb)
{
	return(hsb->size_x - hsb->button_left->size_x - hsb->button_right->size_x);
}


void LBG_hscrollbar_calc_barwidth(LBG_HSCROLLBAR* hsb)
{
	hsb->scrollbar->size_x = integer(maxv(LBG_hscrollbar_get_minwidth(hsb),LBG_hscrollbar_get_maxwidth(hsb) - hsb->scrollmax*hsb->ppa)+0.5);
}


int LBG_mouse_over_hscrollbar_move(LBG_HSCROLLBAR* hsb)
{
	if(hsb) return ((mouse_pos.x >= hsb->scrollbar->pos_x) && (mouse_pos.x < hsb->scrollbar->pos_x + hsb->scrollbar->size_x) && (mouse_pos.y >= hsb->scrollbar->pos_y) && (mouse_pos.y < hsb->scrollbar->pos_y + hsb->scrollbar->size_y) && (LBG_mouse_window() == hsb->target));
	else return 0;
}



void LBG_hscrollbar_execute (LBG_HSCROLLBAR* hsb, void* func)
{
	if(func != 0)
	{
		LBG_event_object = hsb;
		LBG_event_scrollbar = hsb;
		LBG_event_hscrollbar = hsb;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_hscrollbar_condition (LBG_HSCROLLBAR* hsb, void* func)
{
	if(func != 0)
	{
		LBG_event_object = hsb;
		LBG_event_scrollbar = hsb;
		LBG_event_hscrollbar = hsb;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}

LBG_WINDOW* LBG_scrollbar_parent_window(LBG_HSCROLLBAR* sb)
{
	LBG_WINDOW* p = sb->target;
	while(p)
	{
		if(p->stype == 1) break;
		p = p->parent;
	}
	return p;
}

int LBG_hscrollbar_mouse_for_wheel (LBG_HSCROLLBAR* hsb);
int LBG_vscrollbar_mouse_for_wheel (LBG_VSCROLLBAR* vsb);
int LBG_scrollbar_no_other (LBG_HSCROLLBAR* sb)
{
	if(sb->target->stype != 1) return 1;
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	while(hsb)
	{
		if((LBG_scrollbar_parent_window(hsb) == sb->target) && (!((hsb == sb) || (hsb->target == sb->target) || (hsb->target->stype == 1)))) if (LBG_hscrollbar_mouse_for_wheel(hsb))
		return 0;
		hsb = hsb->next;
	}
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if((LBG_scrollbar_parent_window(vsb) == sb->target) && (!((vsb == sb) || (vsb->target == sb->target) || (vsb->target->stype == 1)))) if (LBG_vscrollbar_mouse_for_wheel(vsb))
		return 0;
		vsb = vsb->next;
	}
	return 1;
}


int LBG_hscrollbar_mouse_for_wheel (LBG_HSCROLLBAR* hsb)
{
	if(hsb->target)
	switch(hsb->target->stype)
	{
		case 1:
			if(!LBG_scrollbar_no_other(hsb)) return 0;
			return(LBG_window_mouse_over_content(hsb->target) && (LBG_mouse_window() == hsb->target) && LBG_hscrollbar_condition(hsb,hsb->Condition));
		break;
		default: return 0;
	}
}





LBG_HSCROLLBAR* LBG_manage_hscrollbar (LBG_HSCROLLBAR* hsb)
{
	int target_vscroll = 0;
	LBG_update_hscrollbar_layer(hsb);
	
	if(hsb->target)
	switch(hsb->target->stype)
	{
		case 1:
			target_vscroll = hsb->target->flags & WF_VSCROLLBAR;
		break;
		default: return 0;
	}
	
	
	if ((!((hsb->flags & HSF_DISABLED) || (hsb->flags & HSF_AUTODISABLED))) && (hsb->target->flags & WF_HSCROLLBAR) && LBG_not_disabled_by_disableflag(hsb))
	{
		
		if (!(key_pressed(280)))
		{
			hsb->flags &= ~HSFi_CLICK0;
			hsb->flags &= ~HSFi_CLICK1;
		}
		if (LBG_mouse_over_hscrollbar_move(hsb) && (((!(hsb->flags & HSFi_CLICK0)) && (!(hsb->flags & HSFi_CLICK1))) || ((!(hsb->flags & HSFi_CLICK0)) && ((hsb->flags & HSFi_CLICK1)))))
		{
			hsb->flags |= HSFi_OVER;
			if (key_pressed(280))
			{
				if(!((!(hsb->flags & HSFi_CLICK0)) && ((hsb->flags & HSFi_CLICK1))))
				{
					hsb->mg = mouse_pos.x - hsb->scrollbar->pos_x;
				}
				
				hsb->flags &= ~HSFi_CLICK0;
				hsb->flags |= HSFi_CLICK1;
			}
		}
		else
		{
			if(!(hsb->flags & HSFi_OVER))
			{
				hsb->flags &= ~HSFi_OVER;
			}
		}
		if ((!(hsb->flags & HSFi_CLICK0)) && ((hsb->flags & HSFi_CLICK1)))
		{
			hsb->scrollbar->pos_x = mouse_pos.x - hsb->mg;
			LBG_hscrollbar_execute(hsb,hsb->Scrolling);
			
			if (LBG_hscrollbar_get_maxwidth(hsb) - hsb->scrollbar->size_x) hsb->scrollamount = (hsb->scrollbar->pos_x - hsb->pos_x - hsb->button_left->size_x)*hsb->scrollmax/(LBG_hscrollbar_get_maxwidth(hsb) - hsb->scrollbar->size_x);
			else hsb->scrollamount = 0;
		}
		if ((!(hsb->flags & HSFi_CLICK0)) && (!(hsb->flags & HSFi_CLICK1)) && (key_pressed(280)))
		{
			hsb->flags |= HSFi_CLICK0;
			hsb->flags &= ~HSFi_CLICK1;
		}
		
	}
	
	
	
	if(hsb->target)
	switch(hsb->target->stype)
	{
		case 1:
		hsb->pos_x = hsb->target->cpos_x;
		hsb->pos_y = hsb->target->cpos_y + hsb->target->csize_y;
		hsb->size_x = hsb->target->csize_x;
		
		hsb->panel->pos_x = hsb->pos_x;
		hsb->panel->pos_y = hsb->pos_y;
		hsb->panel->size_x = hsb->size_x;
		
		hsb->button_right->pos_x = hsb->size_x - hsb->button_right->size_x;
		
		
		hsb->scrollbar->pos_x = hsb->pos_x + hsb->button_left->size_x;
		hsb->scrollbar->pos_y = hsb->pos_y;
		
		hsb->corner->pos_x = hsb->pos_x + hsb->size_x;
		hsb->corner->pos_y = hsb->pos_y;
		
		
		
		
		break;
	}
	
	
	LBG_hscrollbar_calc_barwidth(hsb);
	if(hsb->scrollbar->size_x != bmap_width(hsb->scrollbar->bmap))
	{
		ptr_remove(hsb->scrollbar->bmap);
		hsb->scrollbar->bmap = bmap_createblack(hsb->scrollbar->size_x,hsb->size_y,32);
		LBG_hscrollbar_bitmap(hsb->scrollbar->bmap,hsb->bmaps,hsb->scrollbar->size_x,hsb->size_y);
	}
	
	if((hsb->button_left->flags & BF_CLICKED) && LBG_mouse_over_object(hsb->button_left))
	{
		hsb->scrollamount -= hsb->buttonspeed*time_step;
		LBG_hscrollbar_execute(hsb,hsb->Scrolling);
	}
	if((hsb->button_right->flags & BF_CLICKED) && LBG_mouse_over_object(hsb->button_right))
	{
		hsb->scrollamount += hsb->buttonspeed*time_step;
		LBG_hscrollbar_execute(hsb,hsb->Scrolling);
	}
	
	if(LBG_hscrollbar_mouse_for_wheel(hsb) && (!target_vscroll) && LBG_not_disabled_by_disableflag(hsb)) hsb->scrollamount -= hsb->wheelspeed*mickey.z/12;
	if(LBG_hscrollbar_mouse_for_wheel(hsb) && (!target_vscroll) && LBG_not_disabled_by_disableflag(hsb) && hsb->wheelspeed*mickey.z) LBG_hscrollbar_execute(hsb,hsb->Scrolling);
	
	hsb->scrollamount = minv(hsb->scrollamount,hsb->scrollmax);
	hsb->scrollamount = maxv(hsb->scrollamount,0);
	if(hsb->scrollmax) hsb->scrollbar->pos_x += (LBG_hscrollbar_get_maxwidth(hsb)-hsb->scrollbar->size_x)*hsb->scrollamount/hsb->scrollmax;
	
	if(hsb->target) hsb->target->hscrollamount = hsb->scrollamount;
	
	
	
	
	
	
	
	
	if(hsb->flags & HSF_SHOW)
	{
		hsb->panel->flags |= SHOW;
		hsb->scrollbar->flags |= SHOW;
		hsb->corner->flags |= SHOW;
		hsb->button_left->flags |= BF_SHOW;
		hsb->button_right->flags |= BF_SHOW;
	}
	else
	{
		hsb->panel->flags &= ~SHOW;
		hsb->scrollbar->flags &= ~SHOW;
		hsb->corner->flags &= ~SHOW;
		hsb->button_left->flags &= ~BF_SHOW;
		hsb->button_right->flags &= ~BF_SHOW;
	}
	
	hsb->corner->flags &= ~SHOW;
	if((hsb->flags & HSF_SHOW) && (target_vscroll))
	hsb->corner->flags |= SHOW;
	
	if((hsb->flags & HSF_AUTODISABLED) || (!(hsb->target->flags & WF_HSCROLLBAR)))
	{
		hsb->panel->flags &= ~SHOW;
		hsb->scrollbar->flags &= ~SHOW;
		hsb->corner->flags &= ~SHOW;
		hsb->button_left->flags &= ~BF_SHOW;
		hsb->button_right->flags &= ~BF_SHOW;
	}
	
	
	
	
	return(hsb->next);
}



void LBG_hsbmaps_destroy_2frames (LBG_HSCROLLBAR_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_HSCROLLBAR_BMAPS* LBG_hsbmaps (BMAP* bmap_left, BMAP* bmap_middle, BMAP* bmap_right, BMAP* bmap_bar, BMAP* bmap_corner)
{
	LBG_HSCROLLBAR_BMAPS* bmaps = malloc(sizeof(LBG_HSCROLLBAR_BMAPS));
	bmaps->bmap_left = bmap_left;
	bmaps->bmap_middle = bmap_middle;
	bmaps->bmap_right = bmap_right;
	bmaps->bmap_bar = bmap_bar;
	bmaps->bmap_corner = bmap_corner;
	LBG_pbmaps_destroy_2frames(bmaps);
	return(bmaps);
}



LBG_HSCROLLBAR* LBG_destroy_hscrollbar (LBG_HSCROLLBAR* hsb)
{
	LBG_hscrollbar_execute(hsb,hsb->Destroy);
	
	ptr_remove(hsb->panel);
	ptr_remove(hsb->scrollbar);
	ptr_remove(hsb->corner);
	LBG_destroy_button(hsb->button_left);
	LBG_destroy_button(hsb->button_right);
	
	LBG_object_destroy_infoboxes(hsb);
	LBG_object_destroy_rightclicks(hsb);
	
	LBG_HSCROLLBAR* next = hsb->next;
	if(hsb->previous) hsb->previous->next = hsb->next;
	else LBG_HSCROLLBAR_FIRST = hsb->next;
	if(hsb->next) hsb->next->previous = hsb->previous;
	
	free(hsb);
	LBG_object_make_handles_invalid(hsb);
	return(next);
}
// </lbgui_hscrollfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_vscrollfunc.h>
void LBG_vscrollbar_bitmap (BMAP* _bmap, LBG_VSCROLLBAR_BMAPS* bmaps, var size_x, var size_y) // For internal use
{
	bmap_blit(_bmap,bmaps->bmap_top,vector(0,0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_bottom,vector(0,size_y-bmap_height(bmaps->bmap_bottom),0),NULL);
	bmap_blit(_bmap,bmaps->bmap_middle,vector(0,bmap_height(bmaps->bmap_top),0),vector(bmap_width(bmaps->bmap_middle),size_y-bmap_height(bmaps->bmap_top)-bmap_height(bmaps->bmap_bottom),0));
}



void LBG_update_window (LBG_WINDOW* win);
LBG_VSCROLLBAR* LBG_create_vscrollbar (LBG_WINDOW* _target, LBG_VSCROLLBAR_BMAPS* bmaps, LBG_BUTTON_BMAPS* btbmaps, LBG_BUTTON_BMAPS* bbbmaps, long flags)
{
	LBG_VSCROLLBAR* vsb = malloc(sizeof(LBG_VSCROLLBAR));
	vsb->ssize = sizeof(LBG_VSCROLLBAR);
	vsb->stype = 10;
	
	
	
	
	vsb->target = _target;
	vsb->layer = 0;
	vsb->flags = flags;
	
	
	
	vsb->scale_x = 1;
	vsb->scale_y = 1;
	
	vsb->panel = pan_create("",LBG_object_calc_panel_layer(vsb));
	vsb->bmaps.bmap_top = bmaps->bmap_top;
	vsb->bmaps.bmap_middle = bmaps->bmap_middle;
	vsb->bmaps.bmap_bottom = bmaps->bmap_bottom;
	vsb->bmaps.bmap_bar = bmaps->bmap_bar;
	
	
	vsb->panel->bmap = vsb->bmaps.bmap_bar;
	
	
	if(vsb->target)
	switch(vsb->target->stype)
	{
		case 1:
		vsb->ppa = 0.2;
		vsb->wheelspeed = 5;
		break;
		
		case 13:
		vsb->ppa = ((LBG_LISTBOX*)(vsb->target))->itemheight/2;
		vsb->wheelspeed = 0.5;
		break;
		
		default:
		vsb->ppa = 1;
		vsb->wheelspeed = 1;
		break;
	}
	
	
	vsb->size_x = bmap_width(vsb->bmaps.bmap_bar);
	vsb->size_y = 32;
	vsb->scrollbar = pan_create("",LBG_object_calc_panel_layer(vsb)+1);
	vsb->scrollbar->bmap = bmap_createblack(vsb->size_x,vsb->size_y,32);
	LBG_vscrollbar_bitmap(vsb->scrollbar->bmap,bmaps,vsb->size_x,vsb->size_y);
	
	vsb->corner = pan_create("",LBG_object_calc_panel_layer(vsb)+1);
	
	
	
	
	
	vsb->button_top = LBG_create_button(vsb,0,0,0,0,"",btbmaps,0,BF_SHOW | BFi_SCROLLBAR);
	vsb->button_bottom = LBG_create_button(vsb,0,0,0,0,"",bbbmaps,0,BF_SHOW | BFi_SCROLLBAR);
	
	
	
	if(vsb->flags & PBF_SHOW)
	{
		vsb->panel->flags |= SHOW;
		vsb->scrollbar->flags |= SHOW;
		vsb->button_top->flags |= BF_SHOW;
		vsb->button_bottom->flags |= BF_SHOW;
	}
	
	
	vsb->scrollamount = 0;
	vsb->scrollmax = 0;
	vsb->buttonspeed = 5;
	
	
	
	vsb->next = NULL;
	if(LBG_VSCROLLBAR_FIRST == NULL)
	{
		LBG_VSCROLLBAR_FIRST = vsb;
		vsb->previous = NULL;
	}
	else
	{
		vsb->previous = LBG_object_last(LBG_VSCROLLBAR_FIRST);
		vsb->previous->next = vsb;
	}
	
	
	LBG_object_upate_size (vsb);
	
	switch(vsb->target->stype)
	{
		case 1:
		vsb->target->flags |= WF_VSCROLLBAR;
		LBG_update_window(vsb->target);
		break;
		
		case 13:
		vsb->target->flags |= WF_VSCROLLBAR;
		break;
	}
	
	
	vsb->Destroy = 0;
	vsb->Scrolling = 0;
	vsb->Condition = 0;
	
	
	
	return (vsb);
}


void LBG_update_vscrollbar_layer (LBG_VSCROLLBAR* vsb)
{
	var x;
	x = LBG_object_calc_panel_layer(vsb);
	if(vsb->panel->layer != x) layer_sort(vsb->panel,x);
	x = LBG_object_calc_panel_layer(vsb)+1;
	if(vsb->scrollbar->layer != x) layer_sort(vsb->scrollbar,x);
	x = LBG_object_calc_panel_layer(vsb);
	if(vsb->corner->layer != x) layer_sort(vsb->corner,x);
	LBG_update_button_layer (vsb->button_top);
	LBG_update_button_layer (vsb->button_bottom);
}



var LBG_vscrollbar_get_minheight(LBG_VSCROLLBAR* vsb)
{
	return(bmap_height(vsb->bmaps.bmap_top) + bmap_height(vsb->bmaps.bmap_middle) + bmap_height(vsb->bmaps.bmap_bottom));
}
var LBG_vscrollbar_get_maxheight(LBG_VSCROLLBAR* vsb)
{
	return(vsb->size_y - vsb->button_top->size_y - vsb->button_bottom->size_y);
}


void LBG_vscrollbar_calc_barheight(LBG_VSCROLLBAR* vsb)
{
	vsb->scrollbar->size_y = integer(maxv(LBG_vscrollbar_get_minheight(vsb),LBG_vscrollbar_get_maxheight(vsb) - vsb->scrollmax*vsb->ppa)+0.5);
}


int LBG_mouse_over_vscrollbar_move(LBG_VSCROLLBAR* vsb)
{
	switch(vsb->target->stype)
	{
		case 1:
		if(vsb) return ((mouse_pos.x >= vsb->scrollbar->pos_x) && (mouse_pos.x < vsb->scrollbar->pos_x + vsb->scrollbar->size_x) && (mouse_pos.y >= vsb->scrollbar->pos_y) && (mouse_pos.y < vsb->scrollbar->pos_y + vsb->scrollbar->size_y) && (LBG_mouse_window() == vsb->target));
		else return 0;
		break;
		
		case 13:
		if(vsb) return ((mouse_pos.x >= vsb->scrollbar->pos_x) && (mouse_pos.x < vsb->scrollbar->pos_x + vsb->scrollbar->size_x) && (mouse_pos.y >= vsb->scrollbar->pos_y) && (mouse_pos.y < vsb->scrollbar->pos_y + vsb->scrollbar->size_y) && (LBG_mouse_window() == vsb->target->parent));
		else return 0;
		break;
	}
	
}

void LBG_vscrollbar_execute (LBG_VSCROLLBAR* vsb, void* func)
{
	if(func != 0)
	{
		LBG_event_object = vsb;
		LBG_event_scrollbar = vsb;
		LBG_event_vscrollbar = vsb;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_vscrollbar_condition (LBG_VSCROLLBAR* vsb, void* func)
{
	if(func != 0)
	{
		LBG_event_object = vsb;
		LBG_event_scrollbar = vsb;
		LBG_event_vscrollbar = vsb;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}

LBG_WINDOW* LBG_vscrollbar_parent_window(LBG_VSCROLLBAR* vsb)
{
	LBG_WINDOW* p = vsb->target;
	while(p)
	{
		if(p->stype == 2) break;
		p = p->parent;
	}
	return p;
}


int LBG_mouse_over_listbox_larea (LBG_LISTBOX* lst);
int LBG_vscrollbar_mouse_for_wheel (LBG_VSCROLLBAR* vsb)
{
	if(vsb->target)
	switch(vsb->target->stype)
	{
		case 1:
		if(!LBG_scrollbar_no_other(vsb)) return 0;
		return(LBG_window_mouse_over_content(vsb->target) && (LBG_mouse_window() == vsb->target)&& LBG_vscrollbar_condition(vsb,vsb->Condition));
		break;
		case 13:
		return(LBG_window_mouse_over_content(vsb->target->parent) && (LBG_mouse_window() == vsb->target->parent) && LBG_mouse_over_listbox_larea(vsb->target) && LBG_vscrollbar_condition(vsb,vsb->Condition));
		break;
		default: return 0;
	}
}


LBG_VSCROLLBAR* LBG_manage_vscrollbar (LBG_VSCROLLBAR* vsb)
{
	LBG_update_vscrollbar_layer(vsb);
	
	
	
	
	if ((!((vsb->flags & VSF_DISABLED) || (vsb->flags & VSF_AUTODISABLED))) && (vsb->target->flags & WF_VSCROLLBAR) && LBG_not_disabled_by_disableflag(vsb))
	{
		
		if (!(key_pressed(280)))
		{
			vsb->flags &= ~VSFi_CLICK0;
			vsb->flags &= ~VSFi_CLICK1;
		}
		if (LBG_mouse_over_vscrollbar_move(vsb) && (((!(vsb->flags & VSFi_CLICK0)) && (!(vsb->flags & VSFi_CLICK1))) || ((!(vsb->flags & VSFi_CLICK0)) && ((vsb->flags & VSFi_CLICK1)))))
		{
			vsb->flags |= VSFi_OVER;
			if (key_pressed(280))
			{
				if(!((!(vsb->flags & VSFi_CLICK0)) && ((vsb->flags & VSFi_CLICK1))))
				{
					vsb->mg = mouse_pos.y - vsb->scrollbar->pos_y;
				}
				
				vsb->flags &= ~VSFi_CLICK0;
				vsb->flags |= VSFi_CLICK1;
			}
		}
		else
		{
			if(!(vsb->flags & VSFi_OVER))
			{
				vsb->flags &= ~VSFi_OVER;
			}
		}
		if ((!(vsb->flags & VSFi_CLICK0)) && ((vsb->flags & VSFi_CLICK1)))
		{
			vsb->scrollbar->pos_y = mouse_pos.y - vsb->mg;
			LBG_vscrollbar_execute(vsb,vsb->Scrolling);
			
			if (LBG_vscrollbar_get_maxheight(vsb) - vsb->scrollbar->size_y) vsb->scrollamount = (vsb->scrollbar->pos_y - vsb->pos_y - vsb->button_top->size_y)*vsb->scrollmax/(LBG_vscrollbar_get_maxheight(vsb) - vsb->scrollbar->size_y);
			else vsb->scrollamount = 0;
		}
		if ((!(vsb->flags & VSFi_CLICK0)) && (!(vsb->flags & VSFi_CLICK1)) && (key_pressed(280)))
		{
			vsb->flags |= VSFi_CLICK0;
			vsb->flags &= ~VSFi_CLICK1;
		}
		
	}
	
	
	
	if(vsb->target)
	switch(vsb->target->stype)
	{
		case 1:
		vsb->pos_x = vsb->target->cpos_x + vsb->target->csize_x;
		vsb->pos_y = vsb->target->cpos_y;
		vsb->size_y = vsb->target->csize_y;
		
		vsb->panel->pos_x = vsb->pos_x;
		vsb->panel->pos_y = vsb->pos_y;
		vsb->panel->size_y = vsb->size_y;
		
		vsb->button_bottom->pos_y = vsb->size_y - vsb->button_bottom->size_y;
		
		
		vsb->scrollbar->pos_x = vsb->pos_x;
		vsb->scrollbar->pos_y = vsb->pos_y + vsb->button_top->size_y;
		
		vsb->corner->pos_x = vsb->pos_x;
		
		
		break;
		
		
		case 13:
		vsb->pos_x = LBG_object_realpos_x(vsb->target) + ((LBG_LISTBOX*)(vsb->target))->size_x - vsb->size_x;
		vsb->pos_y = LBG_object_realpos_y(vsb->target);
		vsb->size_y = ((LBG_LISTBOX*)(vsb->target))->size_y;
		
		vsb->panel->pos_x = vsb->pos_x;
		vsb->panel->pos_y = vsb->pos_y;
		vsb->panel->size_y = vsb->size_y;
		
		vsb->button_bottom->pos_y = vsb->size_y - vsb->button_bottom->size_y;
		
		
		vsb->scrollbar->pos_x = vsb->pos_x;
		vsb->scrollbar->pos_y = vsb->pos_y + vsb->button_top->size_y;
		
		vsb->corner->pos_x = vsb->pos_x;
		
		
		
		
		
		break;
	}
	
	
	LBG_vscrollbar_calc_barheight(vsb);
	if(vsb->scrollbar->size_y != bmap_height(vsb->scrollbar->bmap))
	{
		ptr_remove(vsb->scrollbar->bmap);
		vsb->scrollbar->bmap = bmap_createblack(vsb->size_x,vsb->scrollbar->size_y,32);
		LBG_vscrollbar_bitmap(vsb->scrollbar->bmap,vsb->bmaps,vsb->size_x,vsb->scrollbar->size_y);
	}
	
	if((vsb->button_top->flags & BF_CLICKED) && LBG_mouse_over_object(vsb->button_top))
	{
		vsb->scrollamount -= vsb->buttonspeed*time_step;
		LBG_vscrollbar_execute(vsb,vsb->Scrolling);
	}
	if((vsb->button_bottom->flags & BF_CLICKED) && LBG_mouse_over_object(vsb->button_bottom))
	{
		vsb->scrollamount += vsb->buttonspeed*time_step;
		LBG_vscrollbar_execute(vsb,vsb->Scrolling);
	}
	
	if(LBG_vscrollbar_mouse_for_wheel(vsb) && LBG_not_disabled_by_disableflag(vsb)) vsb->scrollamount -= vsb->wheelspeed*mickey.z/12;
	if(LBG_vscrollbar_mouse_for_wheel(vsb) && LBG_not_disabled_by_disableflag(vsb) && vsb->wheelspeed*mickey.z) LBG_hscrollbar_execute(vsb,vsb->Scrolling);
	
	vsb->scrollamount = minv(vsb->scrollamount,vsb->scrollmax);
	vsb->scrollamount = maxv(vsb->scrollamount,0);
	if(vsb->scrollmax) vsb->scrollbar->pos_y += (LBG_vscrollbar_get_maxheight(vsb)-vsb->scrollbar->size_y)*vsb->scrollamount/vsb->scrollmax;
	
	if(vsb->target)
	switch(vsb->target->stype)
	{
		case 1: vsb->target->vscrollamount = vsb->scrollamount; break;
		case 13: ((LBG_LISTBOX*)(vsb->target))->vscrollamount = vsb->scrollamount; break;
		
	}
	
	
	
	vsb->corner->flags &= ~SHOW;
	
	
	if(vsb->flags & VSF_SHOW)
	{
		vsb->panel->flags |= SHOW;
		vsb->scrollbar->flags |= SHOW;
		vsb->button_top->flags |= BF_SHOW;
		vsb->button_bottom->flags |= BF_SHOW;
	}
	else
	{
		vsb->panel->flags &= ~SHOW;
		vsb->scrollbar->flags &= ~SHOW;
		vsb->corner->flags &= ~SHOW;
		vsb->button_top->flags &= ~BF_SHOW;
		vsb->button_bottom->flags &= ~BF_SHOW;
	}
	
	if((vsb->flags & VSF_AUTODISABLED) || (!(vsb->target->flags & WF_VSCROLLBAR)))
	{
		vsb->panel->flags &= ~SHOW;
		vsb->scrollbar->flags &= ~SHOW;
		vsb->corner->flags &= ~SHOW;
		vsb->button_top->flags &= ~BF_SHOW;
		vsb->button_bottom->flags &= ~BF_SHOW;
	}
	
	if(vsb->target) if(vsb->target->stype == 13)
	{
		vsb->panel->size_x = maxv(0.1,minv(bmap_width(vsb->panel->bmap),((LBG_LISTBOX*)(vsb->target))->panel->pos_x+((LBG_LISTBOX*)(vsb->target))->panel->size_x-vsb->panel->pos_x)+0.1);
		vsb->panel->size_y = maxv(0.1,minv(vsb->size_y,((LBG_LISTBOX*)(vsb->target))->panel->pos_y+((LBG_LISTBOX*)(vsb->target))->panel->size_y-vsb->panel->pos_y)+0.1);
		
		vsb->scrollbar->size_x = vsb->panel->size_x;
		vsb->scrollbar->size_y = maxv(0.1,minv(vsb->scrollbar->size_y,((LBG_LISTBOX*)(vsb->target))->panel->pos_y+((LBG_LISTBOX*)(vsb->target))->panel->size_y-vsb->scrollbar->pos_y)+0.1);
	}
	
	return(vsb->next);
}



void LBG_vsbmaps_destroy_2frames (LBG_VSCROLLBAR_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_VSCROLLBAR_BMAPS* LBG_vsbmaps (BMAP* bmap_top, BMAP* bmap_middle, BMAP* bmap_bottom, BMAP* bmap_bar)
{
	LBG_VSCROLLBAR_BMAPS* bmaps = malloc(sizeof(LBG_VSCROLLBAR_BMAPS));
	bmaps->bmap_top = bmap_top;
	bmaps->bmap_middle = bmap_middle;
	bmaps->bmap_bottom = bmap_bottom;
	bmaps->bmap_bar = bmap_bar;
	LBG_pbmaps_destroy_2frames(bmaps);
	return(bmaps);
}



LBG_VSCROLLBAR* LBG_destroy_vscrollbar (LBG_VSCROLLBAR* vsb)
{
	LBG_vscrollbar_execute(vsb,vsb->Destroy);
	
	ptr_remove(vsb->panel);
	ptr_remove(vsb->scrollbar);
	ptr_remove(vsb->corner);
	LBG_destroy_button(vsb->button_top);
	LBG_destroy_button(vsb->button_bottom);
	
	LBG_object_destroy_infoboxes(vsb);
	LBG_object_destroy_rightclicks(vsb);
	
	LBG_VSCROLLBAR* next = vsb->next;
	if(vsb->previous) vsb->previous->next = vsb->next;
	else LBG_VSCROLLBAR_FIRST = vsb->next;
	if(vsb->next) vsb->next->previous = vsb->previous;
	
	free(vsb);
	LBG_object_make_handles_invalid(vsb);
	return(next);
}
// </lbgui_vscrollfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_sliderfunc.h>
LBG_SLIDER* LBG_create_slider (LBG_WINDOW* _parent, var pos_x, var pos_y, var width, LBG_SLIDER_BMAPS* bmaps, var minimum, var maximum, var value, long flags)
{
	LBG_SLIDER* sli = malloc(sizeof(LBG_SLIDER));
	sli->ssize = sizeof(LBG_SLIDER);
	sli->stype = 11;
	
	
	
	sli->parent = _parent;
	sli->layer = 0;
	sli->flags = flags;
	
	
	
	sli->pos_x = pos_x;
	sli->pos_y = pos_y;
	
	sli->scale_x = 1;
	sli->scale_y = 1;
	
	
	if(flags & SF_EXTERNVAR)
	{
		sli->value = *((var*)value);
		sli->v = value;
	}
	else
	{
		sli->value = value;
		sli->v = NULL;
	}
	
	sli->maximum = maximum;
	sli->minimum = minimum;
	
	sli->panel = pan_create("",LBG_object_calc_panel_layer(sli));
	sli->bmaps.bmap_left = bmaps->bmap_left;
	sli->bmaps.bmap_middle = bmaps->bmap_middle;
	sli->bmaps.bmap_right = bmaps->bmap_right;
	sli->bmaps.bmap_knob_default = bmaps->bmap_knob_default;
	sli->bmaps.bmap_knob_over = bmaps->bmap_knob_over;
	sli->bmaps.bmap_knob_clicked = bmaps->bmap_knob_clicked;
	
	
	sli->size_x = width;
	sli->size_y = bmap_height(sli->bmaps.bmap_left);
	
	
	sli->panel->bmap = bmap_createblack(sli->size_x,sli->size_y,32);
	LBG_progressbar_bitmap(sli->panel->bmap,bmaps,sli->size_x,sli->size_y);
	sli->panel->pos_x = sli->pos_x;
	sli->panel->pos_y = sli->pos_y;
	sli->panel->size_x = sli->size_x;
	sli->panel->size_y = sli->size_y;
	
	
	sli->knob = pan_create("",LBG_object_calc_panel_layer(sli)+1);
	sli->knob->bmap = sli->bmaps.bmap_knob_default;
	sli->knob->size_x = bmap_width(sli->bmaps.bmap_knob_default);
	sli->knob->size_y = bmap_height(sli->bmaps.bmap_knob_default);
	
	if(sli->flags & SF_SHOW)
	{
		sli->panel->flags |= SHOW;
		sli->knob->flags |= SHOW;
	}
	
	
	
	
	sli->next = NULL;
	if(LBG_SLIDER_FIRST == NULL)
	{
		LBG_SLIDER_FIRST = sli;
		sli->previous = NULL;
	}
	else
	{
		sli->previous = LBG_object_last(LBG_SLIDER_FIRST);
		sli->previous->next = sli;
	}
	
	
	sli->Destroy = 0;
	sli->Sliding = 0;
	
	LBG_object_upate_size (sli);
	
	
	return (sli);
}




void LBG_update_slider_layer (LBG_SLIDER* sli)
{
	var x;
	x = LBG_object_calc_panel_layer(sli);
	if(sli->panel->layer != x) layer_sort(sli->panel,x);
	x = LBG_object_calc_panel_layer(sli)+1;
	if(sli->knob->layer != x) layer_sort(sli->knob,x);
}


void LBG_slider_execute (LBG_SLIDER* sli, void* func)
{
	if(func != 0)
	{
		LBG_event_object = sli;
		LBG_event_slider = sli;
		LBG_event = func;
		LBG_event();
	}
}

LBG_SLIDER* LBG_manage_slider (LBG_SLIDER* sli)
{
	LBG_object_upate_pos(sli);
	LBG_object_upate_size(sli);
	LBG_update_slider_layer(sli);
	
	
	
	
	if(sli->flags & SF_EXTERNVAR) sli->value = *(sli->v);
	
	
	if(!(sli->flags & SF_DISABLED))
	{
		
		if (!(key_pressed(280)))
		{
			sli->flags &= ~SFi_CLICK0;
			sli->flags &= ~SFi_CLICK1;
		}
		if (LBG_not_disabled_by_disableflag(sli) && LBG_mouse_over_object(sli) && (sli->parent == LBG_mouse_window()) && LBG_window_mouse_over_content(sli->parent) && (((!(sli->flags & SFi_CLICK0)) && (!(sli->flags & SFi_CLICK1))) || ((!(sli->flags & SFi_CLICK0)) && ((sli->flags & SFi_CLICK1)))))
		{
			sli->flags |= SFi_OVER;
			sli->knob->bmap = sli->bmaps.bmap_knob_over;
			if (key_pressed(280))
			{
				if(!((!(sli->flags & SFi_CLICK0)) && ((sli->flags & SFi_CLICK1))))
				{
					if(mouse_pos.x < sli->knob->pos_x) sli->knob->pos_x = mouse_pos.x;
					if(mouse_pos.x > sli->knob->pos_x + sli->knob->size_x) sli->knob->pos_x = mouse_pos.x - sli->knob->size_x + 1;
					sli->mg = mouse_pos.x - sli->knob->pos_x;
				}
				
				sli->flags &= ~SFi_CLICK0;
				sli->flags |= SFi_CLICK1;
				sli->knob->bmap = sli->bmaps.bmap_knob_clicked;
			}
		}
		else
		{
			sli->knob->bmap = sli->bmaps.bmap_knob_default;
			if(!(sli->flags & SFi_OVER))
			{
				sli->flags &= ~SFi_OVER;
			}
		}
		if ((!(sli->flags & SFi_CLICK0)) && ((sli->flags & SFi_CLICK1)))
		{
			sli->knob->pos_x = mouse_pos.x - sli->mg;
			LBG_slider_execute(sli,sli->Sliding);
			
			if (sli->size_x - sli->knob->size_x) sli->value = (sli->knob->pos_x-sli->panel->pos_x)*(sli->maximum-sli->minimum)/(sli->size_x-sli->knob->size_x) + sli->minimum;
			else sli->value = 0;
		}
		if ((!(sli->flags & SFi_CLICK0)) && (!(sli->flags & SFi_CLICK1)) && (key_pressed(280)))
		{
			sli->flags |= SFi_CLICK0;
			sli->flags &= ~SFi_CLICK1;
		}
		
	}
	
	
	
	
	
	
	
	sli->value = maxv(sli->value,sli->minimum);
	sli->value = minv(sli->value,sli->maximum);
	sli->knob->pos_x = sli->panel->pos_x + (sli->size_x - sli->knob->size_x)*(sli->value-sli->minimum)/(sli->maximum-sli->minimum)+0.5;
	sli->knob->pos_y = sli->panel->pos_y;
	
	if(sli->flags & SF_EXTERNVAR) *(sli->v) = sli->value;
	
	
	
	
	if(sli->flags & SF_SHOW)
	{
		sli->panel->flags |= SHOW;
		sli->knob->flags |= SHOW;
	}
	else
	{
		sli->panel->flags &= ~SHOW;
		sli->knob->flags &= ~SHOW;
	}
	
	
	
	return sli->next;
}


LBG_SLIDER* LBG_update_slider (LBG_SLIDER* sli)
{
	LBG_object_upate_pos(sli);
	LBG_object_upate_size(sli);
	LBG_update_slider_layer(sli);
	ptr_remove(sli->panel->bmap);
	sli->panel->bmap = bmap_createblack(sli->size_x,sli->size_y,32);
	LBG_progressbar_bitmap(sli->panel->bmap,sli->bmaps,sli->size_x,sli->size_y);
}



LBG_SLIDER* LBG_destroy_slider (LBG_SLIDER* sli)
{
	LBG_slider_execute(sli,sli->Destroy);
	
	ptr_remove(sli->panel);
	ptr_remove(sli->knob);
	
	LBG_object_destroy_infoboxes(sli);
	LBG_object_destroy_rightclicks(sli);
	
	LBG_SLIDER* next = sli->next;
	if(sli->previous) sli->previous->next = sli->next;
	else LBG_SLIDER_FIRST = sli->next;
	if(sli->next) sli->next->previous = sli->previous;
	
	free(sli);
	LBG_object_make_handles_invalid(sli);
	return(next);
}



void LBG_sbmaps_destroy_2frames (LBG_SLIDER_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_SLIDER_BMAPS* LBG_sbmaps (BMAP* bmap_left, BMAP* bmap_middle, BMAP* bmap_right, BMAP* bmap_knob_default, BMAP* bmap_knob_over, BMAP* bmap_knob_clicked)
{
	LBG_SLIDER_BMAPS* bmaps = malloc(sizeof(LBG_SLIDER_BMAPS));
	bmaps->bmap_left = bmap_left;
	bmaps->bmap_middle = bmap_middle;
	bmaps->bmap_right = bmap_right;
	bmaps->bmap_knob_default = bmap_knob_default;
	bmaps->bmap_knob_over = bmap_knob_over;
	bmaps->bmap_knob_clicked = bmap_knob_clicked;
	LBG_sbmaps_destroy_2frames(bmaps);
	return(bmaps);
}
// </lbgui_sliderfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_listfunc.h>
void LBG_listbox_update_bmap (LBG_LISTBOX* lst, BMAP* bmap, LBG_LISTITEM_BMAPS* bmaps, int nr)
{
	BMAP* b;
	if(bmaps.bmap_left)
	{
		if((bmap != NULL) && (bmap != LBG_empty_bmap))
		{
			ptr_remove(bmap);
		}
		b = bmap_createblack(lst->lsize_x,lst->itemheight,32);
		switch(nr)
		{
			case 1: lst->bmap_default = b; break;
			case 2: lst->bmap_over = b; break;
			case 3: lst->bmap_marked = b; break;
		}
		
		LBG_progressbar_bitmap(b,bmaps,lst->lsize_x,lst->itemheight);
	}
	else
	{
		switch(nr)
		{
			case 1: lst->bmap_default = LBG_empty_bmap; break;
			case 2: lst->bmap_over = LBG_empty_bmap; break;
			case 3: lst->bmap_marked = LBG_empty_bmap; break;
		}
	}
}

void LBG_listbox_update_bmaps (LBG_LISTBOX* lst)
{
	LBG_listbox_update_bmap (lst,lst->bmap_default,lst->bmaps_default,1);
	LBG_listbox_update_bmap (lst,lst->bmap_over,lst->bmaps_over,2);
	LBG_listbox_update_bmap (lst,lst->bmap_marked,lst->bmaps_marked,3);
}

LBG_LISTBOX* LBG_create_listbox (LBG_WINDOW* _parent, var pos_x, var pos_y, var size_x, var size_y, var ipos_x, var ipos_y, var isize_x, var isize_y, LBG_LISTBOX_BMAPS* bmaps, long flags)
{
	LBG_LISTBOX* lst = malloc(sizeof(LBG_LISTBOX));
	lst->ssize = sizeof(LBG_LISTBOX);
	lst->stype = 13;
	
	
	
	lst->parent = _parent;
	lst->layer = 0;
	lst->flags = flags;
	
	
	
	lst->pos_x = pos_x;
	lst->pos_y = pos_y;
	
	lst->scale_x = 1;
	lst->scale_y = 1;
	
	
	lst->ipos_x = ipos_x;
	lst->ipos_y = ipos_y;
	lst->isize_x = isize_x;
	lst->isize_y = isize_y;
	
	lst->lpos_x = lst->pos_x + lst->ipos_x;
	lst->lpos_y = lst->pos_y + lst->ipos_y;
	lst->lsize_x = lst->isize_x;
	lst->lsize_y = lst->isize_y;
	
	
	
	lst->panel = pan_create("",LBG_object_calc_panel_layer(lst));
	lst->bmaps.bmap_topleft = bmaps->bmap_topleft;
	lst->bmaps.bmap_top = bmaps->bmap_top;
	lst->bmaps.bmap_topright = bmaps->bmap_topright;
	lst->bmaps.bmap_left = bmaps->bmap_left;
	lst->bmaps.bmap_right = bmaps->bmap_right;
	lst->bmaps.bmap_bottomleft = bmaps->bmap_bottomleft;
	lst->bmaps.bmap_bottom = bmaps->bmap_bottom;
	lst->bmaps.bmap_bottomright = bmaps->bmap_bottomright;
	lst->bmaps.bmap_center = bmaps->bmap_center;
	
	
	lst->size_x = size_x;
	lst->size_y = size_y;
	
	
	lst->panel->bmap = bmap_createblack(lst->size_x,lst->size_y,32);
	LBG_window_content_bitmap(lst->panel->bmap,bmaps,lst->size_x,lst->size_y);
	lst->panel->pos_x = lst->pos_x;
	lst->panel->pos_y = lst->pos_y;
	lst->panel->size_x = lst->size_x;
	lst->panel->size_y = lst->size_y;
	
	
	if(lst->flags & LF_SHOW)
	{
		lst->panel->flags |= SHOW;
	}
	
	
	memset(&(lst->bmaps_default),0,sizeof(LBG_LISTITEM_BMAPS));
	memset(&(lst->bmaps_over),0,sizeof(LBG_LISTITEM_BMAPS));
	memset(&(lst->bmaps_marked),0,sizeof(LBG_LISTITEM_BMAPS));
	lst->bmaps_default.bmap_left = NULL;
	lst->bmaps_over.bmap_left = NULL;
	lst->bmaps_marked.bmap_left = NULL;
	
	lst->bmap_default = LBG_empty_bmap;
	lst->bmap_over = LBG_empty_bmap;
	lst->bmap_marked = LBG_empty_bmap;
	
	lst->item_first = NULL;
	
	
	lst->font = 0;
	
	lst->tpos_x = 0;
	lst->tpos_y = 0;
	
	if(LBG_listitem_font) lst->itemheight = LBG_listitem_font.dy;
	else lst->itemheight = 32;
	
	lst->color_default.red = 255;
	lst->color_default.green = 255;
	lst->color_default.blue = 255;
	lst->color_over.red = 255;
	lst->color_over.green = 255;
	lst->color_over.blue = 255;
	lst->color_marked.red = 255;
	lst->color_marked.green = 255;
	lst->color_marked.blue = 255;
	
	
	
	lst->vscrollamount = 0;
	lst->marked_item = NULL;
	
	lst->next = NULL;
	if(LBG_LISTBOX_FIRST == NULL)
	{
		LBG_LISTBOX_FIRST = lst;
		lst->previous = NULL;
	}
	else
	{
		lst->previous = LBG_object_last(LBG_LISTBOX_FIRST);
		lst->previous->next = lst;
	}
	
	
	LBG_object_upate_size (lst);
	
	LBG_listbox_update_bmaps(lst);
	
	lst->Destroy = 0;
	lst->Select = 0;
	
	return (lst);
}





LBG_LISTITEM* LBG_create_listitem (LBG_LISTBOX* _parent, var position, STRING* caption, long flags)
{
	LBG_LISTITEM* itm = malloc(sizeof(LBG_LISTITEM));
	itm->ssize = sizeof(LBG_LISTITEM);
	itm->stype = 14;
	
	itm.skill_x = position;
	
	if(flags & LIF_EXTERNSTRING)
	{
		itm->caption = caption;
	}
	else
	{
		itm->caption = str_create("");
		str_cpy(itm->caption,caption);
	}
	
	itm->parent = _parent;
	itm->layer = 0;
	itm->flags = flags;
	
	
	
	itm->text = txt_create(1,LBG_object_calc_text_layer(itm));
	ptr_remove((itm->text->pstring)[0]);
	(itm->text->pstring)[0] = itm->caption;
	
	if(((LBG_LISTBOX*)(itm->parent))->font != NULL) itm->text->font = ((LBG_LISTBOX*)(itm->parent))->font;
	else itm->text->font = LBG_listitem_font;
	
	vec_set(itm->text->blue,((LBG_LISTBOX*)(itm->parent))->color_default);
	
	
	
	
	itm->scale_x = 1;
	itm->scale_y = 1;
	
	
	
	
	itm->panel = pan_create("",LBG_object_calc_panel_layer(itm));
	
	
	
	itm->size_x = ((LBG_LISTBOX*)(itm->parent))->lsize_x;
	itm->size_y = ((LBG_LISTBOX*)(itm->parent))->lsize_y;
	
	
	
	
	itm->panel->bmap = LBG_empty_bmap;
	
	
	itm->panel->pos_x = itm->pos_x;
	itm->panel->pos_y = itm->pos_y;
	itm->panel->size_x = itm->size_x;
	itm->panel->size_y = itm->size_y;
	
	
	if(itm->flags & LIF_SHOW)
	{
		itm->panel->flags |= SHOW;
		itm->text->flags |= SHOW;
	}
	
	
	
	
	
	itm->next = NULL;
	if(((LBG_LISTBOX*)(itm->parent))->item_first == NULL)
	{
		((LBG_LISTBOX*)(itm->parent))->item_first = itm;
		itm->previous = NULL;
	}
	else
	{
		if(position >= LBG_object_num(((LBG_LISTBOX*)(itm->parent))->item_first))
		{
			itm->previous = LBG_object_last(((LBG_LISTBOX*)(itm->parent))->item_first);
			itm->previous->next = itm;
		}
		else
		{
			itm->next = LBG_object_nr(((LBG_LISTBOX*)(itm->parent))->item_first,position);
			if(itm->next == ((LBG_LISTBOX*)(itm->parent))->item_first) ((LBG_LISTBOX*)(itm->parent))->item_first = itm;
			itm->previous = itm->next->previous;
			if(itm->previous) itm->previous->next = itm;
			itm->next->previous = itm;
		}
	}
	
	
	LBG_object_upate_size (itm);
	
	itm->Destroy = 0;
	itm->Select = 0;
	itm->Unselect = 0;
	
	
	return (itm);
}









void LBG_update_listitem_layer (LBG_LISTITEM* itm)
{
	var x;
	x = itm->parent->panel->layer+1;
	if(itm->panel->layer != x) layer_sort(itm->panel,x);
	x = itm->parent->panel->layer+2;
	if(itm->text->layer != x) layer_sort(itm->text,x);
}

void LBG_listbox_unmark_all_listitems (LBG_LISTBOX* lst)
{
	LBG_LISTITEM* itm = lst->item_first;
	while(itm)
	{
		itm->flags &= ~LIF_MARKED;
	}
}


void LBG_listbox_execute (LBG_LISTBOX* lst, void* func)
{
	if(func != 0)
	{
		LBG_event_object = lst;
		LBG_event_listbox = lst;
		LBG_event = func;
		LBG_event();
	}
}
void LBG_listitem_execute (LBG_LISTITEM* itm, void* func)
{
	if(func != 0)
	{
		LBG_event_object = itm;
		LBG_event_listbox = itm->parent;
		LBG_event_listitem = itm;
		LBG_event = func;
		LBG_event();
	}
}


var LBG_listbox_num_marked (LBG_LISTBOX* lst)
{
	if(!lst) return (0);
	LBG_LISTITEM* itm = lst->item_first;
	var i = 0;
	while(itm)
	{
		if(itm->flags & LIF_MARKED) i++;
		itm = itm->next;
	}
	return(i);
}

var LBG_listbox_set_marked (LBG_LISTBOX* lst,var num)
{
	if(!lst) return (0);
	LBG_LISTITEM* itm = lst->item_first;
	
	var i = 0;
	while(itm)
	{
		if(itm->skill_x == num)
		{
			itm->flags |= LIF_MARKED;
			lst.marked_item = itm;	
			i++;
			itm = itm->next;
			
		}
		else
		{
			itm->flags &= ~LIF_MARKED;
			
			itm = itm->next;
		}
		 
	}
	return(itm);
}




LBG_EDITBOX* LBG_update_editbox (LBG_EDITBOX* ebx);
void LBG_mark_listitem (LBG_LISTITEM* itm)
{
	int x;
	itm->flags |= LIF_EVENT;
	
	if((itm->flags & LIF_MARKED) && (itm->parent->flags & LF_UNSELECT) && (key_ctrl || key_shift || (LBG_listbox_num_marked(itm->parent) <= 1)))
	{
		itm->flags &= ~LIF_MARKED;
		if(((LBG_LISTBOX*)(itm->parent))->marked_item == itm) ((LBG_LISTBOX*)(itm->parent))->marked_item = NULL;
		LBG_listitem_execute(itm,itm->Unselect);
	}
	else
	{
		
		itm->flags |= LIF_MARKED;
		((LBG_LISTBOX*)(itm->parent))->marked_item = itm;
		if((itm->parent->flags & LFi_RIGHTCLICK) || (itm->parent->flags & LFi_COMBOBOX))
		{
			itm->parent->flags &= ~LF_SHOW;
			itm->parent->flags |= LF_DISABLED;
			if(itm->parent->flags & LFi_RIGHTCLICK)
			{
				itm->parent->parent->flags |= RFi_CLICK0;
				itm->parent->parent->flags &= ~RFi_CLICK1;
				itm->parent->parent->flags &= ~RF_CLICKED;
				itm->parent->parent->flags &= ~RF_ACTIVE;
			}
			if(itm->parent->flags & LFi_COMBOBOX)
			{
				str_cpy(((LBG_COMBOBOX*)(itm->parent->parent))->caption,itm->caption);
				LBG_update_editbox(((LBG_COMBOBOX*)(itm->parent->parent))->editbox);
				((LBG_COMBOBOX*)(itm->parent->parent))->chosen_option = itm;
			}
		}
	}
	
	LBG_listitem_execute(itm,itm->Select);
	LBG_listbox_execute(itm->parent,((LBG_LISTBOX*)(itm->parent))->Select);
	LBG_LISTITEM* itm1 = ((LBG_LISTBOX*)(itm->parent))->item_first;
	if (!((itm->parent->flags & LF_MULTIPLE) && (key_ctrl || key_shift)))
	while(itm1)
	{
		if ((itm1 != itm) || (itm->parent->flags & LFi_RIGHTCLICK) || (itm->parent->flags & LFi_COMBOBOX))
		{
			x = itm1->flags & LIF_MARKED;
			itm1->flags &= ~LIF_MARKED;
			if(x) LBG_listitem_execute(itm1,itm1->Unselect);
		}
		itm1 = itm1->next;
	}
}

void LBG_listitem_event (LBG_LISTITEM* itm)
{
	
	itm->flags &= ~LIF_EVENT;
	if(!key_pressed(280)) return;
	LBG_HANDLE* h = LBG_get_eventhandle(itm);
	wait(1);
	if(!h->valid)
	{
		LBG_destroy_handle(h);
		return;
	}
	if(!key_pressed(280))
	{
		
		
		LBG_mark_listitem(itm);
		
		
		wait(1);
		if(!h->valid)
		{
			LBG_destroy_handle(h);
			return;
		}
		itm->flags &= ~LIF_EVENT;
	}
}

int LBG_mouse_over_listbox_larea (LBG_LISTBOX* lst)
{
	return ((mouse_pos.x >= lst->lpos_x) && (mouse_pos.x < lst->lpos_x + lst->lsize_x) && (mouse_pos.y >= lst->lpos_y) && (mouse_pos.y < lst->lpos_y + lst->lsize_y) && (mouse_pos.x < lst->panel->pos_x + lst->size_x - lst->vscroll_width));
}

LBG_LISTITEM* LBG_manage_listitem (LBG_LISTITEM* itm)
{
	itm->size_y = ((LBG_LISTBOX*)(itm->parent))->itemheight;
	
	LBG_object_upate_pos(itm);
	LBG_object_upate_size(itm);
	LBG_update_listitem_layer(itm);
	
	if(itm->flags & LIF_MARKED) vec_set(itm->text->blue,((LBG_LISTBOX*)(itm->parent))->color_marked);
	else vec_set(itm->text->blue,((LBG_LISTBOX*)(itm->parent))->color_default);
	
	if (!(itm->parent->flags & LF_DISABLED))
	{
		if (!(key_pressed(280)))
		{
			itm->flags &= ~LIFi_CLICK0;
			itm->flags &= ~LIFi_CLICK1;
			itm->flags &= ~LIF_CLICKED;
		}
		
		if (LBG_not_disabled_by_disableflag(itm) && LBG_mouse_over_object(itm) && LBG_mouse_over_object(itm->parent) && LBG_mouse_over_listbox_larea(itm->parent) && ((itm->parent == LBG_mouse_window()) || (itm->parent->parent == LBG_mouse_window())) && (LBG_window_mouse_over_content (itm->parent->parent) || (itm->parent->flags & LFi_RIGHTCLICK) || (itm->parent->flags & LFi_COMBOBOX)) && (((!(itm->flags & LIFi_CLICK0)) && (!(itm->flags & LIFi_CLICK1))) || ((!(itm->flags & LIFi_CLICK0)) && ((itm->flags & LIFi_CLICK1)))))
		{
			itm->flags |= LIFi_OVER;
			
			if(itm->flags & LIF_MARKED) itm->panel.bmap = ((LBG_LISTBOX*)(itm->parent))->bmap_marked;
			else itm->panel.bmap = ((LBG_LISTBOX*)(itm->parent))->bmap_over;
			vec_set(itm->text->blue,((LBG_LISTBOX*)(itm->parent))->color_over);
			if (key_pressed(280))
			{
				itm->flags &= ~LIFi_CLICK0;
				itm->flags |= LIFi_CLICK1;
				itm->flags |= LIF_CLICKED;
				itm->panel.bmap = ((LBG_LISTBOX*)(itm->parent))->bmap_marked;
				vec_set(itm->text->blue,((LBG_LISTBOX*)(itm->parent))->color_marked);
				LBG_listitem_event(itm);
			}
		}
		else
		{
			
			if(itm->flags & LIF_MARKED) itm->panel.bmap = ((LBG_LISTBOX*)(itm->parent))->bmap_marked;
			else itm->panel.bmap = ((LBG_LISTBOX*)(itm->parent))->bmap_default;
			if(!(itm->flags & LIFi_OVER))
			{
				itm->flags &= ~LIFi_OVER;
				itm->flags &= ~LIF_CLICKED;
			}
			itm->flags &= ~LIF_EVENT;
		}
		if ((!(itm->flags & LIFi_CLICK0)) && (!(itm->flags & LIFi_CLICK1)) && (key_pressed(280)))
		{
			itm->flags |= LIFi_CLICK0;
			itm->flags &= ~LIFi_CLICK1;
			itm->flags &= ~LIF_CLICKED;
		}
		
	}
	else
	{
		itm->flags |= LIFi_CLICK0;
		itm->flags &= ~LIFi_CLICK1;
		itm->flags &= ~LIFi_OVER;
		itm->flags &= ~LIF_CLICKED;
	}
	
	
	if(itm->parent->flags & LF_SHOW)
	{
		itm->panel->flags |= SHOW;
		itm->text->flags |= SHOW;
	}
	else
	{
		itm->panel->flags &= ~SHOW;
		itm->text->flags &= ~SHOW;
	}
	
	
	return itm->next;
}

void LBG_update_listbox_layer (LBG_LISTBOX* lst)
{
	if(lst->parent)
	if((lst->parent->stype == 15) || (lst->parent->stype == 16))
	{
		var x;
		x = LBG_highest_layer-5;
		if(lst->panel->layer != x) layer_sort(lst->panel,x);
		return;
	}
	
	var x;
	x = LBG_object_calc_panel_layer(lst);
	if(lst->panel->layer != x) layer_sort(lst->panel,x);
}

void LBG_listbox_calc_vscroll_width (LBG_LISTBOX* lst)
{
	lst->vscroll_width = 0;
	if(!(lst->flags & LF_VSCROLLBAR)) return;
	
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == lst){lst->vscroll_width = vsb->size_x;return;}vsb = vsb->next;
	}
}


void LBG_listbox_update_ilpossize (LBG_LISTBOX* lst)
{
	LBG_listbox_calc_vscroll_width(lst);
	lst->lpos_x = lst->panel->pos_x + lst->ipos_x;
	lst->lpos_y = lst->panel->pos_y + lst->ipos_y;
	lst->lsize_x = lst->isize_x;
	lst->lsize_y = lst->isize_y;
}

var LBG_listbox_get_number_of_items(LBG_LISTBOX* lst)
{
	var ret = 0;
	LBG_LISTITEM* itm = lst->item_first;
	while(itm)
	{
		itm = itm->next;
		ret++;
	}
	return(ret);
}

LBG_LISTBOX* LBG_manage_listbox (LBG_LISTBOX* lst)
{
	LBG_object_upate_pos(lst);
	LBG_object_upate_size(lst);
	LBG_update_listbox_layer(lst);
	
	LBG_listbox_update_ilpossize(lst);
	
	
	
	var y = lst->lpos_y - integer(lst->vscrollamount+0.5)*lst->itemheight;
	LBG_LISTITEM* itm = lst->item_first;
	while(itm)
	{
		itm->pos_x = lst->lpos_x;
		itm->pos_y = y;
		itm = LBG_manage_listitem(itm);
		y += lst->itemheight;
	}
	if(lst->flags & LF_AUTOVSCROLL)
	{
		if(LBG_listbox_get_number_of_items(lst)*lst->itemheight > lst->lsize_y) lst->flags |= LF_VSCROLLBAR;
		else lst->flags &= ~LF_VSCROLLBAR;
	}
	
	if(lst->flags & LF_SHOW)
	{
		lst->panel->flags |= SHOW;
	}
	else
	{
		lst->panel->flags &= ~SHOW;
	}
	
	
	return lst->next;
}




var LBG_listbox_get_vscrollmax (LBG_LISTBOX* lst)
{
	return(LBG_listbox_get_number_of_items(lst)-integer(lst->lsize_y/lst->itemheight));
}

void LBG_update_listbox (LBG_LISTBOX* lst)
{
	LBG_object_upate_pos(lst);
	LBG_object_upate_size(lst);
	LBG_update_listbox_layer(lst);
	LBG_listbox_update_ilpossize(lst);
	LBG_listbox_update_bmaps(lst);
	
	
	
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == lst) vsb->scrollmax = LBG_listbox_get_vscrollmax(lst);
		vsb = vsb->next;
	}
	
	
	ptr_remove(lst->panel->bmap);
	lst->panel->bmap = bmap_createblack(lst->size_x,lst->size_y,32);
	LBG_window_content_bitmap(lst->panel->bmap,lst->bmaps,lst->size_x,lst->size_y);
	lst->panel->size_x = lst->size_x;
	lst->panel->size_y = lst->size_y;
}


LBG_LISTITEM* LBG_destroy_listitem (LBG_LISTITEM* itm)
{
	LBG_listitem_execute(itm,itm->Destroy);
	
	if(itm->parent->flags & LFi_COMBOBOX)
	{
		if(((LBG_COMBOBOX*)(itm->parent->parent))->chosen_option == itm) ((LBG_COMBOBOX*)(itm->parent->parent))->chosen_option = NULL;
	}
	if(((LBG_LISTBOX*)(itm->parent))->marked_item == itm) ((LBG_LISTBOX*)(itm->parent))->marked_item = NULL;
	
	if(!(itm->flags & LIF_EXTERNSTRING)) ptr_remove(itm->caption);
	ptr_remove(itm->text);
	ptr_remove(itm->panel);
	
	LBG_object_destroy_infoboxes(itm);
	LBG_object_destroy_rightclicks(itm);
	
	
	LBG_LISTITEM* next = itm->next;
	if(itm->previous) itm->previous->next = itm->next;
	else ((LBG_LISTBOX*)(itm->parent))->item_first = itm->next;
	if(itm->next) itm->next->previous = itm->previous;
	
	free(itm);
	LBG_object_make_handles_invalid(itm);
	return(next);
}





LBG_LISTBOX* LBG_destroy_listbox (LBG_LISTBOX* lst)
{
	LBG_listbox_execute(lst,lst->Destroy);
	ptr_remove(lst->panel);
	
	LBG_LISTITEM* itm = lst->item_first;
	while(itm)
	{
		itm = LBG_destroy_listitem(itm);
	}
	
	
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == lst)
		{
			vsb = LBG_destroy_vscrollbar (vsb);
		}
		else vsb = vsb->next;
	}
	
	LBG_object_destroy_infoboxes(lst);
	LBG_object_destroy_rightclicks(lst);
	
	
	LBG_LISTBOX* next = lst->next;
	if(lst->previous) lst->previous->next = lst->next;
	else LBG_LISTBOX_FIRST = lst->next;
	if(lst->next) lst->next->previous = lst->previous;
	
	free(lst);
	LBG_object_make_handles_invalid(lst);
	return(next);
}




void LBG_listbox_calc_size_y (LBG_LISTBOX* lst) // if it's part of a rightclick menu or a combobox
{
	lst->size_y = lst->ipos_y*2;
	LBG_LISTITEM* itm = lst->item_first;
	while(itm)
	{
		lst->size_y += lst->itemheight;
		itm = itm->next;
	}
}





void LBG_lbmaps_destroy_2frames (LBG_LISTBOX_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_LISTBOX_BMAPS* LBG_lbmaps (BMAP* bmap_topleft, BMAP* bmap_top, BMAP* bmap_topright, BMAP* bmap_left,
BMAP* bmap_right, BMAP* bmap_bottomleft, BMAP* bmap_bottom, BMAP* bmap_bottomright, BMAP* bmap_center)
{
	LBG_LISTBOX_BMAPS* bmaps = malloc(sizeof(LBG_LISTBOX_BMAPS));
	bmaps->bmap_topleft = bmap_topleft;
	bmaps->bmap_top = bmap_top;
	bmaps->bmap_topright = bmap_topright;
	bmaps->bmap_left = bmap_left;
	bmaps->bmap_right = bmap_right;
	bmaps->bmap_bottomleft = bmap_bottomleft;
	bmaps->bmap_bottom = bmap_bottom;
	bmaps->bmap_bottomright = bmap_bottomright;
	bmaps->bmap_center = bmap_center;
	LBG_lbmaps_destroy_2frames(bmaps);
	return(bmaps);
}





// </lbgui_listfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_rightclickfunc.h>
LBG_RIGHTCLICK* LBG_create_rightclick (LBG_WINDOW* _target, var size_x, var ipos_x, var ipos_y, var isize_x, LBG_LISTBOX_BMAPS* bmaps, long flags)
{
	LBG_RIGHTCLICK* rcl = malloc(sizeof(LBG_RIGHTCLICK));
	rcl->ssize = sizeof(LBG_RIGHTCLICK);
	rcl->stype = 15;
	
	
	
	rcl->target = _target;
	rcl->layer = 0;
	rcl->flags = flags;
	
	
	rcl->pos_x = 0;
	rcl->pos_y = 0;
	
	
	
	rcl->scale_x = 1;
	rcl->scale_y = 1;
	
	
	
	rcl->menu = LBG_create_listbox (rcl,0,0,size_x,ipos_y,ipos_x,ipos_y,isize_x,ipos_y,bmaps,0);
	rcl->menu->flags |= LFi_RIGHTCLICK;
	
	
	rcl->next = NULL;
	if(LBG_RIGHTCLICK_FIRST == NULL)
	{
		LBG_RIGHTCLICK_FIRST = rcl;
		rcl->previous = NULL;
	}
	else
	{
		rcl->previous = LBG_object_last(LBG_RIGHTCLICK_FIRST);
		rcl->previous->next = rcl;
	}
	
	rcl->Open = 0;
	rcl->Destroy = 0;
	rcl->Condition = 0;
	
	
	
	return (rcl);
}



void LBG_menu_correct_position (LBG_LISTBOX* mnu)
{
	if(mnu->pos_x < LBG_screenpos_x) mnu->pos_x = 0;
	else if(mnu->pos_x > LBG_screenpos_x + LBG_screensize_x - mnu->size_x) mnu->pos_x = LBG_screenpos_x + LBG_screensize_x - mnu->size_x;
	if(mnu->pos_y < LBG_screenpos_y) mnu->pos_y = 0;
	else if(mnu->pos_y > LBG_screenpos_y + LBG_screensize_y - mnu->size_y) mnu->pos_y = LBG_screenpos_y + LBG_screensize_y - mnu->size_y;
}




void LBG_rightclick_execute (LBG_RIGHTCLICK* rcl, void* func)
{
	if(func != 0)
	{
		LBG_event_object = rcl;
		LBG_event_rightclick = rcl;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_rightclick_condition (LBG_RIGHTCLICK* rcl, void* func)
{
	if(func != 0)
	{
		LBG_event_object = rcl;
		LBG_event_rightclick = rcl;
		LBG_condition = func;
		return LBG_condition();
	}
	return 1;
}

void LBG_rightclick_event (LBG_RIGHTCLICK* rcl)
{
	rcl.flags &= ~RF_EVENT;
	if(!key_pressed(281)) return;
	wait(1);
	if(!key_pressed(281))
	{
		LBG_rightclick_execute(rcl,rcl->Open);
		rcl->flags |= RF_EVENT;
		if(rcl->flags & RF_SHOW) rcl->menu->flags |= LF_SHOW;
		rcl->menu->flags &= ~LF_DISABLED;
		rcl->menu->pos_x = mouse_pos.x;
		rcl->menu->pos_y = mouse_pos.y;
		LBG_listbox_calc_size_y(rcl->menu);
		LBG_menu_correct_position(rcl->menu);
		LBG_update_listbox(rcl->menu);
		wait(1);
		rcl->flags &= ~RF_EVENT;
	}
}




int LBG_rightclick_over_condition (LBG_RIGHTCLICK* rcl)
{
	if (rcl->target) return  (LBG_mouse_over_object(rcl->target) && (rcl->target->parent == LBG_mouse_window()) && LBG_window_mouse_over_content (rcl->target->parent) && ((rcl->target->stype != 2) || ((rcl->target->flags & BFi_OVER))));
	return (!LBG_mouse_window());
}

LBG_RIGHTCLICK* LBG_manage_rightclick (LBG_RIGHTCLICK* rcl)
{
	
	if((rcl->menu->flags & LF_SHOW) && (!(LBG_mouse_over_object(rcl->menu))) && ((key_pressed(280)) || (key_pressed(281))) && (!(rcl->flags & RF_EVENT)))
	{
		rcl->menu->flags &= ~LF_SHOW;
		rcl->menu->flags |= LF_DISABLED;
	}
	
	
	if (!(rcl->flags & RF_DISABLED))
	{
		if (!(key_pressed(280)))
		{
			rcl->flags &= ~RFi_CLICK0;
			rcl->flags &= ~RFi_CLICK1;
			rcl->flags &= ~RF_CLICKED;
		}
		
		if(LBG_rightclick_condition(rcl,rcl->Condition) && LBG_rightclick_over_condition(rcl))
		{
			rcl->flags |= RFi_OVER;
			if (key_pressed(281))
			{
				rcl->flags &= ~RFi_CLICK0;
				rcl->flags |= RFi_CLICK1;
				rcl->flags |= RF_CLICKED;
				
				LBG_rightclick_event(rcl);
				
				rcl->flags |= RF_ACTIVE;
				
			}
		}
		else
		{
			rcl.flags &= ~RF_EVENT;
			
			rcl->flags &= ~RFi_OVER;
			rcl->flags &= ~RF_CLICKED;
		}
		if ((!(rcl->flags & RFi_CLICK0)) && (!(rcl->flags & RFi_CLICK1)) && ((key_pressed(280)) || (key_pressed(281))))
		{
			rcl->flags |= RFi_CLICK0;
			rcl->flags &= ~RFi_CLICK1;
			rcl->flags &= ~RF_CLICKED;
			
			rcl->flags &= ~RF_ACTIVE;
			
		}
		
	}
	else
	{
		rcl->flags |= RFi_CLICK0;
		rcl->flags &= ~RFi_CLICK1;
		rcl->flags &= ~RFi_OVER;
		rcl->flags &= ~RF_CLICKED;
	}
	
	
	
	return rcl->next;
}


void LBG_update_rightclick (LBG_RIGHTCLICK* rcl)
{
	rcl->menu->isize_y = LBG_object_num(rcl->menu->item_first)*rcl->menu->itemheight;
	LBG_update_listbox(rcl->menu);
}

LBG_LISTITEM* LBG_rightclick_add_option (LBG_RIGHTCLICK* rcl, var position, STRING* caption, long flags, void* Event)
{
	LBG_LISTITEM* itm = LBG_create_listitem (rcl->menu,position,caption,flags);
	itm->Select = Event;
	return(itm);
}

LBG_RIGHTCLICK* LBG_destroy_rightclick (LBG_RIGHTCLICK* rcl)
{
	LBG_rightclick_execute(rcl,rcl->Destroy);
	
	LBG_destroy_listbox(rcl->menu);
	
	LBG_object_destroy_infoboxes(rcl);
	LBG_object_destroy_rightclicks(rcl);
	
	LBG_RIGHTCLICK* next = rcl->next;
	if(rcl->previous) rcl->previous->next = rcl->next;
	else LBG_RIGHTCLICK_FIRST = rcl->next;
	if(rcl->next) rcl->next->previous = rcl->previous;
	
	free(rcl);
	LBG_object_make_handles_invalid(rcl);
	return(next);
}
// </lbgui_rightclickfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_digitsfunc.h>
LBG_DIGITS* LBG_create_digits (LBG_WINDOW* _parent, var pos_x, var pos_y, STRING* format, var value, long flags)
{
	LBG_DIGITS* dgts = malloc(sizeof(LBG_DIGITS));
	dgts->ssize = sizeof(LBG_DIGITS);
	dgts->stype = 17;
	
	dgts->parent = _parent;
	dgts->layer = 0;
	dgts->flags = flags;
	
	
	dgts->pos_x = pos_x;
	dgts->pos_y = pos_y;
	
	dgts->scale_x = 1;
	dgts->scale_y = 1;
	
	
	if(flags & DF_EXTERNVAR)
	{
		dgts->value = *((var*)value);
		dgts->v = value;
	}
	else
	{
		dgts->value = value;
		dgts->v = NULL;
	}
	
	if(flags & DF_EXTERNFORMAT)
	{
		dgts->format = format;
	}
	else
	{
		dgts->format = str_create("");
		str_cpy(dgts->format,format);
	}
	
	dgts->text = txt_create(1,LBG_object_calc_text_layer(dgts));
	dgts->text->font = LBG_digits_font;
	dgts->caption = (dgts->text->pstring)[0];
	
	dgts->size_x = dgts->text->size_x;
	dgts->size_y = dgts->text->size_y;
	
	
	dgts->text->pos_x = dgts->pos_x;
	dgts->text->pos_y = dgts->pos_y;
	
	if(dgts->flags & DF_SHOW)
	{
		if(dgts->text) dgts->text.flags |= SHOW;
	}
	
	
	dgts->Destroy = 0;
	
	
	dgts->next = NULL;
	if(LBG_DIGITS_FIRST == NULL)
	{
		LBG_DIGITS_FIRST = dgts;
		dgts->previous = NULL;
	}
	else
	{
		dgts->previous = LBG_object_last(LBG_DIGITS_FIRST);
		dgts->previous->next = dgts;
	}
	
	return (dgts);
}




void LBG_update_digits_layer (LBG_DIGITS* dgts)
{
	var x;
	x = LBG_object_calc_text_layer(dgts);
	if(dgts->text->layer != x) layer_sort(dgts->text,x);
}

LBG_DIGITS* LBG_manage_digits (LBG_DIGITS* dgts)
{ 
	LBG_object_upate_pos(dgts);
	LBG_object_upate_size(dgts);
	LBG_update_digits_layer(dgts);
	
	if(dgts->flags & DF_EXTERNVAR) dgts->value = *(dgts->v);
	str_printf((dgts->text->pstring)[0], _chr(dgts->format),(double)dgts->value);
	
	
	if(dgts->flags & DF_SHOW)
	{
		dgts->text->flags |= SHOW;
	}
	else
	{
		dgts->text->flags &= ~SHOW;
	}
	return dgts->next;
}



void LBG_update_digits (LBG_DIGITS* dgts)
{
	LBG_object_upate_pos(dgts);
	LBG_object_upate_size(dgts);
	LBG_update_digits_layer(dgts);
}

void LBG_digits_execute (LBG_DIGITS* dgts, void* func)
{
	if(func != 0)
	{
		LBG_event_object = dgts;
		LBG_event_digits = dgts;
		LBG_event = func;
		LBG_event();
	}
}



LBG_DIGITS* LBG_destroy_digits (LBG_DIGITS* dgts)
{
	LBG_digits_execute(dgts,dgts->Destroy);
	
	ptr_remove(dgts->text);
	
	LBG_DIGITS* next = dgts->next;
	if(dgts->previous) dgts->previous->next = dgts->next;
	else LBG_DIGITS_FIRST = dgts->next;
	if(dgts->next) dgts->next->previous = dgts->previous;
	
	free(dgts);
	LBG_object_make_handles_invalid(dgts);
	return(next);
}

// </lbgui_digitsfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_editfunc.h>

void LBG_editbox_update_vstring (LBG_EDITBOX* ebx)
{
	if(ebx->flags & EF_PASSWORD)
	{
		str_cpy(ebx->vstring,"");
		var n = str_len(ebx->caption)-ebx->hscrollamount;
		var i;
		for(i=0;i<n;i++) str_cat(ebx->vstring,"*");
		return;
	}
	str_cpy(ebx->vstring,ebx->caption);
	str_clip(ebx->vstring,ebx->hscrollamount);
}


LBG_EDITBOX* LBG_create_editbox (LBG_WINDOW* _parent, var pos_x, var pos_y, var width, var tpos_x, var tpos_y, STRING* caption, LBG_EDITBOX_BMAPS* bmaps, long flags)
{
	LBG_EDITBOX* ebx = malloc(sizeof(LBG_EDITBOX));
	ebx->ssize = sizeof(LBG_EDITBOX);
	ebx->stype = 18;
	
	if(flags & EF_EXTERNSTRING)
	{
		ebx->caption = caption;
	}
	else
	{
		ebx->caption = str_create("");
		str_cpy(ebx->caption,caption);
	}
	ebx->vstring = str_create(ebx->caption);
	ebx->vsleft = str_create(ebx->caption);
	ebx->vsright = str_create("");
	
	
	ebx->parent = _parent;
	ebx->layer = 0;
	ebx->flags = flags;
	
	ebx->text = txt_create(1,LBG_object_calc_text_layer(ebx));
	ptr_remove((ebx->text->pstring)[0]);
	(ebx->text->pstring)[0] = ebx->vstring;
	
	ebx->text->font = LBG_editbox_font;
	
	ebx->tpos_x = tpos_x;
	ebx->tpos_y = tpos_y;
	
	
	ebx->pos_x = pos_x;
	ebx->pos_y = pos_y;
	
	ebx->scale_x = 1;
	ebx->scale_y = 1;
	
	ebx->panel = pan_create("",LBG_object_calc_panel_layer(ebx));
	ebx->bmaps.bmap_left = bmaps.bmap_left;
	ebx->bmaps.bmap_middle = bmaps.bmap_middle;
	ebx->bmaps.bmap_right = bmaps.bmap_right;
	
	
	ebx->size_x = width;
	ebx->size_y = bmap_height(ebx->bmaps.bmap_right);
	
	
	ebx->panel->bmap = bmap_createblack(ebx->size_x,ebx->size_y,32);
	LBG_progressbar_bitmap(ebx->panel->bmap,bmaps,ebx->size_x,ebx->size_y);
	ebx->panel->pos_x = ebx->pos_x;
	ebx->panel->pos_y = ebx->pos_y;
	ebx->panel->size_x = ebx->size_x;
	ebx->panel->size_y = ebx->size_y;
	
	ebx->text->pos_x = ebx->pos_x + ebx->tpos_x;
	ebx->text->pos_y = ebx->pos_y + ebx->tpos_y;
	
	
	
	
	ebx->hscrollamount = 0;
	ebx->cursor = txt_create(1,LBG_object_calc_text_layer(ebx)+1);
	str_cpy((ebx->cursor->pstring)[0],"|");
	ebx->cursor->font = ebx->text->font;
	
	
	ebx->time = 0.5;
	ebx->counter = 0;
	
	ebx->max_length = 0;
	
	
	if(ebx->flags & EF_SHOW)
	{
		ebx->panel->flags |= SHOW;
		ebx->text->flags |= SHOW;
		ebx->cursor->flags |= SHOW;
	}
	
	
	
	ebx->next = NULL;
	if(LBG_EDITBOX_FIRST == NULL)
	{
		LBG_EDITBOX_FIRST = ebx;
		ebx->previous = NULL;
	}
	else
	{
		ebx->previous = LBG_object_last(LBG_EDITBOX_FIRST);
		ebx->previous->next = ebx;
	}
	
	
	LBG_object_upate_size (ebx);
	
	
	
	ebx->Destroy = 0;
	ebx->Mask = 0;
	ebx->Key = 0;
	
	
	LBG_editbox_update_vstring(ebx);
	
	return (ebx);
}

void LBG_update_editbox_layer (LBG_EDITBOX* ebx)
{
	var x;
	x = LBG_object_calc_panel_layer(ebx);
	if(ebx->panel->layer != x) layer_sort(ebx->panel,x);
	x = LBG_object_calc_text_layer(ebx);
	if(ebx->text->layer != x) layer_sort(ebx->text,x);
	x = LBG_object_calc_text_layer(ebx)+1;
	if(ebx->cursor->layer != x) layer_sort(ebx->cursor,x);
}


STRING* LBG_str_width_str_temp = "";
var LBG_str_width (STRING* str, FONT* font)
{
	str_cpy(LBG_str_width_str_temp,str);
	var x = str_width("W",font);
	str_cat(LBG_str_width_str_temp,"W");
	var y = str_width(LBG_str_width_str_temp,font);
	return y-x;
}





void LBG_editbox_update_vleftright (LBG_EDITBOX* ebx)
{
	str_cpy(ebx->vsleft,ebx->vstring);
	str_cpy(ebx->vsright,ebx->vstring);
	str_trunc(ebx->vsleft,str_len(ebx->vstring)-ebx->cursor_pos+ebx->hscrollamount);
	str_clip(ebx->vsright,str_len(ebx->vstring)-ebx->cursor_pos+ebx->hscrollamount);
	
}

void LBG_editbox_update_cursor_pos (LBG_EDITBOX* ebx)
{
	ebx->cursor->pos_x = ebx->text->pos_x + LBG_str_width(ebx->vsleft,ebx->text->font) -str_width("|",ebx->text->font)/2;
	ebx->cursor->pos_y = ebx->text->pos_y;
}

void LBG_editbox_update_cursor(LBG_EDITBOX* ebx)
{
	if(ebx->cursor_pos < 0) ebx->cursor_pos = 0;
	if(ebx->cursor_pos > str_len(ebx->caption)) ebx->cursor_pos = str_len(ebx->caption);
	
	
	LBG_editbox_update_vstring(ebx);
	LBG_editbox_update_vleftright(ebx);
	LBG_editbox_update_cursor_pos(ebx);
}


STRING* LBG_editbox_inchar_str1 = "";
STRING* LBG_editbox_inchar_str2 = "";


void LBG_editbox_backspace(LBG_EDITBOX* ebx)
{
	if(ebx->cursor_pos <= 0) return;
	str_cpy(ebx->vsleft,ebx->caption);
	str_cpy(ebx->vsright,ebx->caption);
	str_trunc(ebx->vsleft,str_len(ebx->caption)-ebx->cursor_pos+1);
	str_clip(ebx->vsright,ebx->cursor_pos);
	str_cpy(ebx->caption,ebx->vsleft);
	str_cat(ebx->caption,ebx->vsright);
	ebx->cursor_pos--;
	str_cpy(LBG_editbox_inchar_str1,"");
	
	
	LBG_editbox_update_cursor(ebx);
}

void LBG_editbox_delete(LBG_EDITBOX* ebx)
{
	if(ebx->cursor_pos >= str_len(ebx->caption)) return;
	str_cpy(ebx->vsleft,ebx->caption);
	str_cpy(ebx->vsright,ebx->caption);
	str_trunc(ebx->vsleft,str_len(ebx->caption)-ebx->cursor_pos);
	str_clip(ebx->vsright,ebx->cursor_pos+1);
	str_cpy(ebx->caption,ebx->vsleft);
	str_cat(ebx->caption,ebx->vsright);
	str_cpy(LBG_editbox_inchar_str1,"");
	
	
	LBG_editbox_update_cursor(ebx);
}


void LBG_editbox_autoscroll_right (LBG_EDITBOX* ebx)
{
	while(ebx->cursor->pos_x > ebx->text->pos_x + bmap_width(ebx->panel->bmap)-ebx->tpos_x*2)
	{
		ebx->hscrollamount++;
		if(ebx->hscrollamount >= str_len(ebx->caption))
		{
			ebx->hscrollamount = str_len(ebx->caption);
			LBG_editbox_update_cursor(ebx);
			break;
		}
		LBG_editbox_update_cursor(ebx);
	}
}

void LBG_editbox_autoscroll_left (LBG_EDITBOX* ebx)
{
	while(ebx->cursor_pos < ebx->hscrollamount)
	{
		ebx->hscrollamount-=5;
		if(ebx->hscrollamount <= 0)
		{
			ebx->hscrollamount = 0;
			LBG_editbox_update_cursor(ebx);
			break;
		}
		LBG_editbox_update_cursor(ebx);
	}
}

void LBG_editbox_autoscroll (LBG_EDITBOX* ebx)
{
	LBG_editbox_autoscroll_left(ebx);
	LBG_editbox_autoscroll_right(ebx);
}




void LBG_editbox_execute (LBG_EDITBOX* ebx, void* func)
{
	if(func != 0)
	{
		LBG_event_object = ebx;
		LBG_event_editbox = ebx;
		LBG_event = func;
		LBG_event();
	}
}

int LBG_mask (STRING* input);
int LBG_editbox_mask (LBG_EDITBOX* ebx, void* func, STRING* input)
{
	if(func != 0)
	{
		LBG_event_object = ebx;
		LBG_event_editbox = ebx;
		LBG_mask = func;
		return LBG_mask(input);
	}
	return 1;
}



LBG_EDITBOX* LBG_active_editbox;
void LBG_find_active_editbox ()
{
	LBG_active_editbox = NULL;
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	while(ebx)
	{
		if(ebx->flags & EF_ACTIVE)
		{
			LBG_active_editbox = ebx;
			return;
		}
		ebx = ebx->next;
	}
}



void LBG_editbox_inchar_loop ()
{
	while(1)
	{
		LBG_find_active_editbox();
		if(!LBG_active_editbox)
		{
			wait(1);
			if(!(LBG_flags & LBGUI_RUNNING)) return;
			continue;
		}
		if(LBG_active_editbox->flags & EF_ACTIVE)
		{
			inchar(LBG_editbox_inchar_str2);
		}
		else wait(1);
		if(!(LBG_flags & LBGUI_RUNNING)) return;
		LBG_find_active_editbox();
		if(!LBG_active_editbox) continue;
		if(str_to_asc(LBG_editbox_inchar_str2) == 32)
		{
			LBG_active_editbox->counter = 0;
			LBG_flags &= ~LBGUI_STOPACTION;
			if(key_lastpressed != 57)
			{
				str_cpy(LBG_editbox_inchar_str2,""); // if it's not a space, it shouldn't return a space!
				LBG_editbox_execute(LBG_active_editbox,LBG_active_editbox->Key);
			}
			if(!(LBG_flags & LBGUI_STOPACTION))
			switch(key_lastpressed)
			{
				case 75: // left
				LBG_active_editbox->cursor_pos--;
				LBG_editbox_update_cursor(LBG_active_editbox);
				break;
				case 77: // right
				LBG_active_editbox->cursor_pos++;
				LBG_editbox_update_cursor(LBG_active_editbox);
				break;
				case 14: // backspace
				LBG_editbox_backspace(LBG_active_editbox);
				break;
				case 83: // delete
				LBG_editbox_delete(LBG_active_editbox);
				break;
				case 71: // Home (Pos1)
				LBG_active_editbox->cursor_pos=0;
				LBG_editbox_update_cursor(LBG_active_editbox);
				break;
				case 79: // End
				LBG_active_editbox->cursor_pos=str_len(LBG_active_editbox->caption);
				LBG_editbox_update_cursor(LBG_active_editbox);
				break;
			}
			LBG_editbox_autoscroll(LBG_active_editbox);
		}
		if(LBG_active_editbox->flags & EF_NUMBERS)
		{
			var c = str_to_asc(LBG_editbox_inchar_str2);
			if ((c < 48) || (c > 57)) str_cpy(LBG_editbox_inchar_str2,"");
		}
		if(LBG_active_editbox->flags & EF_ALPHANUMERIC)
		{
			var c = str_to_asc(LBG_editbox_inchar_str2);
			if (((c < 48) || (c > 57)) && ((c < 97) || (c > 122)) && ((c < 65) || (c > 90)) && (c != 95) && (c != 32)) str_cpy(LBG_editbox_inchar_str2,"");
		}
		if(LBG_active_editbox->flags & EF_NOSPACE)
		{
			if(str_to_asc(LBG_editbox_inchar_str2) == 32) str_cpy(LBG_editbox_inchar_str2,"");
		}
		if(LBG_active_editbox->flags & EF_NOUNDERSCORE)
		{
			if(str_to_asc(LBG_editbox_inchar_str2) == 95) str_cpy(LBG_editbox_inchar_str2,"");
		}
		if(!LBG_editbox_mask(LBG_active_editbox,LBG_active_editbox->Mask,LBG_editbox_inchar_str2)) str_cpy(LBG_editbox_inchar_str2,"");
		
		if (LBG_active_editbox->max_length) if(str_len(LBG_active_editbox->caption) >= LBG_active_editbox->max_length) str_cpy(LBG_editbox_inchar_str2,"");
		
		if ((key_lastpressed == 28) || (key_lastpressed == 1))
		{
			LBG_active_editbox->flags &= ~EF_ACTIVE;
			LBG_find_active_editbox();
			str_cpy(LBG_editbox_inchar_str1,"");
			str_cpy(LBG_editbox_inchar_str2,"");
			continue;
		}
		
		
		
		str_cat(LBG_editbox_inchar_str1,LBG_editbox_inchar_str2);
		str_cpy(LBG_editbox_inchar_str2,"");
		if(LBG_active_editbox->flags & EF_READONLY) str_cpy(LBG_editbox_inchar_str1,"");
	}
	
}



void LBG_editbox_add_input(LBG_EDITBOX* ebx)
{
	if(!str_len(LBG_editbox_inchar_str1)) return;
	ebx->counter = 0;
	
	str_cpy(ebx->vsleft,ebx->caption);
	str_cpy(ebx->vsright,ebx->caption);
	str_trunc(ebx->vsleft,str_len(ebx->caption)-ebx->cursor_pos);
	str_clip(ebx->vsright,ebx->cursor_pos);
	str_cpy(ebx->caption,ebx->vsleft);
	str_cat(ebx->caption,LBG_editbox_inchar_str1);
	str_cat(ebx->caption,ebx->vsright);
	ebx->cursor_pos += str_len(LBG_editbox_inchar_str1);
	str_cpy(LBG_editbox_inchar_str1,"");
	
	
	LBG_editbox_update_cursor(ebx);
	LBG_editbox_autoscroll(ebx);
}


void LBG_editbox_set_cursor_pos_by_mouse (LBG_EDITBOX* ebx)
{
	var x = str_width("|",ebx->text->font)/2;
	if(mouse_pos.x - x <= ebx->text->pos_x)
	{
		ebx->cursor_pos = ebx->hscrollamount;
		LBG_editbox_update_cursor(ebx);
		return;
	}
	if(mouse_pos.x - x >= LBG_str_width(ebx->vstring,ebx->text->font) + ebx->text->pos_x)
	{
		ebx->cursor_pos = str_len(ebx->vstring) + ebx->hscrollamount;
		LBG_editbox_update_cursor(ebx);
		return;
	}
	var i; var y = str_len(ebx->vstring);
	for(i=1;i<=y;i++)
	{
		str_cpy(LBG_str_temp,ebx->vstring);
		str_trunc(LBG_str_temp,y-i);
		if(mouse_pos.x - x <= ebx->text->pos_x + LBG_str_width(LBG_str_temp,ebx->text->font))
		{
			ebx->cursor_pos = i + ebx->hscrollamount;
			LBG_editbox_update_cursor(ebx);
			return;
		}
	}
	ebx->cursor_pos = str_len(ebx->vstring) + ebx->hscrollamount;
	LBG_editbox_update_cursor(ebx);
	
}



LBG_EDITBOX* LBG_manage_editbox (LBG_EDITBOX* ebx)
{
	LBG_object_upate_pos(ebx);
	LBG_object_upate_size(ebx);
	LBG_update_editbox_layer(ebx);
	ebx->cursor->pos_y = ebx->text->pos_y;
	
	ebx->counter += time_step/16;
	ebx->counter %= (ebx->time*2);
	
	if (!(ebx->flags & EF_DISABLED))
	{
		if (!(key_pressed(280)))
		{
			ebx->flags &= ~EFi_CLICK0;
			ebx->flags &= ~EFi_CLICK1;
			ebx->flags &= ~EF_CLICKED;
		}
		
		if (LBG_mouse_over_object(ebx) && (ebx->parent == LBG_mouse_window()) && LBG_window_mouse_over_content (ebx->parent) && (((!(ebx->flags & EFi_CLICK0)) && (!(ebx->flags & EFi_CLICK1))) || ((!(ebx->flags & EFi_CLICK0)) && ((ebx->flags & EFi_CLICK1)))))
		{
			LBG_mouse_cursor = 6;
			
			
			ebx->flags |= EFi_OVER;
			if (key_pressed(280))
			{
				ebx->flags &= ~EFi_CLICK0;
				ebx->flags |= EFi_CLICK1;
				ebx->flags |= EF_CLICKED;
				
				ebx->flags |= EF_ACTIVE;
				inkey_active = 0;
				LBG_editbox_set_cursor_pos_by_mouse(ebx);
				ebx->counter = 0;
			}
		}
		else
		{
			ebx.flags &= ~EF_EVENT;
			ebx->flags &= ~EFi_OVER;
			ebx->flags &= ~EF_CLICKED;
		}
		if ((!(ebx->flags & EFi_CLICK0)) && (!(ebx->flags & EFi_CLICK1)) && (key_pressed(280)))
		{
			ebx->flags |= EFi_CLICK0;
			ebx->flags &= ~EFi_CLICK1;
			ebx->flags &= ~EF_CLICKED;
			
			ebx->flags &= ~EF_ACTIVE;
		}
		
	}
	else
	{
		ebx->flags |= EFi_CLICK0;
		ebx->flags &= ~EFi_CLICK1;
		ebx->flags &= ~EFi_OVER;
		ebx->flags &= ~EF_CLICKED;
	}
	
	
	
	if(LBG_active_editbox == ebx) LBG_editbox_add_input(ebx);
	if (ebx->max_length) if(str_len(ebx->caption) > ebx->max_length)
	{
		str_trunc(ebx->caption,str_len(ebx->caption)-ebx->max_length);
		LBG_editbox_update_cursor(ebx);
	}
	
	
	
	if(ebx->flags & EF_SHOW)
	{
		ebx->panel->flags |= SHOW;
		ebx->text->flags |= SHOW;
		if(ebx->counter < ebx->time) ebx->cursor->flags |= SHOW;
		else ebx->cursor->flags &= ~SHOW;
		if(!(ebx->flags & EF_ACTIVE)) ebx->cursor->flags &= ~SHOW;
	}
	else
	{
		ebx->panel->flags &= ~SHOW;
		ebx->text->flags &= ~SHOW;
		ebx->cursor->flags &= ~SHOW;
	}
	
	
	
	
	
	
	
	return ebx->next;
}







LBG_EDITBOX* LBG_destroy_editbox (LBG_EDITBOX* ebx)
{
	
	LBG_editbox_execute(ebx,ebx->Destroy);
	
	if(!(ebx->flags & EF_EXTERNSTRING)) ptr_remove(ebx->caption);
	ptr_remove(ebx->text);
	ptr_remove(ebx->panel);
	ptr_remove(ebx->vstring);
	ptr_remove(ebx->vsleft);
	ptr_remove(ebx->vsright);
	ptr_remove(ebx->cursor);
	
	LBG_object_destroy_infoboxes(ebx);
	LBG_object_destroy_rightclicks(ebx);
	
	LBG_EDITBOX* next = ebx->next;
	if(ebx->previous) ebx->previous->next = ebx->next;
	else LBG_EDITBOX_FIRST = ebx->next;
	if(ebx->next) ebx->next->previous = ebx->previous;
	
	
	free(ebx);
	LBG_object_make_handles_invalid(ebx);
	return(next);
}




void LBG_update_editbox (LBG_EDITBOX* ebx)
{
	LBG_object_upate_pos(ebx);
	LBG_object_upate_size(ebx);
	LBG_update_editbox_layer(ebx);
	LBG_editbox_update_cursor(ebx);
	LBG_editbox_autoscroll(ebx);
	ptr_remove(ebx->panel->bmap);
	ebx->panel->bmap = bmap_createblack(ebx->size_x,ebx->size_y,32);
	LBG_progressbar_bitmap(ebx->panel->bmap,ebx->bmaps,ebx->size_x,ebx->size_y);
}




void LBG_ebmaps_destroy_2frames (LBG_EDITBOX_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_EDITBOX_BMAPS* LBG_ebmaps (BMAP* bmap_left, BMAP* bmap_middle, BMAP* bmap_right)
{
	LBG_EDITBOX_BMAPS* bmaps = malloc(sizeof(LBG_EDITBOX_BMAPS));
	bmaps->bmap_left = bmap_left;
	bmaps->bmap_middle = bmap_middle;
	bmaps->bmap_right = bmap_right;
	LBG_ebmaps_destroy_2frames(bmaps);
	return(bmaps);
}



void LBG_editbox_set_text_color (LBG_EDITBOX* ebx, COLOR* color)
{
	vec_set(ebx->text->blue,color);
	vec_set(ebx->cursor->blue,color);
}
// </lbgui_editfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_comboboxfunc.h>
LBG_COMBOBOX* LBG_create_combobox (LBG_WINDOW* _parent, var pos_x, var pos_y, var width,var tpos_x, var tpos_y, STRING* caption, LBG_EDITBOX_BMAPS* ebmaps, var ipos_x, var ipos_y, var isize_x, LBG_LISTBOX_BMAPS* mbmaps, LBG_BUTTON_BMAPS* bbmaps, long flags)
{
	LBG_COMBOBOX* cbb = malloc(sizeof(LBG_COMBOBOX));
	cbb->ssize = sizeof(LBG_COMBOBOX);
	cbb->stype = 16;
	
	
	
	cbb->parent = _parent;
	cbb->layer = 0;
	cbb->flags = flags;
	
	
	cbb->pos_x = pos_x;
	cbb->pos_y = pos_y;
	
	cbb->scale_x = 1;
	cbb->scale_y = 1;
	
	
	
	cbb->menu = LBG_create_listbox (cbb,0,0,width,ipos_y,ipos_x,ipos_y,isize_x,ipos_y,mbmaps,0);
	cbb->menu->flags |= LFi_COMBOBOX;
	
	long eflags = EF_DISABLED;
	if(flags & CBF_EXTERNSTRING) eflags |= EF_EXTERNSTRING;
	cbb->editbox = LBG_create_editbox (cbb->parent,cbb->pos_x,cbb->pos_y,width-bmap_width(bbmaps->bmap_default),tpos_x,tpos_y,caption,ebmaps,eflags);
	cbb->caption = cbb->editbox->caption;
	
	cbb->button = LBG_create_button(cbb,cbb->pos_x+cbb->editbox->size_x,cbb->pos_y,0,0,"",bbmaps,0,BFi_COMBOBOX);
	
	cbb->chosen_option = NULL;
	
	cbb->Destroy = 0;
	cbb->Open = 0;
	cbb->Close = 0;
	
	
	
	if(cbb->flags & CBF_SHOW)
	{
		cbb->editbox->flags |= EF_SHOW;
		cbb->button->flags |= BF_SHOW;
	}
	else
	{
		cbb->editbox->flags &= ~EF_SHOW;
		cbb->menu->flags &= ~LF_SHOW;
		cbb->button->flags &= ~BF_SHOW;
	}
	
	
	cbb->next = NULL;
	if(LBG_COMBOBOX_FIRST == NULL)
	{
		LBG_COMBOBOX_FIRST = cbb;
		cbb->previous = NULL;
	}
	else
	{
		cbb->previous = LBG_object_last(LBG_COMBOBOX_FIRST);
		cbb->previous->next = cbb;
	}
	
	
	
	return (cbb);
}


void LBG_combobox_execute (LBG_COMBOBOX* cbb, void* func)
{
	if(func != 0)
	{
		LBG_event_object = cbb;
		LBG_event_combobox = cbb;
		LBG_event = func;
		LBG_event();
	}
}


LBG_COMBOBOX* LBG_manage_combobox (LBG_COMBOBOX* cbb)
{
	cbb->editbox->pos_x = cbb->pos_x;
	cbb->editbox->pos_y = cbb->pos_y;
	
	if((cbb->menu->flags & LF_SHOW) && (!(LBG_mouse_over_object(cbb->menu))) && ((key_pressed(280)) || (key_pressed(281))))
	{
		cbb->menu->flags &= ~LF_SHOW;
		cbb->menu->flags |= LF_DISABLED;
		LBG_combobox_execute(cbb,cbb->Close);
	}
	
	
	if(cbb->button->flags & BF_EVENT)
	{
		cbb->menu->flags |= LF_SHOW;
		cbb->menu->flags &= ~LF_DISABLED;
		cbb->menu->pos_x = cbb->editbox->panel->pos_x;
		cbb->menu->pos_y = cbb->editbox->panel->pos_y + cbb->editbox->panel->size_y;
		LBG_listbox_calc_size_y(cbb->menu);
		LBG_menu_correct_position(cbb->menu);
		LBG_update_listbox(cbb->menu);
		LBG_combobox_execute(cbb,cbb->Open);
	}
	
	
	
	return cbb->next;
}



void LBG_update_combobox (LBG_COMBOBOX* cbb)
{
	cbb->menu->isize_y = LBG_object_num(cbb->menu->item_first)*cbb->menu->itemheight;
	LBG_update_editbox(cbb->editbox);
	LBG_update_listbox(cbb->menu);
	LBG_update_button(cbb->button);
}


LBG_COMBOBOX* LBG_destroy_combobox (LBG_COMBOBOX* cbb)
{
	
	LBG_combobox_execute(cbb,cbb->Destroy);
	
	LBG_destroy_editbox(cbb->editbox);
	LBG_destroy_button(cbb->button);
	LBG_destroy_listbox(cbb->menu);
	
	LBG_object_destroy_infoboxes(cbb);
	LBG_object_destroy_rightclicks(cbb);
	
	
	LBG_COMBOBOX* next = cbb->next;
	if(cbb->previous) cbb->previous->next = cbb->next;
	else LBG_COMBOBOX_FIRST = cbb->next;
	if(cbb->next) cbb->next->previous = cbb->previous;
	
	
	free(cbb);
	LBG_object_make_handles_invalid(cbb);
	return(next);
}

// </lbgui_comboboxfunc.h>
//-------------------------------------------------------------------------------------------------------
// <lbgui_windowfunc.h>


var LBG_window_titlebarheight (LBG_WINDOW* win)
{
	if(win->flags & WFi_NOTITLEBAR) return 0;
	else return bmap_height(win->bbmaps.bmap_titlebar_left);
}

var LBG_window_leftborderwidth (LBG_WINDOW* win)
{
	if(win->flags & WFi_NOBORDER) return 0;
	else return bmap_width(win->bbmaps.bmap_border_left);
}

var LBG_window_rightborderwidth (LBG_WINDOW* win)
{
	if(win->flags & WFi_NOBORDER) return 0;
	else return bmap_width(win->bbmaps.bmap_border_right);
}

var LBG_window_bottomborderheight (LBG_WINDOW* win)
{
	if(win->flags & WFi_NOBORDER) return 0;
	else return bmap_height(win->bbmaps.bmap_border_bottom);
}

var LBG_window_num_titiblebar_buttons (LBG_WINDOW* win)
{
	var ret = 0;
	if (win->flags & WF_XBUTTON) ret++;
	if (win->flags & WF_MAXBUTTON) ret++;
	return(ret);
}

void LBG_window_border_bitmap (BMAP* _bmap, LBG_WBORDER_BMAPS* bmaps, var size_x, var size_y) // For internal use
{
	bmap_blit(_bmap,bmaps->bmap_titlebar_left,vector(0,0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_titlebar_right,vector(size_x-bmap_width(bmaps->bmap_titlebar_right),0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_titlebar_middle,vector(bmap_width(bmaps->bmap_titlebar_left),0,0),vector(size_x-bmap_width(bmaps->bmap_titlebar_left)-bmap_width(bmaps->bmap_titlebar_right),bmap_height(bmaps->bmap_titlebar_middle),0));
	
	if(!bmaps->bmap_border_bottomleft) return;
	bmap_blit(_bmap,bmaps->bmap_border_bottomleft,vector(0,size_y-bmap_height(bmaps->bmap_border_bottomleft),0),NULL);
	bmap_blit(_bmap,bmaps->bmap_border_bottomright,vector(size_x-bmap_width(bmaps->bmap_border_bottomright),size_y-bmap_height(bmaps->bmap_border_bottomright),0),NULL);
	bmap_blit(_bmap,bmaps->bmap_border_left,vector(0,bmap_height(bmaps->bmap_titlebar_middle),0),vector(bmap_width(bmaps->bmap_border_left),size_y-bmap_height(bmaps->bmap_titlebar_middle)-bmap_height(bmaps->bmap_border_bottomleft),0));
	bmap_blit(_bmap,bmaps->bmap_border_right,vector(size_x-bmap_width(bmaps->bmap_border_right),bmap_height(bmaps->bmap_titlebar_middle),0),vector(bmap_width(bmaps->bmap_border_right),size_y-bmap_height(bmaps->bmap_titlebar_middle)-bmap_height(bmaps->bmap_border_bottomright),0));
	bmap_blit(_bmap,bmaps->bmap_border_bottom,vector(bmap_width(bmaps->bmap_border_bottomleft),size_y-bmap_height(bmaps->bmap_border_bottom),0),vector(size_x-bmap_width(bmaps->bmap_border_left)-bmap_width(bmaps->bmap_border_right),bmap_height(bmaps->bmap_border_bottom),0));
}

void LBG_window_content_bitmap (BMAP* _bmap, LBG_CBORDER_BMAPS* bmaps, var size_x, var size_y) // For internal use
{
	bmap_blit(_bmap,bmaps->bmap_topleft,vector(0,0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_topright,vector(size_x-bmap_width(bmaps->bmap_topright),0,0),NULL);
	bmap_blit(_bmap,bmaps->bmap_top,vector(bmap_width(bmaps->bmap_topleft),0,0),vector(size_x-bmap_width(bmaps->bmap_topleft)-bmap_width(bmaps->bmap_topright),bmap_height(bmaps->bmap_top),0));
	
	bmap_blit(_bmap,bmaps->bmap_bottomleft,vector(0,size_y-bmap_height(bmaps->bmap_bottomleft),0),NULL);
	bmap_blit(_bmap,bmaps->bmap_bottomright,vector(size_x-bmap_width(bmaps->bmap_bottomright),size_y-bmap_height(bmaps->bmap_bottomright),0),NULL);
	bmap_blit(_bmap,bmaps->bmap_left,vector(0,bmap_height(bmaps->bmap_top),0),vector(bmap_width(bmaps->bmap_left),size_y-bmap_height(bmaps->bmap_top)-bmap_height(bmaps->bmap_bottomleft),0));
	bmap_blit(_bmap,bmaps->bmap_right,vector(size_x-bmap_width(bmaps->bmap_right),bmap_height(bmaps->bmap_top),0),vector(bmap_width(bmaps->bmap_right),size_y-bmap_height(bmaps->bmap_top)-bmap_height(bmaps->bmap_bottomright),0));
	bmap_blit(_bmap,bmaps->bmap_bottom,vector(bmap_width(bmaps->bmap_bottomleft),size_y-bmap_height(bmaps->bmap_bottom),0),vector(size_x-bmap_width(bmaps->bmap_left)-bmap_width(bmaps->bmap_right),bmap_height(bmaps->bmap_bottom),0));
	
	bmap_blit(_bmap,bmaps->bmap_center,vector(bmap_width(bmaps->bmap_left),bmap_height(bmaps->bmap_top),0),vector(size_x-bmap_width(bmaps->bmap_left)-bmap_width(bmaps->bmap_right),size_y-bmap_height(bmaps->bmap_top)-bmap_height(bmaps->bmap_bottom),0));
	
}


int LBG_mouse_over_window (LBG_WINDOW* win)
{
	if(win) return((LBG_mouse_pos_x() > win->pos_x) && (LBG_mouse_pos_x() < win->pos_x + win->size_x) && (LBG_mouse_pos_y() > win->pos_y) && (LBG_mouse_pos_y() < win->pos_y + win->size_y));
	else return 1;
}

LBG_WINDOW* LBG_mouse_window ()
{
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	while(lst)
	{
		if(lst->flags & LF_SHOW)
		if((lst->flags & LFi_RIGHTCLICK) || (lst->flags & LFi_COMBOBOX))
		if(LBG_mouse_over_object(lst))
		return lst;
		lst = lst->next;
	}
	
	LBG_WINDOW* winx = LBG_WINDOW_FIRST;
	LBG_WINDOW* win = winx;
	
	while(winx)
	{
		if(((winx->layer > win->layer) || ((win == LBG_WINDOW_FIRST) && (!LBG_mouse_over_window(win)))) && (LBG_mouse_over_window(winx))) win = winx;
		winx = winx->next;
	}
	if((win == LBG_WINDOW_FIRST) && (!LBG_mouse_over_window(win))) win = 0;
	
	return(win);
}

LBG_WINDOW* LBG_get_highest_window ()
{
	LBG_WINDOW* winx = LBG_WINDOW_FIRST;
	LBG_WINDOW* win = winx;
	
	while(winx)
	{
		if(winx->layer > win->layer) win = winx;
		winx = winx->next;
	}
	return(win);
}

LBG_WINDOW* LBG_get_highest_nsot_window () // not stay on top
{
	LBG_WINDOW* winx = LBG_WINDOW_FIRST;
	LBG_WINDOW* win = winx;
	
	while(winx)
	{
		if(((winx->layer > win->layer) && (!(winx->flags & WF_STAYONTOP))) || (win->flags & WF_STAYONTOP)) win = winx;
		winx = winx->next;
	}
	if (win->flags & WF_STAYONTOP) return 0;
	return(win);
}

var LBG_get_highest_window_layer ()
{
	LBG_WINDOW* win = LBG_get_highest_window ();
	if(win) return(win->layer);
	return(-1);
}


void LBG_update_window(LBG_WINDOW* win);
void LBG_update_window_layer(LBG_WINDOW* win);
void LBG_set_windows_with_layer_to (var oldlayer, var newlayer)
{
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	
	while(win)
	{
		if(win->layer == oldlayer)
		{
			win->layer = newlayer;
			LBG_update_window_layer(win);
		}
		win = win->next;
	}
}

LBG_WINDOW* LBG_get_window_by_layer(var layer)
{
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	
	while(win)
	{
		if(win->layer == layer)
		{
			return win;
		}
		win = win->next;
	}
	return 0;
}


void LBG_set_window_to_top (LBG_WINDOW* win);
void LBG_check_if_stayontop_windows_are_on_top ()
{
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	var lowest_stayontop = 999999;
	var highest_notstayontop = -1;
	LBG_WINDOW* winl;
	
	while(win)
	{
		if(win->flags & WF_STAYONTOP)
		{
			if(win->layer < lowest_stayontop) winl = win;
			lowest_stayontop = minv(lowest_stayontop,win->layer);
		}
		else
		{
			highest_notstayontop = maxv(highest_notstayontop,win->layer);
		}
		win = win->next;
	}
	if(lowest_stayontop < highest_notstayontop)
	{
		LBG_set_window_to_top(winl);
	}
}

void LBG_set_window_to_top_d (LBG_WINDOW* win);
void LBG_window_set_childs_to_top (LBG_WINDOW* win)
{
	LBG_WINDOW* winx = LBG_WINDOW_FIRST;
	while(winx)
	{
		if(winx->parent == win) LBG_set_window_to_top_d(winx);
		winx = winx->next;
	}
}

void LBG_set_window_to_top_c (LBG_WINDOW* win)
{
	var bak_layer = win->layer;
	win->layer = -1;
	var dest_layer = LBG_get_highest_window_layer ();
	
	var i;
	for(i=bak_layer+1;i<=dest_layer;i++) LBG_set_windows_with_layer_to(i,i-1);
	win->layer = dest_layer;
	if(win->layer < 0) win->layer = 0;
	LBG_update_window_layer(win);
	LBG_check_if_stayontop_windows_are_on_top();
}

void LBG_set_window_to_top_d (LBG_WINDOW* win)
{
	if (LBG_get_highest_window () == win) return;
	if ((!(win->flags & WF_STAYONTOP)) && (LBG_get_highest_nsot_window() == win)) return;
	LBG_set_window_to_top_c(win);
	LBG_window_set_childs_to_top(win);
}

void LBG_set_window_to_top (LBG_WINDOW* win)
{
	if (LBG_get_highest_window () == win) return;
	if ((!(win->flags & WF_STAYONTOP)) && (LBG_get_highest_nsot_window() == win)) return;
	if(win->parent)
	{
		LBG_set_window_to_top(win->parent);
	}
	else LBG_set_window_to_top_c(win);
	LBG_window_set_childs_to_top(win);
}



var LBG_window_calc_panel_layer (var wlayer)
{
	return(LBG_lowest_layer+LBG_winlayer+wlayer*LBG_layer_step);
}

var LBG_window_calc_text_layer (var wlayer)
{
	return(LBG_lowest_layer+LBG_winlayer+wlayer*LBG_layer_step+1);
}

var LBG_window_calc_content_layer (var wlayer)
{
	return(LBG_lowest_layer+LBG_winlayer+wlayer*LBG_layer_step+1);
}



void LBG_window_calc_hscroll_height (LBG_WINDOW* win)
{
	win->hscroll_height = 0;
	if(!(win->flags & WF_HSCROLLBAR)) return;
	
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	hsb = LBG_HSCROLLBAR_FIRST;
	while(hsb)
	{
		if(hsb->target == win)
		{
			win->hscroll_height = hsb->size_y;
			return;
		}
		hsb = hsb->next;
	}
}

void LBG_window_calc_vscroll_width (LBG_WINDOW* win)
{
	win->vscroll_width = 0;
	if(!(win->flags & WF_VSCROLLBAR)) return;
	
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == win)
		{
			win->vscroll_width = vsb->size_x;
			return;
		}
		vsb = vsb->next;
	}
}


void LBG_window_calc_csize (LBG_WINDOW* win)
{
	LBG_window_calc_hscroll_height(win);
	LBG_window_calc_vscroll_width(win);
	win->csize_x = win->size_x - LBG_window_leftborderwidth(win) - LBG_window_rightborderwidth(win) - win->vscroll_width;
	win->csize_y = win->size_y - LBG_window_titlebarheight(win) - LBG_window_bottomborderheight(win) - win->hscroll_height;
}






LBG_WINDOW* LBG_create_window (LBG_WINDOW* _parent, var pos_x, var pos_y, var size_x, var size_y, var tpos_x, var tpos_y,
STRING* caption, LBG_WBORDER_BMAPS* bbmaps, LBG_CBORDER_BMAPS* cbmaps, LBG_TBUTTON_BMAPS* tbmaps, var ctype, void* content,
long flags)
{
	LBG_WINDOW* win = malloc(sizeof(LBG_WINDOW));
	win->ssize = sizeof(LBG_WINDOW);
	win->stype = 1;
	
	if(flags & WF_EXTERNSTRING)
	{
		win->caption = caption;
	}
	else
	{
		win->caption = str_create("");
		str_cpy(win->caption,caption);
	}
	
	win->parent = _parent;
	win->layer = LBG_get_highest_window_layer()+1;
	win->flags = flags;
	
	
	win->text = txt_create(1,LBG_window_calc_text_layer(win->layer));
	ptr_remove((win->text->pstring)[0]);
	(win->text->pstring)[0] = win->caption;
	
	win->text->font = LBG_window_font;
	
	
	win->tpos_x = tpos_x;
	win->tpos_y = tpos_y;
	
	
	win->pos_x = pos_x;
	win->pos_y = pos_y;
	win->size_x = size_x;
	win->size_y = size_y;
	
	win->scale_x = 1;
	win->scale_y = 1;
	
	win->panel = pan_create("",LBG_window_calc_panel_layer(win->layer));
	if(bbmaps)
	{
		win->bbmaps.bmap_titlebar_left = bbmaps->bmap_titlebar_left;
		win->bbmaps.bmap_titlebar_middle = bbmaps->bmap_titlebar_middle;
		win->bbmaps.bmap_titlebar_right = bbmaps->bmap_titlebar_right;
		if(!win->bbmaps.bmap_titlebar_left) win->flags |= WFi_NOTITLEBAR;
		win->bbmaps.bmap_border_left = bbmaps->bmap_border_left;
		win->bbmaps.bmap_border_right = bbmaps->bmap_border_right;
		win->bbmaps.bmap_border_bottomleft = bbmaps->bmap_border_bottomleft;
		win->bbmaps.bmap_border_bottom = bbmaps->bmap_border_bottom;
		win->bbmaps.bmap_border_bottomright = bbmaps->bmap_border_bottomright;
		if(!win->bbmaps.bmap_border_left) win->flags |= WFi_NOBORDER;
	}
	else
	{
		win->flags |= WFi_NOTITLEBAR;
		win->flags |= WFi_NOBORDER;
	}
	
	if(cbmaps)
	{
		win->cbmaps.bmap_topleft = cbmaps->bmap_topleft;
		win->cbmaps.bmap_top = cbmaps->bmap_top;
		win->cbmaps.bmap_topright = cbmaps->bmap_topright;
		win->cbmaps.bmap_left = cbmaps->bmap_left;
		win->cbmaps.bmap_right = cbmaps->bmap_right;
		win->cbmaps.bmap_bottomleft = cbmaps->bmap_bottomleft;
		win->cbmaps.bmap_bottom = cbmaps->bmap_bottom;
		win->cbmaps.bmap_bottomright = cbmaps->bmap_bottomright;
		win->cbmaps.bmap_center = cbmaps->bmap_center;
	}
	
	if(tbmaps)
	{
		
		win->tbmaps.bmap_x_default = tbmaps.bmap_x_default;
		win->tbmaps.bmap_x_over = tbmaps.bmap_x_over;
		win->tbmaps.bmap_x_clicked = tbmaps.bmap_x_clicked;
		win->tbmaps.bmap_max_default = tbmaps.bmap_max_default;
		win->tbmaps.bmap_max_over = tbmaps.bmap_max_over;
		win->tbmaps.bmap_max_clicked = tbmaps.bmap_max_clicked;
		win->tbmaps.bmap_res_default = tbmaps.bmap_res_default;
		win->tbmaps.bmap_res_over = tbmaps.bmap_res_over;
		win->tbmaps.bmap_res_clicked = tbmaps.bmap_res_clicked;
	}
	
	
	win->panel->bmap = bmap_createblack(win->size_x,win->size_y,32);
	if(!(win->flags & WFi_NOTITLEBAR)) LBG_window_border_bitmap(win->panel->bmap,bbmaps,win->size_x,win->size_y);
	
	win->panel->pos_x = win->pos_x;
	win->panel->pos_y = win->pos_y;
	win->panel->size_x = win->size_x;
	win->panel->size_y = win->size_y;
	
	win->text->pos_x = win->pos_x + win->tpos_x;
	win->text->pos_y = win->pos_y + win->tpos_y;
	
	
	win->cpos_x = win->pos_x + LBG_window_leftborderwidth(win);
	win->cpos_y = win->pos_y + LBG_window_titlebarheight(win);
	
	LBG_window_calc_csize (win);
	
	
	win->ctype = ctype;
	
	if(win->ctype == 1)
	{
		win->content = pan_create("",LBG_window_calc_content_layer(win->layer));
		((PANEL*)(win->content))->bmap = bmap_createblack(win->csize_x,win->csize_y,32);
		LBG_window_content_bitmap(((PANEL*)(win->content))->bmap,cbmaps,win->csize_x,win->csize_y);
		((PANEL*)(win->content))->pos_x = win->cpos_x;
		((PANEL*)(win->content))->pos_y = win->cpos_y;
		((PANEL*)(win->content))->size_x = win->csize_x;
		((PANEL*)(win->content))->size_y = win->csize_y;
	}
	else if(win->ctype) win->content = content;
	
	
	
	win->minsize_x = size_x;
	win->minsize_y = size_y;
	win->maxsize_x = 0;
	win->maxsize_y = 0;
	
	
	win->bkx = win->pos_x;
	win->bky = win->pos_y;
	
	win->flags2 = 0;
	
	
	
	
	
	if (flags & WF_XBUTTON)
	{
		win->xbutton = LBG_create_button(win,win->size_x+win->xbutton_offx,win->xbutton_offy,0,0,"",LBG_bbmaps(win->tbmaps.bmap_x_default,win->tbmaps.bmap_x_over,win->tbmaps.bmap_x_clicked,win->tbmaps.bmap_x_default,win->tbmaps.bmap_x_over,win->tbmaps.bmap_x_default),0,BF_SHOW | BFi_TITLEBAR);
	}
	if (flags & WF_MAXBUTTON)
	{
		var _x = win->size_x+win->xbutton_offx;
		var _y = win->xbutton_offy;
		if(flags & WF_XBUTTON) _x -= bmap_width(win->tbmaps.bmap_max_default);
		win->maxbutton = LBG_create_button(win,_x,_y,0,0,"",LBG_bbmaps(win->tbmaps.bmap_max_default,win->tbmaps.bmap_max_over,win->tbmaps.bmap_max_clicked,win->tbmaps.bmap_max_default,win->tbmaps.bmap_max_over,win->tbmaps.bmap_max_default),0,BF_SHOW | BFi_TITLEBAR);
	}
	
	
	
	if(win->flags & WF_SHOW)
	{
		win->panel->flags |= SHOW;
		win->text->flags |= SHOW;
		if((win->ctype != 0) && win->content) ((PANEL*)(win->content))->flags |= SHOW;
	}
	
	
	win->next = NULL;
	if(LBG_WINDOW_FIRST == NULL)
	{
		LBG_WINDOW_FIRST = win;
		win->previous = NULL;
	}
	else
	{
		win->previous = LBG_object_last(LBG_WINDOW_FIRST);
		win->previous->next = win;
	}
	
	win->lastsize_x = win->size_x;
	win->lastsize_y = win->size_y;
	
	win->hscrollamount = 0;
	win->vscrollamount = 0;
	
	win->scroll_minsize_x = 0;
	win->scroll_minsize_y = 0;
	win->scroll_bordersize_x = 0;
	win->scroll_bordersize_y = 0;
	
	win->Destroy = 0;
	win->Close = 0;
	win->Maximize = 0;
	win->Restore = 0;
	win->Resize = 0;
	win->Resizing = 0;
	win->Move = 0;
	win->Moving = 0;
	
	
	LBG_update_window(win);
	
	LBG_window_calc_csize(win);
	LBG_check_if_stayontop_windows_are_on_top();
	
	return(win);
}


BOOL LBG_window_mouse_over_titlebar_button (LBG_WINDOW* win)
{
	BOOL ret = 0;
	if(win->flags & WF_XBUTTON) if(LBG_mouse_over_object(win->xbutton)) ret = 1;
	if(win->flags & WF_MAXBUTTON) if(LBG_mouse_over_object(win->maxbutton)) ret = 1;
	
	return (ret);
}

BOOL LBG_mouse_over_window_move (LBG_WINDOW* win)
{
	if(win) if(!(win->flags & WFi_NOTITLEBAR)) return ((LBG_mouse_pos_x() >= win->pos_x) && (LBG_mouse_pos_x() < win->pos_x + win->size_x) && (LBG_mouse_pos_y() >= win->pos_y) && (LBG_mouse_pos_y() < win->pos_y + LBG_window_titlebarheight(win)) && (LBG_mouse_window() == win) && (!LBG_window_mouse_over_titlebar_button(win)));
	return 0;
}

long LBG_mouse_over_window_border (LBG_WINDOW* win)
{
	if(LBG_mouse_window() != win) return (0);
	long ret = 0;
	// 1 = top
	// 2 = left
	// 4 = right
	// 8 = bottom
	if ((LBG_mouse_pos_x() >= win->pos_x) && (LBG_mouse_pos_x() < win->pos_x + LBG_window_leftborderwidth(win)) && (LBG_mouse_pos_y() >= win->pos_y + LBG_window_titlebarheight(win)) && (LBG_mouse_pos_y() < win->pos_y + win->size_y)) ret |= 2;
	if ((LBG_mouse_pos_x() >= win->pos_x + win->size_x - LBG_window_rightborderwidth(win)) && (LBG_mouse_pos_x() < win->pos_x + win->size_x) && (LBG_mouse_pos_y() >= win->pos_y + LBG_window_titlebarheight(win)) && (LBG_mouse_pos_y() < win->pos_y + win->size_y))  ret |= 4;
	if ((LBG_mouse_pos_x() >= win->pos_x) && (LBG_mouse_pos_x() < win->pos_x + win->size_x) && (LBG_mouse_pos_y() > win->pos_y + win->size_y - LBG_window_bottomborderheight(win)) && (LBG_mouse_pos_y() < win->pos_y + win->size_y))  ret |= 8;
	return (ret);
}

var LBG_window_minsx (LBG_WINDOW* win)
{
	return(maxv(LBG_window_leftborderwidth(win) + LBG_window_rightborderwidth(win),win->minsize_x));
}
var LBG_window_minsy (LBG_WINDOW* win)
{
	return(maxv(LBG_window_titlebarheight(win) + LBG_window_bottomborderheight(win),win->minsize_y));
}

var LBG_window_maxsx (LBG_WINDOW* win)
{
	if(win->maxsize_x) return(win->maxsize_x);
	return(4096);
}
var LBG_window_maxsy (LBG_WINDOW* win)
{
	if(win->maxsize_y) return(win->maxsize_y);
	return(4096);
}

long LBG_window_correct_size (LBG_WINDOW* win)
{
	BOOL ret = 0;
	if(win->size_x > LBG_window_maxsx(win)) {win->size_x = LBG_window_maxsx(win); ret = 1;}
	if(win->size_y > LBG_window_maxsy(win)) {win->size_y = LBG_window_maxsy(win); ret = 1;}
	
	if(win->size_x < LBG_window_minsx(win)) {win->size_x = LBG_window_minsx(win); ret = 1;}
	if(win->size_y < LBG_window_minsy(win)) {win->size_y = LBG_window_minsy(win); ret = 1;}
	
	return(ret);
}

void LBG_window_update_pos (LBG_WINDOW* win)
{
	LBG_window_correct_size(win);
	
	win->cpos_x = win->pos_x + LBG_window_leftborderwidth(win);
	win->cpos_y = win->pos_y + LBG_window_titlebarheight(win);
	
	LBG_window_calc_csize (win);
	
	win->panel->pos_x = win->pos_x;
	win->panel->pos_y = win->pos_y;
	win->panel->size_x = win->size_x;
	win->panel->size_y = win->size_y;
	
	win->text->pos_x = win->pos_x + win->tpos_x;
	win->text->pos_y = win->pos_y + win->tpos_y;
	
	if((win->ctype == 1) || (win->ctype == 2))
	{
		((PANEL*)(win->content))->pos_x = win->cpos_x;
		((PANEL*)(win->content))->pos_y = win->cpos_y;
		((PANEL*)(win->content))->size_x = win->csize_x;
		((PANEL*)(win->content))->size_y = win->csize_y;
	}
}

void LBG_update_window_layer (LBG_WINDOW* win)
{
	var x;
	x = LBG_window_calc_panel_layer(win->layer);
	if(win->panel->layer != x) layer_sort(win->panel,x);
	x = LBG_window_calc_text_layer(win->layer);
	if(win->text->layer != x) layer_sort(win->text,x);
	
	if(win->content && ((win->ctype == 1) || (win->ctype == 2)))
	{
		x = LBG_window_calc_content_layer(win->layer);
		if(((PANEL*)(win->content))->layer != x) layer_sort(win->content,LBG_window_calc_content_layer(win->layer));
	}
}


var LBG_window_get_ncsize_x (LBG_WINDOW* win)
{
	var x = win->scroll_minsize_x;
	LBG_BUTTON* but = LBG_BUTTON_FIRST;
	while(but)
	{
		if((but->parent == win) && (!((but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR)))) x = maxv(x,but->pos_x + but->size_x);
		but = but->next;
	}
	LBG_PANEL* pan = LBG_PANEL_FIRST;
	while(pan)
	{
		if(pan->parent == win) x = maxv(x,pan->pos_x + pan->size_x);
		pan = pan->next;
	}
	LBG_TEXT* txt = LBG_TEXT_FIRST;
	while(txt)
	{
		if(txt->parent == win) x = maxv(x,txt->pos_x + txt->size_x);
		txt = txt->next;
	}
	LBG_CHECKBOX* cbx = LBG_CHECKBOX_FIRST;
	while(cbx)
	{
		if(cbx->parent == win) x = maxv(x,cbx->pos_x + cbx->size_x);
		cbx = cbx->next;
	}
	LBG_PROGRESSBAR* prg = LBG_PROGRESSBAR_FIRST;
	while(prg)
	{
		if(prg->parent == win) x = maxv(x,prg->pos_x + prg->size_x);
		prg = prg->next;
	}
	LBG_SLIDER* sli = LBG_SLIDER_FIRST;
	while(sli)
	{
		if(sli->parent == win) x = maxv(x,sli->pos_x + sli->size_x);
		sli = sli->next;
	}
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	while(lst)
	{
		if(lst->parent == win) x = maxv(x,lst->pos_x + lst->size_x);
		lst = lst->next;
	}
	LBG_COMBOBOX* cbx = LBG_COMBOBOX_FIRST;
	while(cbx)
	{
		if(cbx->parent == win) x = maxv(x,cbx->pos_x + cbx->size_x);
		cbx = cbx->next;
	}
	LBG_DIGITS* dgts = LBG_DIGITS_FIRST;
	while(dgts)
	{
		if(dgts->parent == win) x = maxv(x,dgts->pos_x + dgts->size_x);
		dgts = dgts->next;
	}
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	while(ebx)
	{
		if(ebx->parent == win) x = maxv(x,ebx->pos_x + ebx->size_x);
		ebx = ebx->next;
	}
	return(x);
}

var LBG_window_get_hscrollmax (LBG_WINDOW* win)
{
	return(maxv(0,LBG_window_get_ncsize_x(win) + win->scroll_bordersize_x-win->csize_x));
}


var LBG_window_get_ncsize_y (LBG_WINDOW* win)
{
	var y = win->scroll_minsize_y;
	LBG_BUTTON* but = LBG_BUTTON_FIRST;
	while(but)
	{
		if((but->parent == win) && (!((but->flags & BFi_TITLEBAR) || (but->flags & BFi_SCROLLBAR)))) y = maxv(y,but->pos_y + but->size_y);
		but = but->next;
	}
	LBG_PANEL* pan = LBG_PANEL_FIRST;
	while(pan)
	{
		if(pan->parent == win) y = maxv(y,pan->pos_y + pan->size_y);
		pan = pan->next;
	}
	LBG_TEXT* txt = LBG_TEXT_FIRST;
	while(txt)
	{
		if(txt->parent == win) y = maxv(y,txt->pos_y + txt->size_y);
		txt = txt->next;
	}
	LBG_CHECKBOX* cbx = LBG_CHECKBOX_FIRST;
	while(cbx)
	{
		if(cbx->parent == win) y = maxv(y,cbx->pos_y + cbx->size_y);
		cbx = cbx->next;
	}
	LBG_PROGRESSBAR* prg = LBG_PROGRESSBAR_FIRST;
	while(prg)
	{
		if(prg->parent == win) y = maxv(y,prg->pos_y + prg->size_y);
		prg = prg->next;
	}
	LBG_SLIDER* sli = LBG_SLIDER_FIRST;
	while(sli)
	{
		if(sli->parent == win) y = maxv(y,sli->pos_y + sli->size_y);
		sli = sli->next;
	}
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	while(lst)
	{
		if(lst->parent == win) y = maxv(y,lst->pos_y + lst->size_y);
		lst = lst->next;
	}
	LBG_COMBOBOX* cbx = LBG_COMBOBOX_FIRST;
	while(cbx)
	{
		if(cbx->parent == win) y = maxv(y,cbx->pos_y + cbx->size_y);
		cbx = cbx->next;
	}
	LBG_DIGITS* dgts = LBG_DIGITS_FIRST;
	while(dgts)
	{
		if(dgts->parent == win) y = maxv(y,dgts->pos_y + dgts->size_y);
		dgts = dgts->next;
	}
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	while(ebx)
	{
		if(ebx->parent == win) y = maxv(y,ebx->pos_y + ebx->size_y);
		ebx = ebx->next;
	}
	return(y);
}


var LBG_window_get_vscrollmax (LBG_WINDOW* win)
{
	return(maxv(0,LBG_window_get_ncsize_y(win) + win->scroll_bordersize_y-win->csize_y));
}


void LBG_window_execute (LBG_WINDOW* win, void* func)
{
	if(func != 0)
	{
		LBG_event_object = win;
		LBG_event_window = win;
		LBG_event = func;
		LBG_event();
	}
}

void LBG_update_window (LBG_WINDOW* win)
{
	LBG_window_update_pos (win);
	LBG_update_window_layer(win);
	
	ptr_remove(win->panel->bmap);
	
	
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	while(hsb)
	{
		if(hsb->target == win) hsb->scrollmax = LBG_window_get_hscrollmax(win);
		hsb = hsb->next;
	}
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == win) vsb->scrollmax = LBG_window_get_vscrollmax(win);
		vsb = vsb->next;
	}
	
	
	
	
	LBG_window_calc_csize(win);
	if(win->flags & WF_AUTOHSCROLL)
	{
		if(win->flags & WF_HSCROLLBAR)
		{
			if (LBG_window_get_ncsize_x(win) + win->scroll_bordersize_x <= win->csize_x)
			{
				win->flags &= ~WF_HSCROLLBAR;
				win->hscrollamount = 0;
				LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
				hsb = LBG_HSCROLLBAR_FIRST;
			}
		}
		else
		{
			if (LBG_window_get_ncsize_x(win) + win->scroll_bordersize_x > win->csize_x)
			{
				win->flags |= WF_HSCROLLBAR;
				LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
				hsb = LBG_HSCROLLBAR_FIRST;
			}
		}
		LBG_window_update_pos(win);
	}
	if(win->flags & WF_AUTOVSCROLL)
	{
		if(win->flags & WF_VSCROLLBAR)
		{
			if (LBG_window_get_ncsize_y(win) + win->scroll_bordersize_y <= win->csize_y)
			{
				win->flags &= ~WF_VSCROLLBAR;
				win->vscrollamount = 0;
			}
		}
		else
		{
			if (LBG_window_get_ncsize_y(win) + win->scroll_bordersize_y > win->csize_y)
			{
				win->flags |= WF_VSCROLLBAR;
			}
		}
		LBG_window_update_pos(win);
	}
	LBG_window_calc_csize(win);
	
	
	win->panel->bmap = bmap_createblack(win->size_x,win->size_y,32);
	if(!(win->flags & WFi_NOTITLEBAR)) LBG_window_border_bitmap(win->panel->bmap,win->bbmaps,win->size_x,win->size_y);
	
	if(win->ctype == 1)
	{
		ptr_remove(((PANEL*)(win->content))->bmap);
		((PANEL*)(win->content))->bmap = bmap_createblack(win->csize_x,win->csize_y,32);
		LBG_window_content_bitmap(((PANEL*)(win->content))->bmap,win->cbmaps,win->csize_x,win->csize_y);
	}
}



void LBG_set_higher_windows_down (LBG_WINDOW* win)
{
	var n = LBG_get_highest_window_layer();
	var i;
	for(i=win->layer;i<n;i++) LBG_set_windows_with_layer_to(i+1,i);
}


LBG_WINDOW* LBG_destroy_window (LBG_WINDOW* win)
{
	LBG_window_execute(win,win->Destroy);
	
	LBG_set_higher_windows_down(win);
	
	if(!(win->flags & WF_EXTERNSTRING)) ptr_remove(win->caption);
	ptr_remove(win->text);
	ptr_remove(win->panel->bmap);
	ptr_remove(win->panel);
	
	if(win->ctype == 1)
	{
		ptr_remove(((PANEL*)(win->content))->bmap);
		ptr_remove((PANEL*)win->content);
	}
	
	if (win->flags & WF_XBUTTON)
	{
		LBG_destroy_button(win->xbutton);
	}
	if (win->flags & WF_MAXBUTTON)
	{
		LBG_destroy_button(win->maxbutton);
	}
	
	
	
	
	
	LBG_WINDOW* winx = LBG_WINDOW_FIRST;
	winx = LBG_WINDOW_FIRST;
	while(winx)
	{
		if(winx->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(winx->flags & WF_DONTDESTROY))) winx = LBG_destroy_window (winx);
			else
			{
				winx->parent = 0;
				LBG_update_window(winx);
			}
		}
		else winx = winx->next;
	}
	
	LBG_BUTTON* but = LBG_BUTTON_FIRST;
	but = LBG_BUTTON_FIRST;
	while(but)
	{
		if(but->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(but->flags & BF_DONTDESTROY))) but = LBG_destroy_button (but);
			else
			{
				but->parent = 0;
				LBG_update_button(but);
			}
		}
		else but = but->next;
	}
	
	LBG_PANEL* pan = LBG_PANEL_FIRST;
	pan = LBG_PANEL_FIRST;
	while(pan)
	{
		if(pan->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(pan->flags & PF_DONTDESTROY))) pan = LBG_destroy_panel (pan);
			else
			{
				pan->parent = 0;
				LBG_update_panel(pan);
			}
		}
		else pan = pan->next;
	}
	
	LBG_TEXT* txt = LBG_TEXT_FIRST;
	txt = LBG_TEXT_FIRST;
	while(txt)
	{
		if(txt->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(txt->flags & TF_DONTDESTROY))) txt = LBG_destroy_text (txt);
			else
			{
				txt->parent = 0;
				LBG_update_text(txt);
			}
		}
		else txt = txt->next;
	}
	
	LBG_CHECKBOX* cbx = LBG_CHECKBOX_FIRST;
	cbx = LBG_CHECKBOX_FIRST;
	while(cbx)
	{
		if(cbx->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(cbx->flags & CF_DONTDESTROY))) cbx = LBG_destroy_checkbox (cbx);
			else
			{
				cbx->parent = 0;
				LBG_update_checkbox(cbx);
			}
		}
		else cbx = cbx->next;
	}
	
	LBG_INFOBOX* ifo = LBG_INFOBOX_FIRST;
	ifo = LBG_INFOBOX_FIRST;
	while(ifo)
	{
		if(ifo->target == win)
		{
			ifo = LBG_destroy_infobox (ifo);
		}
		else ifo = ifo->next;
	}
	
	LBG_PROGRESSBAR* prg = LBG_PROGRESSBAR_FIRST;
	prg = LBG_PROGRESSBAR_FIRST;
	while(prg)
	{
		if(prg->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(prg->flags & PBF_DONTDESTROY))) prg = LBG_destroy_progressbar (prg);
			else
			{
				prg->parent = 0;
				LBG_update_progressbar(prg);
			}
		}
		else prg = prg->next;
	}
	
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	hsb = LBG_HSCROLLBAR_FIRST;
	while(hsb)
	{
		if(hsb->target == win)
		{
			hsb = LBG_destroy_hscrollbar (hsb);
		}
		else hsb = hsb->next;
	}
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		if(vsb->target == win)
		{
			vsb = LBG_destroy_vscrollbar (vsb);
		}
		else vsb = vsb->next;
	}
	
	LBG_SLIDER* sli = LBG_SLIDER_FIRST;
	sli = LBG_SLIDER_FIRST;
	while(sli)
	{
		if(sli->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(sli->flags & SF_DONTDESTROY))) sli = LBG_destroy_slider (sli);
			else
			{
				sli->parent = 0;
				LBG_update_slider(sli);
			}
		}
		else sli = sli->next;
	}
	
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	lst = LBG_LISTBOX_FIRST;
	while(lst)
	{
		if(lst->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(lst->flags & LF_DONTDESTROY))) lst = LBG_destroy_listbox (lst);
			else
			{
				lst->parent = 0;
				LBG_update_listbox(lst);
			}
		}
		else lst = lst->next;
	}
	
	LBG_COMBOBOX* cbb = LBG_COMBOBOX_FIRST;
	cbb = LBG_COMBOBOX_FIRST;
	while(cbb)
	{
		if(cbb->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(cbb->flags & CF_DONTDESTROY))) cbb = LBG_destroy_combobox (cbb);
			else
			{
				cbb->parent = 0;
				LBG_update_combobox(cbb);
			}
		}
		else cbb = cbb->next;
	}
	
	LBG_DIGITS* dgts = LBG_DIGITS_FIRST;
	dgts = LBG_DIGITS_FIRST;
	while(dgts)
	{
		if(dgts->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(dgts->flags & DF_DONTDESTROY))) dgts = LBG_destroy_digits (dgts);
			else
			{
				dgts->parent = 0;
				LBG_update_digits(dgts);
			}
		}
		else dgts = dgts->next;
	}
	
	LBG_RIGHTCLICK* rcl = LBG_RIGHTCLICK_FIRST;
	rcl = LBG_RIGHTCLICK_FIRST;
	while(rcl)
	{
		if(rcl->target == win)
		{
			rcl = LBG_destroy_rightclick (rcl);
		}
		else rcl = rcl->next;
	}
	
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	ebx = LBG_EDITBOX_FIRST;
	while(ebx)
	{
		if(ebx->parent == win)
		{
			if ((!(win->flags & WF_DONTDESTROYCHILDS)) && (!(ebx->flags & EF_DONTDESTROY))) ebx = LBG_destroy_editbox (ebx);
			else
			{
				ebx->parent = 0;
				LBG_update_editbox(ebx);
			}
		}
		else ebx = ebx->next;
	}
	
	
	LBG_WINDOW* next = win->next;
	if(win->previous) win->previous->next = win->next;
	else LBG_WINDOW_FIRST = win->next;
	if(win->next) win->next->previous = win->previous;
	
	LBG_object_make_handles_invalid(win);
	free(win);
	
	
	return(next);
}



void LBG_update_textsize (LBG_WINDOW* win)
{
	win->text->size_x = win->size_x-win->tpos_x-1;
}

void LBG_maximize_window (LBG_WINDOW* win)
{
	win->bg_ver = win->pos_x;
	win->bg_hor = win->pos_y;
	win->mg_pos_x = win->size_x;
	win->mg_pos_y = win->size_y;
	
	win->flags |= WF_MAXIMIZED;
	
	win->pos_x = LBG_screenpos_x;
	win->pos_y = LBG_screenpos_y;
	
	win->size_x = LBG_screensize_x;
	win->size_y = LBG_screensize_y;
	
	((LBG_BUTTON*)(win->maxbutton))->bmap_default = win->tbmaps.bmap_res_default;
	((LBG_BUTTON*)(win->maxbutton))->bmap_over = win->tbmaps.bmap_res_over;
	((LBG_BUTTON*)(win->maxbutton))->bmap_clicked = win->tbmaps.bmap_res_clicked;
	((LBG_BUTTON*)(win->maxbutton))->bmap_active = win->tbmaps.bmap_res_default;
	((LBG_BUTTON*)(win->maxbutton))->bmap_overactive = win->tbmaps.bmap_res_over;
	((LBG_BUTTON*)(win->maxbutton))->bmap_disabled = win->tbmaps.bmap_res_default;
	
	LBG_update_window(win);
}

void LBG_restore_window (LBG_WINDOW* win)
{
	win->pos_x = win->bg_ver;
	win->pos_y = win->bg_hor;
	win->size_x = win->mg_pos_x;
	win->size_y = win->mg_pos_y;
	
	win->flags &= ~WF_MAXIMIZED;
	
	
	((LBG_BUTTON*)(win->maxbutton))->bmap_default = win->tbmaps.bmap_max_default;
	((LBG_BUTTON*)(win->maxbutton))->bmap_over = win->tbmaps.bmap_max_over;
	((LBG_BUTTON*)(win->maxbutton))->bmap_clicked = win->tbmaps.bmap_max_clicked;
	((LBG_BUTTON*)(win->maxbutton))->bmap_active = win->tbmaps.bmap_max_default;
	((LBG_BUTTON*)(win->maxbutton))->bmap_overactive = win->tbmaps.bmap_max_over;
	((LBG_BUTTON*)(win->maxbutton))->bmap_disabled = win->tbmaps.bmap_max_default;
	
	LBG_update_window(win);
}




LBG_WINDOW* LBG_manage_window (LBG_WINDOW* win)
{
	LBG_window_update_pos (win);
	LBG_update_window_layer(win);
	
	int ndbd = LBG_not_disabled_by_disableflag(win);
	
	if (!(win->flags & WF_DISABLED))
	{
		if((!(win->flags & WF_MAXIMIZED)) && (!(win->flags & WF_DONTMOVE)) && (ndbd))
		{
			if (!(key_pressed(280)))
			{
				win->flags2 &= ~WF2i_CLICK0;
				win->flags2 &= ~WF2i_CLICK1;
			}
			if ((ndbd) && LBG_mouse_over_window_move(win) && (((!(win->flags2 & WF2i_CLICK0)) && (!(win->flags2 & WF2i_CLICK1))) || ((!(win->flags2 & WF2i_CLICK0)) && ((win->flags2 & WF2i_CLICK1)))))
			{
				win->flags2 |= WF2i_OVER;
				if (key_pressed(280))
				{
					if(!((!(win->flags2 & WF2i_CLICK0)) && ((win->flags2 & WF2i_CLICK1))))
					{
						win->mg_pos_x = LBG_mouse_pos_x() - win->pos_x;
						win->mg_pos_y = LBG_mouse_pos_y() - win->pos_y;
						LBG_window_execute(win,win->Move);
					}
					
					win->flags2 &= ~WF2i_CLICK0;
					win->flags2 |= WF2i_CLICK1;
					
					LBG_window_execute(win,win->Moving);
				}
			}
			else
			{
				if(!(win->flags2 & WF2i_OVER))
				{
					win->flags2 &= ~WF2i_OVER;
				}
			}
			if ((!(win->flags2 & WF2i_CLICK0)) && ((win->flags2 & WF2i_CLICK1)))
			{
				win->pos_x = LBG_mouse_pos_x() - win->mg_pos_x;
				win->pos_y = LBG_mouse_pos_y() - win->mg_pos_y;
				
				LBG_window_update_pos(win);
			}
			if ((!(win->flags2 & WF2i_CLICK0)) && (!(win->flags2 & WF2i_CLICK1)) && (key_pressed(280)))
			{
				win->flags2 |= WF2i_CLICK0;
				win->flags2 &= ~WF2i_CLICK1;
			}
		}
		
		
		
		
		
		
		
		
		
		
		
		if ((win->flags & WF_RESIZEABLE) && (!(win->flags & WF_MAXIMIZED)) && (ndbd))
		{
			
			if (ndbd) switch(LBG_mouse_over_window_border(win))
			{
				case 1: case 8:
				if(!(win->flags & WF_LOCKSIZE_Y)) LBG_mouse_cursor = 3;
				break;
				
				case 2: case 4:
				if(!(win->flags & WF_LOCKSIZE_X)) LBG_mouse_cursor = 2;
				break;
				
				case 1|2: case 8|4:
				if(!((win->flags & WF_LOCKSIZE_X) && (win->flags & WF_LOCKSIZE_Y))) LBG_mouse_cursor = 4;
				break;
				
				case 1|4: case 8|2:
				if(!((win->flags & WF_LOCKSIZE_X) && (win->flags & WF_LOCKSIZE_Y))) LBG_mouse_cursor = 5;
				break;
			}
			
			if (!(key_pressed(280)))
			{
				win->flags2 &= ~WF2i_BRCLICK0;
				win->flags2 &= ~WF2i_BRCLICK1;
			}
			if ((ndbd) && (LBG_mouse_over_window_border(win) & 4) && (!(win->flags & WF_LOCKSIZE_X)) && (((!(win->flags2 & WF2i_BRCLICK0)) && (!(win->flags2 & WF2i_BRCLICK1))) || ((!(win->flags2 & WF2i_BRCLICK0)) && ((win->flags2 & WF2i_BRCLICK1)))))
			{
				win->flags2 |= WF2i_BROVER;
				if (key_pressed(280))
				{
					if(!((!(win->flags2 & WF2i_BRCLICK0)) && ((win->flags2 & WF2i_BRCLICK1))))
					{
						win->bg_hor = LBG_mouse_pos_x() - win->size_x;
						LBG_window_execute(win,win->Resize);
					}
					
					win->flags2 &= ~WF2i_BRCLICK0;
					win->flags2 |= WF2i_BRCLICK1;
					
					LBG_window_execute(win,win->Resizing);
				}
			}
			else
			{
				if(!(win->flags2 & WF2i_BROVER))
				{
					win->flags2 &= ~WF2i_BROVER;
				}
			}
			if ((!(win->flags2 & WF2i_BRCLICK0)) && ((win->flags2 & WF2i_BRCLICK1)))
			{
				win->size_x = LBG_mouse_pos_x() - win->bg_hor;
				if(LBG_mouse_cursor != 3) LBG_mouse_cursor = 2;
				else LBG_mouse_cursor = 4;
				
				if(win->lastsize_x != win->size_x) LBG_update_window(win);
			}
			if ((!(win->flags2 & WF2i_BRCLICK0)) && (!(win->flags2 & WF2i_BRCLICK1)) && (key_pressed(280)))
			{
				win->flags2 |= WF2i_BRCLICK0;
				win->flags2 &= ~WF2i_BRCLICK1;
			}
			
			///////////////////////////////
			
			if (!(key_pressed(280)))
			{
				win->flags2 &= ~WF2i_BBCLICK0;
				win->flags2 &= ~WF2i_BBCLICK1;
			}
			if ((ndbd) && (LBG_mouse_over_window_border(win) & 8) && (!(win->flags & WF_LOCKSIZE_Y)) && (((!(win->flags2 & WF2i_BBCLICK0)) && (!(win->flags2 & WF2i_BBCLICK1))) || ((!(win->flags2 & WF2i_BBCLICK0)) && ((win->flags2 & WF2i_BBCLICK1)))))
			{
				win->flags2 |= WF2i_BBOVER;
				if (key_pressed(280))
				{
					if(!((!(win->flags2 & WF2i_BBCLICK0)) && ((win->flags2 & WF2i_BBCLICK1))))
					{
						win->bg_ver = LBG_mouse_pos_y() - win->size_y;
						LBG_window_execute(win,win->Resize);
					}
					
					win->flags2 &= ~WF2i_BBCLICK0;
					win->flags2 |= WF2i_BBCLICK1;
					
					LBG_window_execute(win,win->Resizing);
				}
			}
			else
			{
				if(!(win->flags2 & WF2i_BBOVER))
				{
					win->flags2 &= ~WF2i_BBOVER;
				}
			}
			if ((!(win->flags2 & WF2i_BBCLICK0)) && ((win->flags2 & WF2i_BBCLICK1)))
			{
				win->size_y = LBG_mouse_pos_y() - win->bg_ver;
				if((LBG_mouse_cursor != 2) && (LBG_mouse_cursor != 4)) LBG_mouse_cursor = 3;
				else LBG_mouse_cursor = 4;
				
				if(win->lastsize_y != win->size_y) LBG_update_window(win);
			}
			if ((!(win->flags2 & WF2i_BBCLICK0)) && (!(win->flags2 & WF2i_BBCLICK1)) && (key_pressed(280)))
			{
				win->flags2 |= WF2i_BBCLICK0;
				win->flags2 &= ~WF2i_BBCLICK1;
			}
			
			///////////////////////////////
			
			if (!(key_pressed(280)))
			{
				win->flags2 &= ~WF2i_BLCLICK0;
				win->flags2 &= ~WF2i_BLCLICK1;
			}
			if ((ndbd) && (LBG_mouse_over_window_border(win) & 2) && (!(win->flags & WF_LOCKSIZE_X)) && (((!(win->flags2 & WF2i_BLCLICK0)) && (!(win->flags2 & WF2i_BLCLICK1))) || ((!(win->flags2 & WF2i_BLCLICK0)) && ((win->flags2 & WF2i_BLCLICK1)))))
			{
				win->flags2 |= WF2i_BLOVER;
				if (key_pressed(280))
				{
					if(!((!(win->flags2 & WF2i_BLCLICK0)) && ((win->flags2 & WF2i_BLCLICK1))))
					{
						win->bg_hor = LBG_mouse_pos_x() - win->pos_x;
						LBG_window_execute(win,win->Resize);
					}
					
					win->flags2 &= ~WF2i_BLCLICK0;
					win->flags2 |= WF2i_BLCLICK1;
					
					LBG_window_execute(win,win->Resizing);
				}
			}
			else
			{
				if(!(win->flags2 & WF2i_BLOVER))
				{
					win->flags2 &= ~WF2i_BLOVER;
				}
			}
			if ((!(win->flags2 & WF2i_BLCLICK0)) && ((win->flags2 & WF2i_BLCLICK1)))
			{
				win->size_x += (win->pos_x - (LBG_mouse_pos_x() - win->bg_hor));
				win->pos_x = LBG_mouse_pos_x() - win->bg_hor;
				if(LBG_mouse_cursor != 3) LBG_mouse_cursor = 2;
				else LBG_mouse_cursor = 5;
				
				if(LBG_window_correct_size(win)) win->pos_x = win->bkx;
				if(win->lastsize_x != win->size_x) LBG_update_window(win);
			}
			if ((!(win->flags2 & WF2i_BLCLICK0)) && (!(win->flags2 & WF2i_BLCLICK1)) && (key_pressed(280)))
			{
				win->flags2 |= WF2i_BLCLICK0;
				win->flags2 &= ~WF2i_BLCLICK1;
			}
		}
		
		
		
		
		
		
		
		
		
		
		if (!(key_pressed(280)))
		{
			win->flags2 &= ~WF2i_LYCLICK0;
			win->flags2 &= ~WF2i_LYCLICK1;
		}
		if ((ndbd) && (LBG_mouse_window() == win) && (((!(win->flags2 & WF2i_LYCLICK0)) && (!(win->flags2 & WF2i_LYCLICK1))) || ((!(win->flags2 & WF2i_LYCLICK0)) && ((win->flags2 & WF2i_LYCLICK1))))) // ((but_click == 0) || (but_click == 2))
		{
			win->flags2 |= WF2i_LYOVER;
			if (key_pressed(280))
			{
				win->flags2 &= ~WF2i_LYCLICK0;
				win->flags2 |= WF2i_LYCLICK1;
				
				if ((!(win->flags & WF_DONTSETTOTOP)) && (!(win->flags2 & WF2i_ASETTOTOP)))
				{
					LBG_set_window_to_top(win);
					win->flags2 |= WF2i_ASETTOTOP;
				}
			}
		}
		else
		{
			if(!(win->flags2 & WF2i_LYOVER))
			{
				win->flags2 &= ~WF2i_LYOVER;
			}
		}
		if ((!(win->flags2 & WF2i_LYCLICK0)) && (!(win->flags2 & WF2i_LYCLICK1)) && (key_pressed(280)))
		{
			win->flags2 |= WF2i_LYCLICK0;
			win->flags2 &= ~WF2i_LYCLICK1;
		}
		
		
		
	}
	
	if(!key_pressed(280)) win->flags2 &= ~WF2i_ASETTOTOP;
	
	
	LBG_update_textsize (win);
	
	
	
	win->bkx = win->pos_x;
	win->bky = win->pos_y;
	
	win->lastsize_x = win->size_x;
	win->lastsize_y = win->size_y;
	
	
	if(win->flags & WF_XBUTTON)
	{
		((LBG_BUTTON*)(win->xbutton))->pos_x = win->size_x+win->xbutton_offx;
		((LBG_BUTTON*)(win->xbutton))->pos_y = win->xbutton_offy;
		
		
		LBG_object_upate_pos(win->xbutton);
		
		if(((LBG_BUTTON*)(win->xbutton))->flags & BF_EVENT)
		{
			LBG_flags &= ~LBGUI_STOPACTION;
			LBG_window_execute(win,win->Close);
			if(!(LBG_flags & LBGUI_STOPACTION))
			{
				LBG_WINDOW* _w = win->next;
				LBG_destroy_window(win);
				return _w;
			}
		}
	}
	if(win->flags & WF_MAXBUTTON)
	{
		var _x = win->size_x+win->xbutton_offx;
		var _y = win->xbutton_offy;
		if(win->flags & WF_XBUTTON) _x -= bmap_width(win->tbmaps.bmap_max_default);
		((LBG_BUTTON*)(win->maxbutton))->pos_x = _x;
		((LBG_BUTTON*)(win->maxbutton))->pos_y = _y;
		
		LBG_object_upate_pos(win->maxbutton);
		
		if(((LBG_BUTTON*)(win->maxbutton))->flags & BF_EVENT)
		{
			LBG_flags &= ~LBGUI_STOPACTION;
			if (!(win->flags & WF_MAXIMIZED))
			{
				LBG_window_execute(win,win->Maximize);
				if(!(LBG_flags & LBGUI_STOPACTION)) LBG_maximize_window (win);
			}
			else
			{
				LBG_window_execute(win,win->Restore);
				if(!(LBG_flags & LBGUI_STOPACTION)) LBG_restore_window(win);
			}
		}
		
		
	}
	
	
	return win->next;
}








void LBG_wbmaps_destroy_2frames (LBG_WBORDER_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_WBORDER_BMAPS* LBG_wbbmaps (BMAP* bmap_titlebar_left, BMAP* bmap_titlebar_middle, BMAP* bmap_titlebar_right,
BMAP* bmap_border_left, BMAP* bmap_border_right, BMAP* bmap_border_bottomleft, BMAP* bmap_border_bottom, BMAP* bmap_border_bottomright)
{
	LBG_WBORDER_BMAPS* bmaps = malloc(sizeof(LBG_WBORDER_BMAPS));
	bmaps->bmap_titlebar_left = bmap_titlebar_left;
	bmaps->bmap_titlebar_middle = bmap_titlebar_middle;
	bmaps->bmap_titlebar_right = bmap_titlebar_right;
	bmaps->bmap_border_left = bmap_border_left;
	bmaps->bmap_border_right = bmap_border_right;
	bmaps->bmap_border_bottomleft = bmap_border_bottomleft;
	bmaps->bmap_border_bottom = bmap_border_bottom;
	bmaps->bmap_border_bottomright = bmap_border_bottomright;
	LBG_wbmaps_destroy_2frames(bmaps);
	return(bmaps);
}


void LBG_wcbmaps_destroy_2frames (LBG_CBORDER_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_CBORDER_BMAPS* LBG_wcbmaps (BMAP* bmap_topleft, BMAP* bmap_top, BMAP* bmap_topright, BMAP* bmap_left,
BMAP* bmap_right, BMAP* bmap_bottomleft, BMAP* bmap_bottom, BMAP* bmap_bottomright, BMAP* bmap_center)
{
	LBG_CBORDER_BMAPS* bmaps = malloc(sizeof(LBG_CBORDER_BMAPS));
	bmaps->bmap_topleft = bmap_topleft;
	bmaps->bmap_top = bmap_top;
	bmaps->bmap_topright = bmap_topright;
	bmaps->bmap_left = bmap_left;
	bmaps->bmap_right = bmap_right;
	bmaps->bmap_bottomleft = bmap_bottomleft;
	bmaps->bmap_bottom = bmap_bottom;
	bmaps->bmap_bottomright = bmap_bottomright;
	bmaps->bmap_center = bmap_center;
	LBG_wcbmaps_destroy_2frames(bmaps);
	return(bmaps);
}


void LBG_tbbmaps_destroy_2frames (LBG_TBUTTON_BMAPS* bmaps) // for internal use
{
	wait(2);
	free(bmaps);
}

LBG_TBUTTON_BMAPS* LBG_tbbmaps (BMAP* bmap_x_default, BMAP* bmap_x_over, BMAP* bmap_x_clicked,
BMAP* bmap_max_default, BMAP* bmap_max_over, BMAP* bmap_max_clicked,
BMAP* bmap_res_default, BMAP* bmap_res_over, BMAP* bmap_res_clicked)
{
	LBG_TBUTTON_BMAPS* bmaps = malloc(sizeof(LBG_TBUTTON_BMAPS));
	bmaps->bmap_x_default = bmap_x_default;
	bmaps->bmap_x_over = bmap_x_over;
	bmaps->bmap_x_clicked = bmap_x_clicked;
	
	bmaps->bmap_max_default = bmap_max_default;
	bmaps->bmap_max_over = bmap_max_over;
	bmaps->bmap_max_clicked = bmap_max_clicked;
	
	bmaps->bmap_res_default = bmap_res_default;
	bmaps->bmap_res_over = bmap_res_over;
	bmaps->bmap_res_clicked = bmap_res_clicked;
	LBG_tbbmaps_destroy_2frames(bmaps);
	return(bmaps);
}



int LBG_window_mouse_over_content (LBG_WINDOW* win)
{
	if (!win) return 1;
	return (LBG_mouse_pos_x() >= win->cpos_x) && (LBG_mouse_pos_x() < win->cpos_x + win->csize_x) && (LBG_mouse_pos_y() >= win->cpos_y) && (LBG_mouse_pos_y() < win->cpos_y + win->csize_y);
}



void LBG_window_add_xbutton (LBG_WINDOW* win)
{
	if(win->flags & WF_XBUTTON) return;
	win->flags |= WF_XBUTTON;
	win->xbutton = LBG_create_button(win,win->size_x+win->xbutton_offx,win->xbutton_offy,0,0,"",LBG_bbmaps(win->tbmaps.bmap_x_default,win->tbmaps.bmap_x_over,win->tbmaps.bmap_x_clicked,win->tbmaps.bmap_x_default,win->tbmaps.bmap_x_over,win->tbmaps.bmap_x_default),0,BF_SHOW | BFi_TITLEBAR);
}

void LBG_window_remove_xbutton (LBG_WINDOW* win)
{
	if(!(win->flags & WF_XBUTTON)) return;
	win->flags &= ~WF_XBUTTON;
	LBG_destroy_button(win->xbutton);
	win->xbutton = 0;
}


void LBG_window_add_maxbutton (LBG_WINDOW* win)
{
	if(win->flags & WF_MAXBUTTON) return;
	win->flags |= WF_MAXBUTTON;
	var _x = win->size_x+win->xbutton_offx;
	var _y = win->xbutton_offy;
	if(win->flags & WF_XBUTTON) _x -= bmap_width(win->tbmaps.bmap_max_default);
	win->maxbutton = LBG_create_button(win,_x,_y,0,0,"",LBG_bbmaps(win->tbmaps.bmap_max_default,win->tbmaps.bmap_max_over,win->tbmaps.bmap_max_clicked,win->tbmaps.bmap_max_default,win->tbmaps.bmap_max_over,win->tbmaps.bmap_max_default),0,BF_SHOW | BFi_TITLEBAR);
}

void LBG_window_remove_maxbutton (LBG_WINDOW* win)
{
	if(!(win->flags & WF_MAXBUTTON)) return;
	win->flags &= ~WF_MAXBUTTON;
	LBG_destroy_button(win->maxbutton);
	win->maxbutton = 0;
}

void LBG_resize_window (LBG_WINDOW* win, var size_x, var size_y)
{
	win->size_x = size_x;
	win->size_y = size_y;
	win->minsize_x = minv(win->minsize_x,win->size_x);
	win->minsize_y = minv(win->minsize_y,win->size_y);
	LBG_update_window(win);
}






LBG_WINDOW* LBG_search_disablegui ()
{
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	while(win)
	{
		if(win->flags & WF_DISABLEGUI) return win;
		win = win->next;
	}
	return 0;
}

int LBG_find_window_in_parents (LBG_WINDOW* obj,LBG_WINDOW* win)
{
	while(obj)
	{
		if(obj == win) return 1;
		obj = obj->parent;
	}
	return 0;
}



LBG_WINDOW* LBG_search_disableparent (LBG_WINDOW* obj)
{
	while((obj->stype != 1) && obj->parent) obj = obj->parent;
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	while(win)
	{
		if((win->flags & WF_DISABLEPARENT) && LBG_find_window_in_parents(win,obj)) return win;
		win = win->next;
	}
	return 0;
}

// </lbgui_windowfunc.h>
//-------------------------------------------------------------------------------------------------------




void LBGUI_open ()
{
	if(LBG_flags & LBGUI_RUNNING) return;
	LBG_flags |= LBGUI_RUNNING;
	
	LBG_WINDOW_FIRST = 0;
	LBG_BUTTON_FIRST = 0;
	LBG_PANEL_FIRST = 0;
	LBG_TEXT_FIRST = 0;
	LBG_CHECKBOX_FIRST = 0;
	LBG_INFOBOX_FIRST = 0;
	LBG_PROGRESSBAR_FIRST = 0;
	LBG_HSCROLLBAR_FIRST = 0;
	LBG_VSCROLLBAR_FIRST = 0;
	LBG_SLIDER_FIRST = 0;
	LBG_LISTBOX_FIRST = 0;
	LBG_RIGHTCLICK_FIRST = 0;
	LBG_COMBOBOX_FIRST = 0;
	LBG_DIGITS_FIRST = 0;
	LBG_EDITBOX_FIRST = 0;
	
	
	LBG_BUTTON* but = LBG_BUTTON_FIRST;
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	LBG_PANEL* pan = LBG_PANEL_FIRST;
	LBG_TEXT* txt = LBG_TEXT_FIRST;
	LBG_CHECKBOX* cbx = LBG_CHECKBOX_FIRST;
	LBG_INFOBOX* ifo = LBG_INFOBOX_FIRST;
	LBG_PROGRESSBAR* prg = LBG_PROGRESSBAR_FIRST;
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	LBG_SLIDER* sli = LBG_SLIDER_FIRST;
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	LBG_RIGHTCLICK* rcl = LBG_RIGHTCLICK_FIRST;
	LBG_COMBOBOX* cbb = LBG_COMBOBOX_FIRST;
	LBG_DIGITS* dgts = LBG_DIGITS_FIRST;
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	
	LBG_mouse_lastpos_x = mouse_pos.x;
	LBG_mouse_lastpos_y = mouse_pos.y;
	
	LBG_empty_bmap = bmap_createblack(1,1,32);
	bmap_fill(LBG_empty_bmap,nullvector,0);
	
	
	proc_mode = PROC_LATE;
	
	LBG_editbox_inchar_loop();
	
	while(1)
	{
		LBG_mouse_cursor = 0;
		
		
		
		win = LBG_WINDOW_FIRST;
		while(win)
		{
			win = LBG_manage_window(win);
		}
		hsb = LBG_HSCROLLBAR_FIRST;
		while(hsb)
		{
			hsb = LBG_manage_hscrollbar(hsb);
		}
		vsb = LBG_VSCROLLBAR_FIRST;
		while(vsb)
		{
			vsb = LBG_manage_vscrollbar(vsb);
		}
		cbb = LBG_COMBOBOX_FIRST;
		while(cbb)
		{
			cbb = LBG_manage_combobox(cbb);
		}
		but = LBG_BUTTON_FIRST;
		while(but)
		{
			but = LBG_manage_button(but);
		}
		pan = LBG_PANEL_FIRST;
		while(pan)
		{
			pan = LBG_manage_panel(pan);
		}
		txt = LBG_TEXT_FIRST;
		while(txt)
		{
			txt = LBG_manage_text(txt);
		}
		cbx = LBG_CHECKBOX_FIRST;
		while(cbx)
		{
			cbx = LBG_manage_checkbox(cbx);
		}
		ifo = LBG_INFOBOX_FIRST;
		while(ifo)
		{
			ifo = LBG_manage_infobox(ifo);
		}
		prg = LBG_PROGRESSBAR_FIRST;
		while(prg)
		{
			prg = LBG_manage_progressbar(prg);
		}
		sli = LBG_SLIDER_FIRST;
		while(sli)
		{
			sli = LBG_manage_slider(sli);
		}
		lst = LBG_LISTBOX_FIRST;
		while(lst)
		{
			lst = LBG_manage_listbox(lst);
		}
		rcl = LBG_RIGHTCLICK_FIRST;
		while(rcl)
		{
			rcl = LBG_manage_rightclick(rcl);
		}
		dgts = LBG_DIGITS_FIRST;
		while(dgts)
		{
			dgts = LBG_manage_digits(dgts);
		}
		ebx = LBG_EDITBOX_FIRST;
		while(ebx)
		{
			ebx = LBG_manage_editbox(ebx);
		}
		
		
		
		LBG_mouse_lastpos_x = mouse_pos.x;
		LBG_mouse_lastpos_y = mouse_pos.y;
		
		if(!(LBG_flags & LBGUI_RUNNING)) return;
		wait(1);
	}
}


void LBGUI_close ()
{
	LBG_flags &= ~LBGUI_RUNNING;
	
	
	proc_kill(LBGUI_open);
	proc_kill(LBG_editbox_inchar_loop);
	
	LBG_BUTTON* but = LBG_BUTTON_FIRST;
	LBG_WINDOW* win = LBG_WINDOW_FIRST;
	LBG_PANEL* pan = LBG_PANEL_FIRST;
	LBG_TEXT* txt = LBG_TEXT_FIRST;
	LBG_CHECKBOX* cbx = LBG_CHECKBOX_FIRST;
	LBG_INFOBOX* ifo = LBG_INFOBOX_FIRST;
	LBG_PROGRESSBAR* prg = LBG_PROGRESSBAR_FIRST;
	LBG_HSCROLLBAR* hsb = LBG_HSCROLLBAR_FIRST;
	LBG_VSCROLLBAR* vsb = LBG_VSCROLLBAR_FIRST;
	LBG_SLIDER* sli = LBG_SLIDER_FIRST;
	LBG_LISTBOX* lst = LBG_LISTBOX_FIRST;
	LBG_RIGHTCLICK* rcl = LBG_RIGHTCLICK_FIRST;
	LBG_COMBOBOX* cbb = LBG_COMBOBOX_FIRST;
	LBG_DIGITS* dgts = LBG_DIGITS_FIRST;
	LBG_EDITBOX* ebx = LBG_EDITBOX_FIRST;
	
	win = LBG_WINDOW_FIRST;
	while(win)
	{
		win = LBG_destroy_window(win);
	}
	hsb = LBG_HSCROLLBAR_FIRST;
	while(hsb)
	{
		hsb = LBG_destroy_hscrollbar(hsb);
	}
	vsb = LBG_VSCROLLBAR_FIRST;
	while(vsb)
	{
		vsb = LBG_destroy_vscrollbar(vsb);
	}
	cbb = LBG_COMBOBOX_FIRST;
	while(cbb)
	{
		cbb = LBG_destroy_combobox(cbb);
	}
	ebx = LBG_EDITBOX_FIRST;
	while(ebx)
	{
		ebx = LBG_destroy_editbox(ebx);
	}
	but = LBG_BUTTON_FIRST;
	while(but)
	{
		but = LBG_destroy_button(but);
	}
	pan = LBG_PANEL_FIRST;
	while(pan)
	{
		pan = LBG_destroy_panel(pan);
	}
	txt = LBG_TEXT_FIRST;
	while(txt)
	{
		txt = LBG_destroy_text(txt);
	}
	cbx = LBG_CHECKBOX_FIRST;
	while(cbx)
	{
		cbx = LBG_destroy_checkbox(cbx);
	}
	ifo = LBG_INFOBOX_FIRST;
	while(ifo)
	{
		ifo = LBG_destroy_infobox(ifo);
	}
	prg = LBG_PROGRESSBAR_FIRST;
	while(prg)
	{
		prg = LBG_destroy_progressbar(prg);
	}
	sli = LBG_SLIDER_FIRST;
	while(sli)
	{
		sli = LBG_destroy_slider(sli);
	}
	lst = LBG_LISTBOX_FIRST;
	while(lst)
	{
		lst = LBG_destroy_listbox(lst);
	}
	rcl = LBG_RIGHTCLICK_FIRST;
	while(rcl)
	{
		rcl = LBG_destroy_rightclick(rcl);
	}
	dgts = LBG_DIGITS_FIRST;
	while(dgts)
	{
		dgts = LBG_destroy_digits(dgts);
	}
	
	ptr_remove(LBG_empty_bmap);
}
#endif
