/*
 *
 *  AM --- AmigaMail
 *  (C) 1991, 1992 by Christian Riede
 *
 *  AM is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY.  No author or distributor accepts responsibility to anyone
 *  for the consequences of using it or for whether it serves any
 *  particular purpose or works at all, unless he says so in writing.
 *  Refer to the GNU General Public License, Version 1, for full details.
 *  
 *  Everyone is granted permission to copy, modify and redistribute AM,
 *  but only under the conditions described in the GNU General Public
 *  License, Version 1.  A copy of this license is supposed to have been 
 *  given to you along with AM so you can know your rights and responsi-
 *  bilities.  It should be in a file named COPYING.  Among other things,
 *  the copyright notice and this notice must be preserved on all copies.
 *
 *  
 *
 */


#include "am.h"

#define EDIT_HEIGHT (8*(TextAttr.ta_YSize+6)+10)

#define NEXT      1
#define PREVIOUS  2
#define AB_SORT   3
#define FIND      4
#define CLEAR     5
#define ADD       6
#define UPDATE    7
#define DELETE    8
#define USERNAME  9
#define REALNAME 10
#define REPLYTO  11
#define CTE_     13

#define DEFAULT_CTE CTE_7BIT

void EditAddressBook(void)
{
	int run,w,ActualCTE=DEFAULT_CTE;
	struct IntuiMessage *Msg;
	ULONG Class;
	ULONG Code;
	APTR IAddr;
	struct Address *Address=0,*StartAddress,*Scan;
	struct List Addressbook,Display,Sort;
	struct Window *EditABWindow;
	struct Gadget *GList,*gad;
	struct Gadget *CTEGad,*RealnameGad,*UsernameGad,*ReplyToGad;
	struct Gadget *ActiveGadget;
	char MyUsername[MAIL_FIELDLENGTH];
	char MyRealname[MAIL_FIELDLENGTH];
	int found;
	BPTR ABLock;

	struct NewGadget NextGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Next",&TextAttr,
		NEXT,
		PLACETEXT_IN,
		0,	
		0
	};
	
	struct NewGadget PreviousGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Previous",&TextAttr,
		PREVIOUS,
		PLACETEXT_IN,
		0,	
		0
	};
	
	struct NewGadget SortGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Sort",&TextAttr,
		AB_SORT,
		PLACETEXT_IN,
		0,	
		0
	};
	
	struct NewGadget FindGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Find",&TextAttr,
		FIND,
		PLACETEXT_IN,
		0,	
		0
	};

	struct NewGadget ClearGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Clear",&TextAttr,
		CLEAR,
		PLACETEXT_IN,
		0,	
		0
	};

	struct NewGadget ABAddGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Add",&TextAttr,
		ADD,
		PLACETEXT_IN,
		0,	
		0
	};
	
	struct NewGadget UpdateGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Update",&TextAttr,
		UPDATE,
		PLACETEXT_IN,
		0,	
		0
	};

	struct NewGadget DelGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Delete",&TextAttr,
		DELETE,
		PLACETEXT_IN,
		0,	
		0
	};
	
	struct NewGadget UGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Username:",&TextAttr,
		USERNAME,
		PLACETEXT_LEFT,
		0,	
		0
	};
	
	struct NewGadget RGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Realname:",&TextAttr,
		REALNAME,
		PLACETEXT_LEFT,
		0,	
		0
	};

	struct NewGadget ReplyToGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Reply-To:",&TextAttr,
		REPLYTO,
		PLACETEXT_LEFT,
		0,	
		0
	};
	
	struct NewGadget CTEGadget = 
	{
		0,0,0,0,
		(UBYTE *)"Contents-Type-Encoding:",&TextAttr,
		CTE_,
		PLACETEXT_LEFT,
		0,	
		0
	};
	
	
	if (Screen) /* custom screen requested */
	{
		if (!(EditABWindow = OpenWindowTags(0,
			WA_CustomScreen,Screen,
			WA_Left,ABLeft,
			WA_Top,ABTop,
			WA_Width,ABWidth,
			WA_Height,EDIT_HEIGHT,
			WA_MinWidth,640L,
			WA_MinHeight,180L,
			WA_MaxWidth,1024L,
			WA_MaxHeight,1024L,
			WA_DragBar,TRUE,
			WA_DepthGadget,TRUE,
			WA_CloseGadget,TRUE,
			WA_Activate,TRUE,
			WA_SmartRefresh,TRUE,
			WA_GimmeZeroZero,TRUE,
			WA_Title,"Edit Addressbook",
			WA_RMBTrap,TRUE,
			TAG_END)))
		{
			SimpleRequest(Window,"Can't open Addressbook-Window");
			return;
		}
	}
	else if (PubScreen) /* public screen requested */
	{
		if (!(EditABWindow = OpenWindowTags(0,
			WA_PubScreen,(UBYTE *)PubScreen,
			WA_Left,ABLeft,
			WA_Top,ABTop,
			WA_Width,ABWidth,
			WA_Height,ABHeight1,
			WA_MinWidth,640L,
			WA_MinHeight,180L,
			WA_MaxWidth,1024L,
			WA_MaxHeight,1024L,
			WA_DragBar,TRUE,
			WA_DepthGadget,TRUE,
			WA_CloseGadget,TRUE,
			WA_Activate,TRUE,
			WA_SmartRefresh,TRUE,
			WA_GimmeZeroZero,TRUE,
			WA_Title,"Edit Addressbook",
			WA_RMBTrap,TRUE,
			TAG_END)))
		{
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't open Addressbook-Window");
			return;
		}
		
	}
	else
		return;

	if (!(ABLock = Lock((UBYTE *)ADDRESSBOOK,ACCESS_READ)))
	{
			SimpleRequest(Window,"Can't lock addressbook");
			return;
	}

	/* read addressbook */
	ReadAddressBook(&Addressbook);

	GList = 0;


	/* get visualinfo */
	if(!(NextGadget.ng_VisualInfo = GetVisualInfo(EditABWindow->WScreen,TAG_END)))
	{
		SimpleRequest(Window,"Can't get visual info");
		FreeAddressBook(&Addressbook);
		CloseWindow(EditABWindow);
		return;
	}

	PreviousGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	SortGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	FindGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	ClearGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	ABAddGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	UpdateGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	DelGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	UGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	RGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	ReplyToGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;
	CTEGadget.ng_VisualInfo = NextGadget.ng_VisualInfo;

	/* allocate context */
	if (!(gad = CreateContext(&GList)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create context");
			return;
	}

	/* adjust gadgets to window dimensions */
	ClearGadget.ng_LeftEdge = 5;
	ClearGadget.ng_TopEdge = EditABWindow->GZZHeight-TextAttr.ta_YSize-8;
	ClearGadget.ng_Width = 100;                           /* !!!!!!!!!!!!!!! */
	ClearGadget.ng_Height = TextAttr.ta_YSize+4;

	DelGadget.ng_LeftEdge = EditABWindow->GZZWidth-ClearGadget.ng_Width-ClearGadget.ng_LeftEdge-5;
	DelGadget.ng_TopEdge = ClearGadget.ng_TopEdge;
	DelGadget.ng_Width = ClearGadget.ng_Width;
	DelGadget.ng_Height = ClearGadget.ng_Height;

	w = (DelGadget.ng_LeftEdge-ClearGadget.ng_Width-ClearGadget.ng_LeftEdge)/2;

	ABAddGadget.ng_LeftEdge = ClearGadget.ng_Width+ClearGadget.ng_LeftEdge
		+ w/2 - ClearGadget.ng_Width/2;
	ABAddGadget.ng_TopEdge = ClearGadget.ng_TopEdge;
	ABAddGadget.ng_Width = ClearGadget.ng_Width;
	ABAddGadget.ng_Height = ClearGadget.ng_Height;

	UpdateGadget.ng_LeftEdge = ClearGadget.ng_Width+ClearGadget.ng_LeftEdge
		+ w/2 + w - ClearGadget.ng_Width/2;
	UpdateGadget.ng_TopEdge = ClearGadget.ng_TopEdge;
	UpdateGadget.ng_Width = ClearGadget.ng_Width;
	UpdateGadget.ng_Height = ClearGadget.ng_Height;

	PreviousGadget.ng_LeftEdge = ClearGadget.ng_LeftEdge;
	PreviousGadget.ng_TopEdge = ClearGadget.ng_TopEdge-TextAttr.ta_YSize-8;
	PreviousGadget.ng_Width = ClearGadget.ng_Width;
	PreviousGadget.ng_Height = ClearGadget.ng_Height;

	NextGadget.ng_LeftEdge = EditABWindow->GZZWidth-PreviousGadget.ng_Width
		-PreviousGadget.ng_LeftEdge-5;
	NextGadget.ng_TopEdge = PreviousGadget.ng_TopEdge;
	NextGadget.ng_Width = PreviousGadget.ng_Width;
	NextGadget.ng_Height = PreviousGadget.ng_Height;

	w = (NextGadget.ng_LeftEdge-PreviousGadget.ng_Width-PreviousGadget.ng_LeftEdge)/2;

	FindGadget.ng_LeftEdge = PreviousGadget.ng_Width+PreviousGadget.ng_LeftEdge
		+ w/2 - PreviousGadget.ng_Width/2;
	FindGadget.ng_TopEdge = PreviousGadget.ng_TopEdge;
	FindGadget.ng_Width = PreviousGadget.ng_Width;
	FindGadget.ng_Height = PreviousGadget.ng_Height;

	SortGadget.ng_LeftEdge = PreviousGadget.ng_LeftEdge+PreviousGadget.ng_Width
		+ w + w/2 - PreviousGadget.ng_Width/2;
	SortGadget.ng_TopEdge = PreviousGadget.ng_TopEdge;
	SortGadget.ng_Width = PreviousGadget.ng_Width;
	SortGadget.ng_Height = PreviousGadget.ng_Height;

	CTEGadget.ng_LeftEdge = EditABWindow->GZZWidth/2-150/2;
	CTEGadget.ng_TopEdge = SortGadget.ng_TopEdge-TextAttr.ta_YSize-6;
	CTEGadget.ng_Width = 150;
	CTEGadget.ng_Height = TextAttr.ta_YSize+4;

	ReplyToGadget.ng_LeftEdge = 100;
	ReplyToGadget.ng_TopEdge = CTEGadget.ng_TopEdge-TextAttr.ta_YSize-6;
	ReplyToGadget.ng_Width = EditABWindow->GZZWidth-105;
	ReplyToGadget.ng_Height = TextAttr.ta_YSize+4;

	RGadget.ng_LeftEdge = 100;
	RGadget.ng_TopEdge = ReplyToGadget.ng_TopEdge-TextAttr.ta_YSize-6;
	RGadget.ng_Width = EditABWindow->GZZWidth-105;
	RGadget.ng_Height = TextAttr.ta_YSize+4;

	UGadget.ng_LeftEdge = 100;
	UGadget.ng_TopEdge = RGadget.ng_TopEdge-TextAttr.ta_YSize-6;
	UGadget.ng_Width = EditABWindow->GZZWidth-105;
	UGadget.ng_Height = TextAttr.ta_YSize+4;

	/* create Clear gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&ClearGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Clear gadget");
			return;
	}

	/* create Add gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&ABAddGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Add gadget");
			return;
	}

	/* create Update gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&UpdateGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Update gadget");
			return;
	}

	/* create Delete gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&DelGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Delete gadget");
			return;
	}

	
	/* create Previous gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&PreviousGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Previous gadget");
			return;
	}

	/* create Next gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&NextGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Next gadget");
			return;
	}


	/* create Sort gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&SortGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Sort gadget");
			return;
	}


	/* create Find gadget */
	if(!(gad = CreateGadget(BUTTON_KIND,gad,&FindGadget,
		GA_RELVERIFY,TRUE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create Find gadget");
			return;
	}


	/* create CTEGadget */
	if (!(CTEGad = gad = CreateGadget(CYCLE_KIND,gad,&CTEGadget,
		GTCY_Labels,ContentTransferEncoding,
		GTCY_Active,DEFAULT_CTE,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create CTE gadget");
			return;
	}

	/* create ReplyToGadget */
	if (!(ReplyToGad = gad = CreateGadget(STRING_KIND,gad,&ReplyToGadget,
		GTST_MaxChars,MAIL_FIELDLENGTH,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create ReplyTo gadget");
			return;
	}

	/* get RGadget */
	if (!(RealnameGad = gad = CreateGadget(STRING_KIND,gad,&RGadget,
		GTST_MaxChars,MAIL_FIELDLENGTH,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create To gadget");
			return;
	}

	/* get Username-gadget */
	if (!(UsernameGad = gad = CreateGadget(STRING_KIND,gad,&UGadget,
		GTST_MaxChars,MAIL_FIELDLENGTH,
		TAG_END)))
	{
			CloseWindow(EditABWindow);
			FreeAddressBook(&Addressbook);
			SimpleRequest(Window,"Can't create username gadget");
			return;
	}

	/* show up gadgets */
	AddGList(EditABWindow,GList,-1,-1,NULL);
	RefreshGList(GList,EditABWindow,NULL,-1);
	GT_RefreshWindow(EditABWindow,0);

	ModifyIDCMP(EditABWindow,GADGETUP|CYCLEIDCMP|CLOSEWINDOW);

	ActiveGadget = UsernameGad;

	/* Initialize Display List */
	Display.lh_Head = (struct Node *)&(Display.lh_Tail);
	Display.lh_TailPred = (struct Node *)&(Display.lh_Head);
	Display.lh_Tail = 0;
	Display.lh_Type = AMNT_ADDRESSBOOK;

	for (Address=(struct Address *)Addressbook.lh_Head;
		Address->Node.ln_Succ;
		Address=(struct Address *)Address->Node.ln_Succ)
		AddTail(&Display,&(Address->DisplayNode));
	Address = 0;

	/* main loop */
	ActivateGadget(ActiveGadget,EditABWindow,0);
	run = TRUE;
	while (run)
	{
		Wait(1L<<EditABWindow->UserPort->mp_SigBit);
		while (Msg = GT_GetIMsg(EditABWindow->UserPort))
		{
			/* remember values */
			Class = Msg->Class;
			Code  = Msg->Code;	
			IAddr = Msg->IAddress;

			/* reply message */
			GT_ReplyIMsg(Msg);

			/* dispatch */
			switch(Class)
			{
				case REFRESHWINDOW:
					GT_BeginRefresh(EditABWindow);
					GT_EndRefresh(EditABWindow,TRUE);
					break;
				case CLOSEWINDOW:
					run = FALSE;
					break;
				case GADGETUP:
					switch(((struct Gadget *)IAddr)->GadgetID)
					{
						case USERNAME:
							ActiveGadget = RealnameGad;
							break;

						case REALNAME:
							ActiveGadget = ReplyToGad;
							break;

						case REPLYTO:
							ActiveGadget = UsernameGad;
							break;

						case NEXT:
							if (Address)
								AddTail(&Display,&(Address->DisplayNode));

							Address = (struct Address *) RemHead(&Display);
							if (Address) Address = (struct Address *)
								(((char *)Address)-sizeof(struct Node));

							if (Address)
							{
								GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
									GTST_String,Address->Username,
									TAG_END);
								GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
									GTST_String,Address->Realname,
									TAG_END);
								GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
									GTST_String,Address->ReplyTo,
									TAG_END);
								GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
									GTCY_Active,Address->CTE,
									TAG_END);
								ActualCTE = Address->CTE;
							}
							else
							{
								GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
									GTCY_Active,DEFAULT_CTE,
									TAG_END);
								ActualCTE = DEFAULT_CTE;
							}
							ActiveGadget = UsernameGad;
							break;

						case PREVIOUS:
							if (Address)
								AddHead(&Display,&(Address->DisplayNode));

							Address = (struct Address *) RemTail(&Display);
							if (Address) Address = (struct Address *)
								(((char *)Address)-sizeof(struct Node));

							if (Address) if (Address->Node.ln_Pred)
							{
								GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
									GTST_String,Address->Username,
									TAG_END);
								GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
									GTST_String,Address->Realname,
									TAG_END);
								GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
									GTST_String,Address->ReplyTo,
									TAG_END);
								GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
									GTCY_Active,Address->CTE,
									TAG_END);
								ActualCTE = Address->CTE;
							}
							else
							{
								GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
									GTST_String,"",
									TAG_END);
								GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
									GTCY_Active,DEFAULT_CTE,
									TAG_END);
								ActualCTE = DEFAULT_CTE;
							}
							ActiveGadget = UsernameGad;
							break;

						case DELETE:
							if (Address)
							{
								if (TwoGadRequest(EditABWindow,"Really delete?"))
								{
									RemAddress(Address);
									Address = 0;
									GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
										GTST_String,"",
										TAG_END);
									GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
										GTST_String,"",
										TAG_END);
									GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
										GTST_String,"",
										TAG_END);
									GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
										GTCY_Active,DEFAULT_CTE,
										TAG_END);
									ActualCTE = DEFAULT_CTE;
									ActiveGadget = UsernameGad;
								}
							}
							else
								SimpleRequest(EditABWindow,"No address selected!");

							break;
							
						case UPDATE:
							if (Address)
							{
								if (TwoGadRequest(EditABWindow,"Update current entry?"))
								{
									strcpy(Address->Username,(char *)((struct StringInfo *)
										UsernameGad->SpecialInfo)->Buffer);
									strcpy(Address->Realname,(char *)((struct StringInfo *)
										RealnameGad->SpecialInfo)->Buffer);
									strcpy(Address->ReplyTo,(char *)((struct StringInfo *)
										ReplyToGad->SpecialInfo)->Buffer);
									Address->CTE = ActualCTE;
								}
							}
							else
								SimpleRequest(EditABWindow,"No address selected!");

							break;

						case CLEAR:
							GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
								GTST_String,"",
								TAG_END);
							GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
								GTST_String,"",
								TAG_END);
							GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
								GTST_String,"",
								TAG_END);
							GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
								GTCY_Active,DEFAULT_CTE,
								TAG_END);
							ActualCTE = DEFAULT_CTE;
							ActiveGadget = UsernameGad;

							if (Address)
								AddHead(&Display,&(Address->DisplayNode));
							Address=0;

							break;

						case CTE_:
							ActualCTE = (ActualCTE+1)%5;
							break;
						
						case ADD:							
							/* Username/Realname given? */
							if (!*((char *)((struct StringInfo *)
								UsernameGad->SpecialInfo)->Buffer))
							{
								SimpleRequest(EditABWindow,"No Username!");
								break;
							}
							if (!*((char *)((struct StringInfo *)
								RealnameGad->SpecialInfo)->Buffer))
							{
								SimpleRequest(EditABWindow,"No Realname!");
								break;
							}
							if (TwoGadRequest(EditABWindow,"Really add?"))
							{
								if (Address) 
									AddHead(&Display,&(Address->DisplayNode));

								AddAddress(&Addressbook,
									(char *)((struct StringInfo *)
										RealnameGad->SpecialInfo)->Buffer,
									(char *)((struct StringInfo *)
										UsernameGad->SpecialInfo)->Buffer,
									(char *)((struct StringInfo *)
										ReplyToGad->SpecialInfo)->Buffer,
									ActualCTE);

								Address = (struct Address *) RemTail(&Addressbook);
								AddTail(&Addressbook,(struct Node *)Address);
							}
							break;
								
						case AB_SORT:
							/* Initialize Sort List */
							Sort.lh_Head = (struct Node *)&(Sort.lh_Tail);
							Sort.lh_TailPred = (struct Node *)&(Sort.lh_Head);
							Sort.lh_Tail = 0;
							Sort.lh_Type = AMNT_ADDRESSBOOK;

							/* Sort: straight insertion */
							while (Address = (struct Address *)RemHead(&Addressbook))
							{
								for (Scan = (struct Address *)Sort.lh_Head;
									Scan->Node.ln_Succ;
									Scan=(struct Address *)Scan->Node.ln_Succ)
									if (strcmp(Scan->Username,Address->Username)>0) 
										break;
								Insert(&Sort,(struct Node *)Address,(struct Node *)Scan->Node.ln_Pred);
							}

							/* copy sorted list back to addressbook */
							while (Address = (struct Address *)RemHead(&Sort))
								AddTail(&Addressbook,(struct Node *)Address);

							/* re-initialize display list */
							Display.lh_Head = (struct Node *)&(Display.lh_Tail);
							Display.lh_TailPred = (struct Node *)&(Display.lh_Head);
							Display.lh_Tail = 0;
							Display.lh_Type = AMNT_ADDRESSBOOK;
						
							for (Address=(struct Address *)Addressbook.lh_Head;
								Address->Node.ln_Succ;
								Address=(struct Address *)Address->Node.ln_Succ)
								AddTail(&Display,&(Address->DisplayNode));

							Address = 0;

							break;

						case FIND:
							if (!Address)
								if (Address = (struct Address *) RemHead(&Display))
									Address = (struct Address *) 
										((char *)Address-sizeof(struct Node));
								else
								{
									SimpleRequest(EditABWindow,"no addresses!");
									break;
								}

							StartAddress = Address;

							/* remember Username and Realname for comparision */
							strncpy(MyUsername,
								(char *)((struct StringInfo *)
								UsernameGad->SpecialInfo)->Buffer,MAIL_FIELDLENGTH);
							strncpy(MyRealname,
								(char *)((struct StringInfo *)
								RealnameGad->SpecialInfo)->Buffer,MAIL_FIELDLENGTH);

							found = FALSE;
							do
							{
								/* display to make it interesting for the user :-) */
								GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
									GTST_String,Address->Username,
									TAG_END);
								GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
									GTST_String,Address->Realname,
									TAG_END);
								GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
									GTST_String,Address->ReplyTo,
									TAG_END);
								GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
									GTCY_Active,Address->CTE,
									TAG_END);
								ActualCTE = Address->CTE;

								/* compare */
								if (strstr(Address->Username,MyUsername)&&
									strstr(Address->Realname,MyRealname))
								{
									/* found? then break */
									found = TRUE;
									break;
								}
								else
								{
									GT_SetGadgetAttrs(UsernameGad,EditABWindow,0,
										GTST_String,MyUsername,
										TAG_END);
									GT_SetGadgetAttrs(RealnameGad,EditABWindow,0,
										GTST_String,MyRealname,
										TAG_END);
									GT_SetGadgetAttrs(ReplyToGad,EditABWindow,0,
										GTST_String,"",
										TAG_END);
									GT_SetGadgetAttrs(CTEGad,EditABWindow,0,
										GTCY_Active,Address->CTE,
										TAG_END);
									ActualCTE = Address->CTE;
								}

								/* goto next */
								AddTail(&Display,&(Address->DisplayNode));
								Address = (struct Address *) RemHead(&Display);
								if (Address) Address = (struct Address *)
									(((char *)Address)-sizeof(struct Node));
								
							}
							while (Address!=StartAddress);

							if (!found) SimpleRequest(EditABWindow,"Not found");
							break;

						default:
							puts("unknown gadget");
							break;
					}
				case MOUSEBUTTONS:
					break;
				case INTUITICKS:
					break;
				default:
					printf("Unknkown IntuiMessage->Class:%x\n",Class);
					break;
			}

			ActivateGadget(ActiveGadget,EditABWindow,0);
		}
	}

	
	/* remove,free gadgets */
	RemoveGList(EditABWindow,GList,-1); 
	FreeGadgets(GList);

	FreeVisualInfo(NextGadget.ng_VisualInfo);

	CloseWindow(EditABWindow);

	UnLock(ABLock);

	/* write addressbook */
	if (!(WriteAddressBook(&Addressbook)))
		SimpleRequest(Window,"Can't write addressbook!");

	return;
}
