/*
 *  Source generated with GadToolsBox V1.0
 *  which is (c) Copyright 1991 Jaba Development
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include "/includes/convert.h"
#include "/includes/struct.h"
#include "/includes/tom_gadget.h"
#define	SIZE_STRING	50

extern	struct my_data	my_info;
extern	struct	appel_proc	data_proc;
int	__saveds	Gere_gadg();
extern	struct	IntuitionBase	*IntuitionBase;
extern	UBYTE	flg_debug;

/* This is for a very particular case...sorry!!! */
extern	struct List ModulesListAlea;

#define	TAILLE_CYCLE	20
#define	TAILLE_MX	8
#define	TAILLE_CHECKBOX	10
#define	SIZE_SCROLLBAR	14
#define	SIZE_SELECTION	16
int	nb_all;

#define GD_ok                                  0
#define GD_test                                1
#define GD_cancel                              2
#define GD_info                                3


struct	tom_gadget	gadg_ok    ={"_Ok"    ,BUTTON   , 20, 80, 70,12,0,0,0,0,0};
struct	tom_gadget	gadg_test  ={"_Test"  ,BUTTON   ,100, 80, 70,12,0,0,0,0,0};
struct	tom_gadget	gadg_cancel={"_Cancel",BUTTON   ,180, 80, 70,12,0,0,0,0,0};
struct	tom_gadget	gadg_info  ={"_Info"  ,BUTTON   ,260, 80, 70,12,0,0,0,0,0};

struct Screen	*Scr;
struct Gadget        *Gadgets_tom[MAX_GADGET+4];

typedef	struct	gadg_info{
	char	*p_text;
	int	Type;
	char	**labels;
	struct	List	*list;
	struct	tom_gadget	*tom_gadget;
	struct	Gadget	*p_root;
	int	value;		/* Valeur du gadget */
	int	first;		/* Premier gadget visible pour listview */
	int	nombre;		/* nombre total pour listview,cycle */
	int	nb_vue;		/* Nombre vues, pour listview */
};
int	win_size_x=10;
int	win_size_y=10;

typedef	struct	Gadget_bis{
	struct	Gadget	gadg;
	struct	gadg_info *p_info;
};



static USHORT chip selected_Data[] = 
   {
   0x0000, 0x0800,    /* ....................#........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0001, 0xd800,    /* ...............###.##........... */
   0x0003, 0x9800,    /* ..............###..##........... */
   0x0006, 0x1800,    /* .............##....##........... */
   0x0c18, 0x1800,    /* ....##.....##......##........... */
   0x0f30, 0x1800,    /* ....####..##.......##........... */
   0x01c0, 0x1800,    /* .......###.........##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x7fff, 0xf800,    /* .####################........... */

   0xffff, 0xf000,    /* ####################............ */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0x8000, 0x0000,    /* #............................... */
   };
struct Image selected_Image = { 0,0, 21,10, 2, selected_Data, 0x3,0x0, NULL };

static USHORT chip unselected_Data[] = 
   {
   0x0000, 0x0800,    /* ....................#........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x0000, 0x1800,    /* ...................##........... */
   0x7fff, 0xf800,    /* .####################........... */

   0xffff, 0xf000,    /* ####################............ */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0xc000, 0x0000,    /* ##.............................. */
   0x8000, 0x0000,    /* #............................... */
   };
struct Image unselected_Image = { 0,0, 21,10, 2, unselected_Data, 0x3,0x0, NULL };

struct NewWindow NewWindow = {
	75,85,	/* window XY origin relative to TopLeft of screen */
	150,50,	/* window width and height */
	0,1,	/* detail and block pens */
	GADGETDOWN+GADGETUP+MOUSEBUTTONS+CLOSEWINDOW+REFRESHWINDOW+VANILLAKEY+MOUSEMOVE,	/* IDCMP flags */
	WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE,	/* other window flags */
	NULL,	/* first gadget in gadget list */
	NULL,	/* custom CHECKMARK imagery */
	"Colors",	/* window title */
	NULL,	/* custom screen pointer */
	NULL,	/* custom bitmap */
	5,5,	/* minimum width and height */
	-1,-1,	/* maximum width and height */
	WBENCHSCREEN	/* destination screen type */
};

