#ifndef CODE_GADGETP_H
#define CODE_GADGETP_H

/*-----------------------------------------------------------------------
 * Xclasses header file
 * ($Id: gadget_p.h,v 1.5 2003/01/22 12:49:05 schmitzj Exp $)
 * 
 * Copyright (C) 1998 Jürgen Schmitz
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 *-----------------------------------------------------------------------
 */

#include <Xclasses/Xdisplay.h>
#include <Xclasses/gadget.h>
#include <Xclasses/Ddraw.h>
#include <Xclasses/popup.h>
#include <Xclasses/dlist.h>

// Undefined or: NotUseful, WhenMapped, Always
#define GG_BACKING_STORE	WhenMapped
//#define GG_BACKING_STORE	NotUseful

#define MAXKEY		8

class pgadget : public callable
{
	friend class group;

public:
	class gadget 	*o;
    int     		id;
    callback		fcb;
	
    Cursor  		cursor;
    int				oldcursor;

    unsigned int	mode;
    unsigned int    events;
    int     		button; 
    int     		keystate;
    unsigned long	background;
    unsigned long	foreground;
    int				keyhandlermode;

    char			key_key[MAXKEY];
    int				key_qualifier[MAXKEY];
    int				xkey_key[MAXKEY];
    int				xkey_qualifier[MAXKEY];
	short			key_count;
	short			xkey_count;

    unsigned int	locked_bak:1,
    				grabed:1,
    				blocked_bak:1,
    				blocked:1;
	struct ggs		*myg;
	unsigned long	eventmask;
	XIC				ic;
	unsigned char	buttonmap[5];
    
    class gadget 	*sendto;
    char			*helptext;
    class popup		*gpopup;

    XFontStruct 	*font;
    int				fontnr;

	class message	*msghandler;
	Atom			cutprop;

	pgadget();
	~pgadget();

    void AddGG(void);
    void RemGG(void);
    int ButtonAllowed(unsigned int &b);
    XFontStruct *dfont(void);
    void checkup(void);
	void OpenHelp(int flag=0);
	void CloseHelp(int flag=0);

    void GBPress(XEvent *myevent,class gadget*,int reason);
    void GBRelease(XEvent *myevent,class gadget*,int reason);
    int  GBMove(XEvent *myevent,class gadget*);
	int  GBActivate(XEvent *myevent,int why,class gadget*);
	int  GBSelected(XEvent *myevent,int why,int wasabove,class gadget*);
	void GBExpose(XEvent *myevent,class gadget*);
	int  GClipH(int why,char *data,int size,class gadget*);
	int  GKHandler(XEvent *,KeySym,char *,int);

    class gadget *FindReceiver(void);
    void SetVars(void);
    int  CheckVars(void);
    void ClearVars(void);
    int  SendKey(XEvent *myevent); // -1 - not active, 0 - active, >0 selected ID
    void Glock();
    void Gunlock();
    void Gblock();
    void Gunblock();
	int funccall(void);

	void GetPreferredGeometry(char *name,XRectangle *area);
	void SetGeometry(char *name,XRectangle *area);

	int allevents(XEvent *myevent);

	static int HEvent(XEvent *event,int m);
};


class helpgadget : public gadget, private Ddraw
{
public:
	char *text;
	int  pfeil;
	long col;
	
	helpgadget();
	virtual void GExpose(XEvent *);
	virtual void GSetLimits(void);
	virtual int Create(void);
};

struct fdnode
{
	node 		base;
    callback	fcb;
    int			fd;
	int			done;
    enum selectset {READFD,WRITEFD,EXCEPTFD} mode;
};
class fdlist : public dlist
{
public:
	int maxfd;
	fd_set readfd;
	fd_set writefd;
	fd_set exceptfd;

	fdlist(void) : dlist()
	{
		maxfd=0;
		FD_ZERO(&readfd);
		FD_ZERO(&writefd);
		FD_ZERO(&exceptfd);
	};
	~fdlist()
	{
		fdnode *n;
		while (n=(fdnode*)RemTail())
		{
			delete n;
		}
	};
	void addread(int fd,void *c,void* (*)(int));
	void addread(int fd,callable *c,void (callable::*f)(int));
	void addwrite(int fd,void *c,void* (*)(int));
	void addwrite(int fd,callable *c,void (callable::*f)(int));
	void addexcept(int fd,void *c,void* (*)(int));
	void addexcept(int fd,callable *c,void (callable::*f)(int));
	void remfd(int fd);
	int callback(fd_set *readset,fd_set *writeset,fd_set *exceptset);
};

struct ticknode
{
	node 		base;
    callback	fcb;
	int			delay;
	int			counter;
    enum ticktype {TOREMOVE,REGULARLY,ONCE} mode;
};
class ticklist : public dlist
{
public:

	ticklist(void) : dlist()
	{
	};
	~ticklist()
	{
		ticknode *n;
		while (n=(ticknode*)RemTail())
		{
			delete n;
		}
	};
	void addtick(callable *c,void (callable::*f)(void),int delay,enum ticknode::ticktype mode);
	void addtick(void (*f)(void),int delay,enum ticknode::ticktype mode);
	void remtick(callable *c,void (callable::*f)(void));
	void remtick(void (*f)(void));
	int callback(void);
};

#endif
