#ifndef _WINDOWS_
#define _WINDOWS_

#include "global.hh"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "misc.hh"
#include "boxes.hh"

// SWindow.flags

#define STICKY				(1L << 0)
#define HIDDEN				(1L << 1)
#define TRANSIENT			(1L << 2)
#define HIDDEN_INDEPENDENTLY		(1L << 3)// hidden independently of "transient parent"
#define SPECIALLY_PLACED		(1L << 4)
#define DoesWmTakeFocus			(1L << 5)
#define CLOSEABLE			(1L << 6)
#define WINLISTSKIP			(1L << 7)

#define DECORATIONS			(1L << 8)
#define BORDER_WD			(1L << 9)
#define PADDING_WD			(1L << 10)
#define TITLE				(1L << 11)
#define KEEPONTOP			(1L << 12)

#define MAXIMIZABLE			(1L << 13)
#define HIDE_BUTTON			(1L << 14)

// placement modes
#define WPM_current			0
#define WPM_free			1	
#define WPM_max				2
#define WPM_vmax			3
#define WPM_hmax			4
#define WPM_half_l			5
#define WPM_half_r			6
#define WPM_quad_tl			7
#define WPM_quad_tr			8
#define WPM_quad_bl			9
#define WPM_quad_br			10

struct InfoWin
{
	Window w;
	int wd, ht;

	int init ();
	int done ();
	int map ();
	int unmap ();
	int pr (const char *, ...);
};

struct WinStyle
{
	MyColor frame;
	MyColor title;
	MyColor outline;
	MyColor border;
	GC relGC;
	GC titleGC;
	GC titbkGC;
	GC borderGC;

	char *bkg_xf;
	MyPixmap *bkg;

	WinStyle ();
	int init ();
};

struct DWin: Win
{
	Time last_clicked;
	DWin ();
	int cl ();
	int handle_event ();
};

struct AWin: Box
{
	AWin () {};
	AWin (Box *);
	int ia () {};
};

struct MWM_Hints
{
	long flags;
	long functions;
	long decorations;
	long inputMode;
	long unknown;
};

struct SWM_Hints
{
	int pmode_saved;
	int x_saved;
	int y_saved;
	int wd_saved;
	int ht_saved;
};

struct SWindow
{
	SWindow *next;

	Window awin; // app window
	AWin *a; // its size & pos
	AWin *a_saved; // unmaximized one
	int abw;
	char *name; // name of the window
	char *icon_name;
	int has_net_wm_name;
	int has_net_wm_icon_name;
	char *start_cmd; // which command started the application
	int flags;

	XSizeHints hints; // "normal" (ICCM) hints
	XWMHints *wmhints; // WM hints
	MWM_Hints *mwm_hints;
	XClassHint class_hint;
	Window transient_for;

	int pmode;

	Window pager_view; // small window on pager
	int pager_view_skip; // skip so much lines when displaying name on the pager

	DWin *dwin; // decorations window
	Box *hfr, *hfl, *vft, *vfb;

	int pad_wd, border_wd;

	int gx, gy; // gravity

	int map_state;
	int unmap_events; // no. of unmap events generated by SWM

	SWindow (Window, int);
	~SWindow ();
	int get_name ();
	char* get_net_wm_name ();
	char* get_wm_name ();
	int get_icon_name ();
	char* get_net_wm_icon_name ();
	char* get_wm_icon_name ();
	//int get_command ();
	int get_wm_protocols ();
	int get_size_hints ();
	int mwm_hints_get ();
	int mwm_hints_interpret ();
	//int get_gravity ();
	int starts_hidden ();
	int place ();
	int done ();
	int withdraw ();
	int sync_to_xserver ();
	int save_hints ();
	int pager_view_update ();
	int pager_view_draw (int=0);
	int pager_view_one_line (int &, int &, int);
	int constrain_size (Box *);
	int move (int, int);
	int move_to (int, int);
	int handle_PropertyNotify ();
	int handle_ConfigureRequest ();
	int handle_EnterNotify ();
	int set_map_state (int);
	int send_message (Atom, Time);
	int center ();
	int max_toggle ();
	int stick (int &, int&, int, int, int);
	int stick_on ();
	int stick_off ();
	int stick_toggle ();
	int hide ();
	int show (int=1);
	int do_move (int=0);
	int show_pos ();
	int do_resize ();
	int wd_c ();
	int ht_c ();
	int show_size ();
	int switch_to_desk ();
	int switch_to ();
	int raise ();
	int lower ();
	int close ();
	int destroy ();
	int map_update ();
	int focus ();
	int onto_top ();
	
	int decor_build (int=WPM_current, int=false);
	int decors_toggle ();
	int query_max_flag ();
	int a_get ();
	int a_copy ();
	int style_setup ();
	int style_setup (char *);
};

struct Menu;

struct WinList
{
	SWindow *first;
	Menu *menu;
	Menu *hidden_menu;
	SWindow *focus; // window that has the input focus

	WinList ();

	int init ();
	int done ();
	int should_manage (Window);
	int add (SWindow *);
	int rm (SWindow *);
	int findw (SWindow **, Window);
	int find_dwin (SWindow **, Window);
	int find_pager_view (SWindow **, Window);
	int raise (SWindow * = NULL);
	int handle_Expose (Window);
	int handle_MapRequest ();
	int handle_FocusIn ();
	int focus_root ();
	int focus_find ();
	int focus_find_and_set ();
	int seq_switch ();
	int dsk_scrolling (int, int);
};

//********************************************************************

extern SWindow *swindow;
extern InfoWin info_window;
extern WinList win_list;
extern WinStyle dwin_style;
extern int outline_wd;

extern char *close_free_xf;
extern char *close_hover_xf;
extern char *close_down_xf;
extern char *mx_free_xf;
extern char *mx_hover_xf;
extern char *mx_down_xf;
extern char *hide_free_xf;
extern char *hide_hover_xf;
extern char *hide_down_xf;
extern char *winops_free_xf;
extern char *winops_hover_xf;
extern char *winops_down_xf;

extern int buttons_init ();

#endif