int	size_liste(struct List *l)
{
	struct Node	*n;
	int	compte;

	n=l->lh_Head;
	compte=-1;
	while(n!=0){
		compte++;
		n=n->ln_Succ;
	}
	printd("Compte liste, nombre:%d\n",compte);
	return(compte);
}
struct	Gadget	*add_one_gadget(p_gadg,num,g,Visual)
struct	tom_gadget	*p_gadg;
int	num;
struct	Gadget	*g;
APTR	Visual;
{
	struct	Gadget     *ng,*old_ng,*new_ng;
	struct	Gadget_bis	*gb;
	struct	gadg_info  *gi;
	struct	PropInfo	*pi;
	struct	StringInfo	*si;
	USHORT	dir,y;
	ULONG	value;
	char	**lab;

	ng=(struct	Gadget *)AllocMem(sizeof(struct	Gadget_bis),MEMF_CLEAR);
	gi=(struct gadg_info   *)AllocMem(sizeof(struct	gadg_info),MEMF_CLEAR);

	g->NextGadget       =    ng;
	ng->NextGadget	    =    NULL;
	ng->LeftEdge        =    p_gadg->LeftEdge+1;
	ng->TopEdge         =    p_gadg->TopEdge+1;
	ng->Width           =    p_gadg->Width-2;
	ng->Height          =    p_gadg->Height-2;
	ng->GadgetText      =    NULL;
	ng->GadgetRender    =    NULL;
	ng->Activation      =    RELVERIFY;
	ng->SelectRender    =    NULL;
	((struct Gadget_bis *)ng)->p_info=gi;
	ng->SpecialInfo     =    NULL;
	ng->Flags	    =	 GADGHCOMP;
	ng->GadgetID        =    (USHORT)num;

	gi->p_text=p_gadg->GadgetText;
	gi->Type=p_gadg->type_gadg;
	gi->tom_gadget=p_gadg;
	gi->value=p_gadg->value;
	gi->first=0;

	switch(p_gadg->type_gadg){
		case BUTTON:
			ng->GadgetType=BOOLGADGET;
			break;

		case SLIDER:
			pi=(struct PropInfo   *)AllocMem(sizeof(struct	PropInfo),MEMF_CLEAR);

			value=(p_gadg->value-p_gadg->d1)*0xFFFF/(p_gadg->d2-p_gadg->d1);
			ng->TopEdge+=1;
			ng->LeftEdge+=2;
			ng->Width-=3;
			ng->Height-=2;
			ng->SpecialInfo=pi;
			ng->GadgetType=PROPGADGET;
			ng->GadgetRender=(APTR)AllocMem(sizeof(struct Image),MEMF_CLEAR);
			dir=FREEHORIZ;
			if(ng->Width<ng->Height){
				dir=FREEVERT;
				pi->VertPot=value;
			}else{
				pi->HorizPot=value;
			}
			pi->Flags=dir|PROPBORDERLESS|AUTOKNOB;
			pi->HorizBody=0x1111;
			pi->VertBody=0x1111;
			pi->CWidth=0;
			pi->CHeight=0;
			pi->LeftBorder=0;
			pi->TopBorder=0;
			pi->HPotRes=0;
			pi->VPotRes=0;
			break;

		case CHECKBOX:
			ng->GadgetType=BOOLGADGET;
			ng->Activation|=TOGGLESELECT;
			ng->Width=TAILLE_CHECKBOX*2;
			ng->Height=TAILLE_CHECKBOX;
			ng->SelectRender=&selected_Image;
			ng->GadgetRender=&unselected_Image;
			if(gi->value==TRUE){
				ng->Flags|=(SELECTED);
			}
			ng->Flags|=(GADGIMAGE|GADGHIMAGE);
			break;
		case MX:
			ng->GadgetType=BOOLGADGET;

			gi->labels=(char **)p_gadg->p_data;
			ng->Width=TAILLE_MX*2;
			ng->Height=TAILLE_MX;
			ng->LeftEdge+=(100);
			gi->list=(struct List *)p_gadg->p_data;
			old_ng=ng;
			lab=gi->labels;
			while(*lab!=0){
				nb_all++;
				new_ng=(struct	Gadget *)AllocMem(sizeof(struct	Gadget_bis),MEMF_CLEAR);
				*((struct Gadget_bis *)new_ng)=*((struct Gadget_bis *)old_ng);
				new_ng->TopEdge+=TAILLE_MX;
				printd("Top edge:%d\n",new_ng->TopEdge);
				old_ng->NextGadget=new_ng;			
				gi->p_root=ng;
				old_ng=new_ng;
				lab++;
			}
			ng=new_ng;
			break;
		case LISTVIEW:
			ng->GadgetType=BOOLGADGET;
			ng->Height=8;
			ng->Width-=(SIZE_SCROLLBAR+3);
			y=8;
			gi->list=(struct List *)p_gadg->p_data;
			old_ng=ng;
			gi->nombre=size_liste(gi->list);
			gi->nb_vue=1;
			gi->p_root=ng;
			while(y+8+SIZE_SELECTION+2+2<p_gadg->Height){
				nb_all++;
				ng=(struct	Gadget *)AllocMem(sizeof(struct	Gadget_bis),MEMF_CLEAR);

				/* Recopie la structure de l'ancien gadget dans le nouveau */
				*((struct Gadget_bis *)ng)=*((struct Gadget_bis *)old_ng);
				ng->TopEdge+=8;
				y+=8;
				old_ng->NextGadget=ng;
				gi->nb_vue++;
				old_ng=ng;
			}
			nb_all++;
			ng=(struct	Gadget *)AllocMem(sizeof(struct	Gadget_bis),MEMF_CLEAR);
			*((struct Gadget_bis *)ng)=*((struct Gadget_bis *)old_ng);
			old_ng->NextGadget=ng;
			ng->LeftEdge        =p_gadg->LeftEdge+p_gadg->Width-SIZE_SCROLLBAR+2;
			ng->TopEdge         =p_gadg->TopEdge+1+1;
			ng->Width           =SIZE_SCROLLBAR-5;
			ng->Height          =y-2;
			ng->GadgetType=PROPGADGET;
			pi=(struct PropInfo   *)AllocMem(sizeof(struct	PropInfo),MEMF_CLEAR);
			ng->SpecialInfo=pi;
			ng->GadgetRender=(APTR)AllocMem(sizeof(struct Image),MEMF_CLEAR);
			pi->Flags=FREEVERT|PROPBORDERLESS|AUTOKNOB;
			pi->HorizBody=0x1111;
			if(gi->nb_vue>gi->nombre){
				pi->VertBody=0xffff;
			}else{
				pi->VertBody=0xffff*gi->nb_vue/gi->nombre;
				printd("VertBody:%lx\n",pi->VertBody);
			}
			pi->CWidth=0;
			pi->CHeight=0;
			pi->LeftBorder=0;
			pi->TopBorder=0;
			pi->HPotRes=0;
			pi->VPotRes=0;

			break;
		case OWN_GADGET:
			g=(struct Gadget (*)())((APTR (*)())((struct own_init *)p_gadg->p_data)->own_add)(p_gadg,g,&ng);
			break;
		case CYCLE:
			ng->GadgetType=BOOLGADGET;
			gi->labels=p_gadg->p_data;
			lab=(char **)p_gadg->p_data;
			gi->nombre=0;
			while(*lab!=0){
				gi->nombre++;
				lab++;
			}
			break;
		case	STRING:
		case	INTEGER:
			ng->GadgetType=STRGADGET;
			ng->Height=8;
			si=(struct StringInfo   *)AllocMem(sizeof(struct StringInfo),MEMF_CLEAR);
			si->Buffer=p_gadg->p_data;
			si->MaxChars=p_gadg->d1;
			if(p_gadg->type_gadg==STRING){
				strcpy(si->Buffer,p_gadg->p_data);
			}else{
				ng->Activation|=LONGINT;
				si->Buffer=AllocMem(p_gadg->d1+1,MEMF_CLEAR);
				sprintf(si->Buffer,"%d",p_gadg->value);
			}
			ng->SpecialInfo=si;
			break;
	}
	nb_all++;
	return(ng);

}

