/*-
 * Copyright (c) 2001 Jordan DeLong
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef CLIENT_H
#define CLIENT_H

/* various flags set on clients */
struct clientflags {
	u_int nofocus:1;		/* don't allow input focus */
	u_int noresize:1;		/* don't allow resizing */
	u_int nomove:1;		/* don't allow moving */
	u_int noiconify:1;	/* don't allow iconification */
	u_int nodelete:1;		/* don't allow window deletion */

	u_int zoomed:1;		/* is this window zoomed (maximized, etc) */
	u_int hzoomed:1;		/* is this window hzoomed (maximized, etc) */
	u_int vzoomed:1;		/* is this window vzoomed (maximized, etc) */
	u_int internal:1;		/* this managed window is one of ours */
	u_int transient:1;	/* this is a transient window */
	u_int shaped:1;		/* have shaped frame window */
	u_int sticky:1;		/* is this window sticky */

   u_int shaded:1;		/* is the window shaded ? */

   u_int unmap_from_reparent:1;	/* the unmap_notify we get is from reparenting */

   u_int tentatively_removed:1;	/* the map_request we get is from reparenting */
};

typedef struct double_click
{
   Time last_click_time;
   Window last_click_window;
   int last_click_button;
} double_click_t;

/* bva.
   controls how existing clients are placed by golem. Also can be
   used to start an app in a particular desktop / viewport */
typedef struct client_initial_attributes
{
   desktop_t   *desktop;
   int          viewport_x;
   int          viewport_y;
} client_initial_attributes_t;

/*
 * structure describing a managed client.  this is the place where we keep
 * all of the data relating to individually managed windows; the windows
 * may or may not be made by other X11 clients; if flags.internal it means
 * it is one of our internal windows (created by a plugin).
 */
struct client
{
   Window		window;			/* the client window */

   screen_t	   *screen;	/* screen this client is on */
   workspace_t	*workspace;		/* workspace on the screen for this client */

   client_initial_attributes_t initial_attr; /* bva */

   int		   state;			/* the window's state (X states) */
   int		   stacklayer;		/* stacking layer this client is on */

   int		x, y;			    /* geometry information */
   int		width, height;
   int		save_x, save_y;		     /* saved geometry (while zoomed, etc) */
   int		save_width, save_height;
   int		last_width, last_height; /* last width and height for hinting reshapes */
   int      speed;

   XWMHints	   *wmhints;		/* hints from the client */
   XSizeHints	normalhints;
   XClassHint	classhint;

   char		*store_name;		/* the window's name */

   Window		frame;			/* frame window (reparent of window) */
   Window		*decorwin;		/* decoration windows */

   dgroup_t	      *save_dgroup;		/* saved dgroup; used in fullscreen zoom */
   dgroup_t	      *dgroup;		    /* decoration group this client uses */
   clientflags_t  flags;			/* flags for this client */

   double_click_t doubleclick; /* For determining if a window has been double clicked */

   TAILQ_ENTRY(client)	c_stacking;	/* stacking layer list entry */
   TAILQ_ENTRY(client)	c_focus;	   /* focus list entry */
   LIST_ENTRY(client)	c_list;		/* list of all clients */
};

/*
 * accessors for size information with regard to
 * the client's dgroup.
 */
#define DWIDTH(client)		((client)->dgroup->left_space + (client)->dgroup->right_space)
#define DHEIGHT(client)		((client)->dgroup->top_space + (client)->dgroup->bottom_space)
#define FULLWIDTH(client)	(DWIDTH(client) + (client)->width)
#define FULLHEIGHT(client)	(DHEIGHT(client) + (client)->height)

typedef LIST_HEAD(, client) clientlist_t;
extern clientlist_t client_list;
extern client_t *client_focused;

void client_shutdown();
client_t *client_add(screen_t *screen, Window w,
                     clientflags_t *flags, dgroup_t *dgroup);
void client_map(client_t *client, int allowplace);
void client_rm(client_t *client);
void client_shape(client_t *client);
void client_gravitate(client_t *client);
void client_sizeframe(client_t *client);
void client_setstate(client_t *client, int state);


client_t *client_readd( client_t *client);
void client_tentatively_rm(client_t *client);


#endif