struct	Gadget	*CreateContext(struct	Gadget	**glist)
{
	*glist=(struct Gadget *)AllocMem(sizeof(struct	Gadget_bis ),MEMF_CLEAR);
	(*glist)->NextGadget=NULL;
	nb_all++;
	return(*glist);
}

void	FreeGadgets(struct	Gadget	*glist)
{
	struct	Gadget	*n;
	struct	Gadget_bis	*gb;
	struct	gadg_info	*old_info;

	printd("freegadget\n");
	printd("J'en avais allouer :%d\n",nb_all);
	old_info=0;
	while(glist!=NULL){
	    n=glist->NextGadget;

	    if((glist->GadgetType&SYSGADGET)==0){

		if(old_info==0){
			old_info=((struct Gadget_bis *)glist)->p_info;
		}
		if(glist->SpecialInfo!=0){
			if(glist->GadgetType==PROPGADGET){
				FreeMem(glist->SpecialInfo,sizeof(struct PropInfo));
				FreeMem(glist->GadgetRender,sizeof(struct Image));
			}else if(glist->GadgetType==STRGADGET){
				if((glist->Activation&LONGINT)!=0){
					printd("Je libere une chaine\n");
					FreeMem(((struct StringInfo *)glist->SpecialInfo)->Buffer,
						((struct StringInfo *)glist->SpecialInfo)->MaxChars+1);
				}
				FreeMem(glist->SpecialInfo,sizeof(struct StringInfo));
			}
		}
		gb=(struct Gadget_bis *)glist;
		if(gb->p_info!=old_info){
			FreeMem((APTR)old_info,sizeof(struct gadg_info));
			old_info=gb->p_info;
		}
		FreeMem(gb,sizeof(struct Gadget_bis ));
		nb_all--;
	    }
	    glist=n;
	}
	if(old_info!=0){
		FreeMem((APTR)old_info,sizeof(struct gadg_info));
	}
	printd("Il en reste:%d\n",nb_all);
}

void	aff_texte_under(struct RastPort *rp,int x,int y,char *p_text)
{
	int	i;
	x+=4;
	y+=4;
	SetAPen(rp,1);
	SetDrMd(rp,JAM1);
	i=0;
	Move(rp,x,y);
	while(p_text[i]!=0){
		if(p_text[i]=='_'){
			Text(rp,p_text,i+1);
			p_text=&p_text[i+1];
			x+=i*8;
			i=0;
		}else{
			i++;
		}
	}
	Move(rp,x,y);
	Text(rp,p_text,i);
}
void	aff_texte(struct RastPort *rp,int x,int y,char *p_text,int taille)
{
	int	i,len;
	x+=4;
	y+=4;
	SetAPen(rp,1);
	SetDrMd(rp,JAM2);
	i=0;
	Move(rp,x,y);
	len=strlen(p_text);
	Text(rp,p_text,len);
	SetAPen(rp,0);
	y+=1;
	RectFill(rp,x+len*8,y-7,x+taille,y);
}

void	aff_box(struct RastPort *rp,int	x1,int	y1,int	x2,int	y2)
{
	
	SetAPen(rp,1);
	Move(rp,x1,y2);
	Draw(rp,x1,y1);
	Move(rp,x1-1,y2);
	Draw(rp,x1-1,y1);

	Draw(rp,x2,y1);
	SetAPen(rp,2);
	Draw(rp,x2,y2);
	Move(rp,x2+1,y1);
	Draw(rp,x2+1,y2);

	Draw(rp,x1,y2);
}

void	tom_RefreshGadget(struct Window *Wnd,struct Gadget *g)
{
	struct	gadg_info	*gi;
	struct	RastPort	*rp;
	char	**p_t;
	struct	Node	*node;
	int	x1,y1,x2,y2,taille;
	char	buffer[4];
	int	i,dir,px,py,n;

	rp=Wnd->RPort;
    if(((g->GadgetType)&SYSGADGET)==0){
	x1=g->LeftEdge-1;
	y1=g->TopEdge-1;
	x2=x1+g->Width+1;
	y2=y1+g->Height+1;
	
	gi=((struct Gadget_bis *)g)->p_info;
	switch(gi->Type){
		case BUTTON:
			aff_box(rp,x1,y1,x2,y2);
			taille=8*strlen(gi->p_text);
			aff_texte_under(rp,x1+(g->Width-taille)/2,y1+(g->Height-8)/2+3,gi->p_text);
			break;
		case SLIDER:
			x1-=2;
			x2+=4;
			y1-=1;
			y2+=2;

			if( (((struct PropInfo *)g->SpecialInfo)->Flags & FREEVERT) !=0){
				printd("Free vert!\n");
				dir=FREEVERT;
				px=x1-8*strlen(gi->p_text);
				py=(y1+y2)/2-6;
			}else{
				printd("Free horiz!\n");
				dir=FREEHORIZ;
				px=x1-8*strlen(gi->p_text)-8;
				py=y1+3;
			}
			aff_box(rp,x1,y1,x2,y2);
			aff_texte_under(rp,px,py,gi->p_text);
			sprintf(buffer,"%03d",gi->value);
			printd("Slider, value:%s\n",buffer);
			SetAPen(rp,1);
			SetDrMd(rp,JAM2);
			if(dir==FREEVERT){
				Move(rp,x1-4,y2+10);
			}else{
				Move(rp,x2+4,y1+6);
			}
			Text(rp,buffer,3);
			break;
		case CHECKBOX:
			aff_texte_under(rp,x1-8*strlen(gi->p_text),y1+4,gi->p_text);
			break;
		case LISTVIEW:
			if(gi->p_root==g){
				y2=y1+gi->nb_vue*8+1;
				aff_box(rp,x1,y1,x2,y2);
				aff_box(rp,x1,y2+1,x2+SIZE_SCROLLBAR+4,y2+SIZE_SELECTION);
				aff_box(rp,x2+3,y1,x2+SIZE_SCROLLBAR+4,y2);
				node=gi->list->lh_Head;
				y1+=3;
				n=0;
				while((node!=NULL)&&(y1<y2)){
					if(n>=gi->first){
						aff_texte(rp,x1,y1,node->ln_Name,x2-x1-8);
						y1+=8;
					}
					node=node->ln_Succ;
					n++;
				}
				/* Affichage de la seleciton courante */
				node=gi->list->lh_Head;
				n=0;
				while((node->ln_Succ!=NULL)&&(n!=gi->value)){
					node=node->ln_Succ;
					n++;
				}
				aff_texte(rp,x1,y2+6,node->ln_Name,x2-x1+SIZE_SCROLLBAR-8);
			}
			break;
		case CYCLE:
			SetAPen(rp,0);
			RectFill(rp,x1,y1,x2,y2);
			aff_box(rp,x1,y1,x2,y2);
			SetAPen(rp,2);
			Move(rp,x1+TAILLE_CYCLE,y1+2);
			Draw(rp,x1+TAILLE_CYCLE,y2-2);
			aff_texte_under(rp,x1-8*strlen(gi->p_text),y1+4,gi->p_text);
			p_t=gi->labels;
			aff_texte(rp,x1+TAILLE_CYCLE+4,y1+4,p_t[gi->value],x2-x1-TAILLE_CYCLE-8);
			break;
		case STRING:
		case INTEGER:
			aff_box(rp,x1,y1,x2,y2);
			aff_texte_under(rp,x1-8*strlen(gi->p_text),y1+4,gi->p_text);
			break;
		case MX:
			if(gi->p_root==g){
				x1=gi->tom_gadget->LeftEdge;
				aff_texte_under(rp,x1-8*strlen(gi->p_text),y1+4,gi->p_text);
				p_t=gi->labels;
				i=0;
				printd("gi->value:%d\n",gi->value);
				while(*p_t!=NULL){
					if(gi->value==i){
						SetAPen(rp,3);
					}else{
						SetAPen(rp,0);
					}
					RectFill(rp,x2-TAILLE_MX*2+4,y1+1,x2-4,y1+TAILLE_MX-2);
					aff_texte(rp,x1+5,y1+2,*p_t,x2-x1-25);
					aff_box(rp,x2-TAILLE_MX*2+2,y1+1,x2-2,y1+TAILLE_MX-1);
					p_t++;
					i++;
					y1+=TAILLE_MX;
				}
			}
			break;
	}
    }
}
void	tom_RefreshWindow(struct Window *Wnd,int dummy )
{
	struct	Gadget_bis	*g;
	struct	gadg_info	*old_gadg;

	g=(struct Gadget_bis *)Wnd->FirstGadget;

	old_gadg=0;
	while(g!=NULL){
	    if(g->p_info!=old_gadg){
		    tom_RefreshGadget(Wnd,&g->gadg);
		    old_gadg=g->p_info;
	    }

	    g=(struct Gadget_bis *)g->gadg.NextGadget;
	}

}

struct IntuiMessage *tom_GetMsg(struct MsgPort *UserPort)
{
	struct	IntuiMessage	*msg;
	struct	PropInfo	*pi;
	struct	gadg_info	*gi;
	struct	tom_gadget	*tg;
	struct	Gadget		*gd,*root;
	int	value;

 	msg=(struct IntuiMessage *)GetMsg(UserPort);
	if(msg!=NULL){
		gd=(struct  Gadget *)msg->IAddress;

		if((msg->Class==GADGETDOWN)||(msg->Class==GADGETUP)){
			gi=((struct  Gadget_bis *)gd)->p_info;
			tg=gi->tom_gadget;

			printd("Type:%d\n",gi->Type);
			switch(gi->Type){
				case BUTTON:
					break;
				case SLIDER:
					pi=(struct PropInfo *)gd->SpecialInfo;
					if((pi->Flags)&FREEHORIZ){
						value=(int)pi->HorizPot;
					}else{
						value=(int)pi->VertPot;
					}
					value=(value)*(tg->d2-tg->d1)/0xFFFF+tg->d1;
					msg->Code=value;
					gi->value=value;
					tom_RefreshGadget(msg->IDCMPWindow,gd);
					break;
				case CHECKBOX:
					
					break;
				case LISTVIEW:
					root=gi->p_root;
					if(gd->GadgetType==BOOLGADGET){
						msg->Code=(msg->MouseY-root->TopEdge)/8+gi->first;
						gi->value=msg->Code;

						/* We treat the very particular case */
						/* of the listview of the random     */
						/* gadget			     */

						if(gi->list==&ModulesListAlea){
							press_gadg(gd,msg->Code,0);
						}

					}else if(gd->GadgetType==PROPGADGET){
						pi=(struct PropInfo *)gd->SpecialInfo;
						value=(int)pi->VertPot;
						value=(value)*(gi->nombre-gi->nb_vue)/0xFFFF;
						gi->first=value;
						msg->Code=gi->value;
					}
/*					tom_RefreshGadget(msg->IDCMPWindow,gd);*/
					tom_RefreshGadget(msg->IDCMPWindow,root);
					break;
				case CYCLE:
					gi->value=(gi->value+1)%(gi->nombre);
					tom_RefreshGadget(msg->IDCMPWindow,gd);
					break;
				case STRING:
				case INTEGER:
					tom_RefreshGadget(msg->IDCMPWindow,gd);
					break;
				case MX:
					root=gi->p_root;
					msg->Code=(msg->MouseY-root->TopEdge)/8;
					gi->value=msg->Code;
					tom_RefreshGadget(msg->IDCMPWindow,root);
					break;
			}
		}
	}
	return(msg);
}

/************************************************************************/
/* Fonction qui cree la liste des gadgets, dans le tableau Gadgets_gadg */
/************************************************************************/

InitStuff_gadg(pc,flg_bas)
struct	contexe	*pc;
int	flg_bas;
{
    struct Gadget       *g;
    struct	tom_gadget	*p_gadg;
    int	i,max_x,max_y;

    Scr = IntuitionBase->FirstScreen;
    while((Scr!=NULL)&&((Scr->Flags&SCREENTYPE)!=WBENCHSCREEN)){
	Scr=Scr->NextScreen;
    }
    if(Scr==NULL){
	Scr = IntuitionBase->FirstScreen;
    }
    p_gadg=pc->t_g;

    if ( NOT( g = CreateContext( &pc->GList )))
        return( 3l );

    i=0;
    max_x=win_size_x;
    max_y=win_size_y;
    while(p_gadg[i].type_gadg!=END_LISTE){
	if(p_gadg[i].LeftEdge+p_gadg[i].Width>max_x){
		max_x=p_gadg[i].LeftEdge+p_gadg[i].Width;
	}
	if(p_gadg[i].TopEdge+p_gadg[i].Height>max_y){
		max_y=p_gadg[i].TopEdge+p_gadg[i].Height;
	}
/*
	printf("[%d]: leftedge:%d topedge:%d width:%d height:%d maxx:%d maxy:%d\n",i,
			p_gadg[i].LeftEdge,
			p_gadg[i].TopEdge,
			p_gadg[i].Width,
			p_gadg[i].Height,
			max_x,max_y);
*/
	i++;
    }
    max_y+=10;
    max_x+=30;
    if(flg_bas==FALSE){
	    gadg_ok.TopEdge=max_y;
	    gadg_test.TopEdge=max_y;
	    gadg_cancel.TopEdge=max_y;
	    gadg_info.TopEdge=max_y;
	    max_y+=gadg_ok.Height+10;
	    if(max_x<gadg_info.Width+gadg_info.LeftEdge){
		 max_x=gadg_info.Width+gadg_info.LeftEdge+10;
	    }
    }
    
    if(max_x>Scr->Width)max_x=Scr->Width;
    if(max_x+NewWindow.Width>Scr->Width){
		NewWindow.Width=Scr->Width-max_x;
    }
    if(max_y>Scr->Height)max_y=Scr->Height;
    if(max_y+NewWindow.Height>Scr->Height){
		NewWindow.Height=Scr->Height-max_y;
    }
    NewWindow.LeftEdge=(Scr->Width -max_x)/2;
    NewWindow.TopEdge=(Scr->Height-max_y)/2;
    NewWindow.Width=max_x;
    NewWindow.Height=max_y;

    if(flg_bas==FALSE){
	    g =add_one_gadget(&gadg_ok,GD_ok,g);
	    Gadgets_tom[ GD_ok    ]=g;
	    g =add_one_gadget(&gadg_test,GD_test,g);
	    Gadgets_tom[ GD_test  ]=g;
	    g =add_one_gadget(&gadg_cancel,GD_cancel,g);
	    Gadgets_tom[ GD_cancel]=g;
	    g =add_one_gadget(&gadg_info,GD_info,g);
	    Gadgets_tom[ GD_info  ]=g;
    }

    i=0;
    while(p_gadg[i].type_gadg!=END_LISTE){

	g=add_one_gadget(&p_gadg[i],i+GD_info+1,g);
	Gadgets_tom[ i+GD_info+1 ] = g;

	if ( NOT g ){
		printf("ERREUR creation gadget\n");
	        return( 4l );
	}
	i++;
	if(i==MAX_GADGET){
		printf("Erreur,maximum de gadgets atteint!\n");
	}
    }

    NewWindow.FirstGadget = pc->GList->NextGadget;
    NewWindow.Title = pc->p_name;

    if ( NOT( pc->Wnd = OpenWindow(&NewWindow)))
        return( 5l );
    tom_RefreshWindow( pc->Wnd, 0l );
/*
    GT_RefreshWindow( pc->Wnd, 0l );
*/
    return( 0l );
}

/************************************************** cleanstuff */

void CleanStuff_gadg(pc)
struct	contexe	*pc;
{
    int	i;
    struct	tom_gadget	*p_gadg;

    p_gadg=pc->t_g;
	i=0;
    while(p_gadg[i].type_gadg!=END_LISTE){
	if(p_gadg[i].type_gadg==OWN_GADGET){
		(void (*)())((APTR (*)())((struct own_init *)p_gadg[i].p_data)->own_end)();
	}
	i++;
    }


    if ( pc->Wnd        ){
        CloseWindow( pc->Wnd);
	pc->Wnd=0;
	}
    if ( pc->GList  )
        FreeGadgets( pc->GList );

}

/************************************************** affiche_texte */

void	affiche_texte(char	*p_t,struct contexe *p_c,int flg_auto_remove)
{
	struct	IntuiMessage *msg;
	int	x,y,n,n_max,y_max;
	struct	RastPort	*rp;
	char	buffer[80],*save_pt;
	struct	contexe	my_ctx;
	static	struct	tom_gadget	my_gadg[]={
		{"_Ok",		BUTTON	, 30,100, 200,12,0,0,0,0,0},
		{0,		END_LISTE,  0,  0,  0, 0, 0,0,0,0,0}};

	my_info.flg_send=0;
	if(p_t!=NULL){

		/* Recherche de la taille du texte en x et y, pour pouvoir */
		/* ouvrir une fenetre de la taille desiree		   */

		save_pt=p_t;
		n_max=0;y_max=0;
		n=0;
		do{
			if((*p_t!='\n')&&(*p_t!=0)){
				n++;
			}else{
				if( n_max<n ){
					n_max=n;
				}
				n=0;
				y_max++;
			}
			p_t++;
		}while(*(p_t-1)!=0);
		my_gadg[0].Width=n_max*8;
		my_gadg[0].TopEdge=30+y_max*8;

		if(flg_auto_remove==TRUE){
			my_gadg[0].type_gadg=END_LISTE;
			win_size_x=my_gadg[0].Width;
			win_size_y=my_gadg[0].TopEdge;
		}else{
			my_gadg[0].type_gadg=BUTTON;
		}

		my_ctx.t_g=my_gadg;
		my_ctx.GList=0;
		my_ctx.p_name="Information...";


		/* Open the window and create the gadgets */
		InitStuff_gadg(&my_ctx,TRUE);

		/* Display the information text		  */
		rp=my_ctx.Wnd->RPort;
		x=10;y=30;
		n=0;
		p_t=save_pt;
		SetAPen(rp,1);
		do{
			if((*p_t!='\n')&&(*p_t!=0)){
				buffer[n]=*p_t;
				n++;
			}else{
				Move(rp,x,y);
				Text(rp,buffer,n);
				x=10;y+=8;n=0;
			}
			p_t++;
		}while(*(p_t-1)!=0);

		if(flg_auto_remove==FALSE){
			/* Wait for an action. Any action will close the window!	*/
			WaitPort(my_ctx.Wnd->UserPort);
	     		while((msg=(struct IntuiMessage *)GetMsg(my_ctx.Wnd->UserPort))!=0){
				ReplyMsg(msg);
			}
		}else{
			Delay(100);
		}
		CleanStuff_gadg(&my_ctx);
	}
	my_info.flg_send=1;
}


/************************************************** handle event */

void	handle_event_gadg(pg,code,pc)
struct	Gadget	*pg;
int	code;
struct	contexe	*pc;
{
	int	id;
	struct	tom_gadget	*p_t;
	
	id=pg->GadgetID;
	if(id<=GD_info){
		switch(id){
			case	GD_info:
				affiche_texte(data_proc.p_texte,pc,FALSE);
				break;
			case	GD_ok:
				pc->flg_save=TRUE;
			case	GD_cancel:
				pc->flg_end=TRUE;
				break;
			case	GD_test:
				my_info.flg_send=1;
				my_info.flg_stop=0;
				big_blank();
				my_info.flg_send=1;
				break;
			default:
				break;
		}
	}else{
	   p_t=&pc->t_g[id-GD_info-1];
	   switch(p_t->type_gadg){
		case	BUTTON:
			printd("C'etait un boutton\n");
			if(p_t->p_data!=0){
				printd("J'appelle la fct!\n");
/*				pc->flg_end=(int (*)())((APTR (*)())p_t->p_data)(pg,p_t,pc);
*/
				pc->flg_end=((int (*)())p_t->p_data)(pg,p_t,pc);
			}
			break;
		case	LISTVIEW:
			printd("Listview,Value:%d\n",code);
		case	CYCLE:
			printd("Value:%d\n",code);
			p_t->value=code;
			break;
		case	STRING:
			printd("String\n");
			break;
		case	INTEGER:
			p_t->value=(p_t->p_data,((struct StringInfo *)(pg->SpecialInfo))->LongInt);
			printd("Integer:%d\n",p_t->value);
			break;
		case	CHECKBOX:
			if((pg->Flags&SELECTED)==0){
				p_t->value=FALSE;
			}else{
				p_t->value=TRUE;
			}
			printd("C'etait une checkbox,value:%d\n",p_t->value);
			break;
		case	SLIDER:
			printd("C'etait un slider,valeur:%d!\n",code);
			p_t->value=code;
			if(p_t->p_data!=NULL){
				*((int *)(p_t->p_data))=code;
			}
			break;
		case	MX:
			printd("C'etait un mx,choix:%d\n",code);
			p_t->value=code;
			break;
		case	OWN_GADGET:
			(void (*)())((APTR (*)())((struct own_init *)p_t->p_data)->own_press)(pg,code,pc->Wnd);
			break;
	    }
	}
}

/************************************************** change state */

void	change_state(pg,code,pc)
struct	Gadget	*pg;
int	code;
struct	contexe	*pc;
{
	if((pg->Flags&SELECTED)==0){
		pg->Flags|=SELECTED;
	}else{
		pg->Flags&=~SELECTED;
	}
	RefreshGadgets(pg,pc->Wnd,NULL);
	tom_RefreshWindow( pc->Wnd, 0l );
/*	GT_RefreshWindow( pc->Wnd, 0l );
*/
	handle_event_gadg(pg,code,pc);
}
void	test_bornes(struct	tom_gadget	*p_liste)
{
	if(p_liste->value<p_liste->d1){
		p_liste->value=p_liste->d2;
	}
	if(p_liste->value>p_liste->d2){
		p_liste->value=p_liste->d1;
	}
}

/************************************************** find raccourcis */

void	find_raccourcis(code,pc)
int	code;
struct	contexe	*pc;
{
	USHORT	i;
	short	dir,flg_found;
	struct	tom_gadget	*p_liste;
	char	*p_text;

	p_liste=pc->t_g;
	i=0;
	dir=1;
	flg_found=FALSE;
	while((p_liste->type_gadg!=END_LISTE)&&(flg_found==FALSE)){
		p_text=p_liste->GadgetText;
		while(*p_text!=0){
			if((*p_text=='_')&&(tolower(*(p_text+1))==tolower(code))){
				flg_found=TRUE;
				if(isupper(code)){
					dir=-1;
				}
			}
			p_text++;
		}
		if(flg_found==TRUE){
			switch(p_liste->type_gadg){

				case	OWN_GADGET:
				case	BUTTON:
/*
					ActivateGadget(Gadgets_tom[i+GD_info+1],pc->Wnd,NULL);
*/
					handle_event_gadg(Gadgets_tom[i+GD_info+1],code,pc);
					break;
				case	CHECKBOX:
					change_state(Gadgets_tom[i+GD_info+1],code,pc);
					break;
				case	SLIDER:
					p_liste->value+=dir;
					test_bornes(p_liste);
/*
					GT_SetGadgetAttrs (Gadgets_tom[i+GD_info+1],pc->Wnd,
						NULL,GTSL_Level,(p_liste->value)%(p_liste->d2),TAG_DONE);
*/
					break;
				case	MX:
					p_liste->value+=dir;
					test_bornes(p_liste);
/*
					GT_SetGadgetAttrs (Gadgets_tom[i+GD_info+1],pc->Wnd,
                        		     NULL,GTMX_Active,(p_liste->value),TAG_DONE);
*/
					break;
				case	CYCLE:
					p_liste->value+=dir;
					test_bornes(p_liste);
/*
					GT_SetGadgetAttrs (Gadgets_tom[i+GD_info+1],pc->Wnd,
                        		     NULL,GTCY_Active,(p_liste->value),TAG_DONE);
*/
					break;
				case	LISTVIEW:
					p_liste->value+=dir;
					test_bornes(p_liste);
/*
					GT_SetGadgetAttrs (Gadgets_tom[i+GD_info+1],pc->Wnd,
                        		     NULL,GTLV_Selected,(p_liste->value),GTLV_Top,p_liste->value,TAG_DONE);
*/
					break;
			}
		}
		p_liste++;
		i++;
	}
}

/************************************************** main_gadg */

void main_gadg(pc)
struct	contexe	*pc;
{
	struct	IntuiMessage *msg;
	int	class,code;
	APTR	IAdress;

	pc->flg_end=FALSE;

	do{
	   WaitPort(pc->Wnd->UserPort);
	     while((msg=(struct IntuiMessage *)tom_GetMsg(pc->Wnd->UserPort))!=0){
		class=msg->Class;
		code=msg->Code;
		IAdress=msg->IAddress;
		ReplyMsg((struct Message *)msg);
		switch(class){
			case	CLOSEWINDOW:
				pc->flg_end=TRUE;
				break;
			case	VANILLAKEY:
				switch(code){
					case 'o':
						pc->flg_end=TRUE;
						pc->flg_save=TRUE;
						break;
					case 'c':
					case 27:		/* escape */
						pc->flg_end=TRUE;
						break;
					case 't':
						handle_event_gadg(Gadgets_tom[GD_test],code,pc);
						break;
					case 'i':
						handle_event_gadg(Gadgets_tom[GD_info],code,pc);
						break;
					default:
						find_raccourcis(code,pc);
						break;
				}
				break;

			case	GADGETDOWN:
			case	GADGETUP:
				handle_event_gadg(IAdress,code,pc);
				break;
			case	REFRESHWINDOW:
				printd("Refresh window\n");
				tom_RefreshWindow( pc->Wnd, 0l );
/*
				RefreshWindow( pc->Wnd, 0l );
*/
				break;

			default:
				break;
		}
	     }
	}while(pc->flg_end==FALSE);
}


int __saveds Gere_gadg(struct tom_gadget *p_gadg,char	*p_name)
{
	struct	contexe	ctx;
	
	ctx.t_g=p_gadg;
	ctx.GList=0;
	ctx.p_name=p_name;
	ctx.flg_save=FALSE;
	InitStuff_gadg(&ctx,FALSE);
	main_gadg(&ctx,FALSE);	
	CleanStuff_gadg(&ctx);
	return(ctx.flg_save);
}
