/*
**	RatePanel.c
**
**	Editing panel for phone units configuration
**
**	Copyright © 1990-1996 by Olaf `Olsen' Barthel
**		All Rights Reserved
**
**	:ts=4
*/

#ifndef _GLOBAL_H
#include "Global.h"
#endif

enum	{	GAD_TIME=1,GAD_ADDTIME,GAD_REMOVETIME,GAD_EDITTIME,
			GAD_PAY1,GAD_MINUTES1,
			GAD_PAY2,GAD_MINUTES2,
			GAD_LIST,
			GAD_ADDDATE,GAD_ADDDAY,GAD_EDIT,
			GAD_CLONE,GAD_REMOVE,GAD_IMPORT
		};

struct DoubleInfo
{
	LONG	GlyphWidth,
			HeaderLen;
};

VOID
Rate2String(ULONG Rate,STRPTR String)
{
	if(Rate % 10000)
	{
		LONG i,Len;

		SPrintf(String,"%ld%lc%04ld",Rate / 10000,DecimalPoint,Rate % 10000);

		Len = strlen(String);

		for(i = Len - 1 ; i >= Len - 3 ; i--)
		{
			if(String[i] == '0')
				String[i] = 0;
			else
				break;
		}
	}
	else
		SPrintf(String,"%ld",Rate / 10000);
}

ULONG
String2Rate(STRPTR String)
{
	ULONG Lead;
	ULONG Follow;
	ULONG Factor;
	BOOL Decimal;
	LONG i;

	Lead = 0;
	Follow = 0;
	Factor = 1000;
	Decimal = FALSE;

	for(i = 0 ; i < strlen(String) ; i++)
	{
		if(String[i] == DecimalPoint)
			Decimal = TRUE;
		else
		{
			ULONG v = String[i] & 0xf;

			if(Decimal)
			{
				Follow += v * Factor;

				Factor /= 10;
			}
			else
				Lead = (10 * Lead) + v;
		}
	}

	return(Lead * 10000 + Follow);
}

STATIC ULONG __saveds __asm
RateEditRoutine(REG(a2) struct SGWork *Work,REG(a1) ULONG *Msg)
{
	if(*Msg == SGH_KEY)
	{
		ULONG Integral;
		LONG i;
		BOOL Decimal;
		WORD Follow;
		BOOL UseIt;
		UBYTE c;

		Integral = 0;
		Decimal = FALSE;
		Follow = 0;
		UseIt = TRUE;

		for(i = 0 ; i < strlen(Work->WorkBuffer) ; i++)
		{
			c = Work->WorkBuffer[i];

			if(c == '.')
				c = Work->WorkBuffer[i] = DecimalPoint;

			if(c == DecimalPoint)
			{
				if(Decimal)
				{
					UseIt = FALSE;
					break;
				}
				else
					Decimal = TRUE;
			}
			else
			{
				if(c >= '0' && c <= '9')
				{
					if(Decimal)
						Follow++;
					else
						Integral = (Integral * 10) + (c & 0xf);
				}
				else
				{
					UseIt = FALSE;
					break;
				}
			}
		}

		if(Follow > 4 || !UseIt || Integral > 429496)
		{
			Work->EditOp	= EO_BADFORMAT;
			Work->Actions	= SGA_BEEP;
		}
	}
	else
	{
		if(*Msg != SGH_CLICK)
			return(FALSE);
	}

	return(TRUE);
}

	/* RateListViewRender():
	 *
	 *	This callback routine is responsible for rendering
	 *	the single listview entries.
	 */

STATIC ULONG __saveds __asm
RateListViewRender(REG(a0) struct Hook *Hook,REG(a1) struct LVDrawMsg *Msg,REG(a2) struct Node *Node)
{
		/* We only know how to redraw lines. */

	if(Msg->lvdm_MethodID == LV_DRAW)
	{
		struct RastPort		*RPort	= Msg->lvdm_RastPort;
		LONG				 Left	= Msg->lvdm_Bounds.MinX,
							 Top	= Msg->lvdm_Bounds.MinY,
							 Width	= Msg->lvdm_Bounds.MaxX - Msg->lvdm_Bounds.MinX + 1,
							 Height	= Msg->lvdm_Bounds.MaxY - Msg->lvdm_Bounds.MinY + 1,
							 Delta,
							 FgPen,BgPen,
							 Len,LabelLen,Template;
		UBYTE				*String,Header[8];
		struct DoubleInfo	*Info;
		UWORD				*Pens;

		Pens = Msg->lvdm_DrawInfo->dri_Pens;

		Info = Hook->h_Data;

		String = &Node->ln_Name[Info->HeaderLen];

		CopyMem(Node->ln_Name,Header,Info->HeaderLen);

		Header[Info->HeaderLen] = 0;

			/* Determine the rendering pens. */

		if(Msg->lvdm_State == LVR_SELECTED)
		{
			FgPen = FILLTEXTPEN;
			BgPen = FILLPEN;
		}
		else
		{
			FgPen = TEXTPEN;
			BgPen = BACKGROUNDPEN;
		}

		FgPen = Pens[FgPen];
		BgPen = Pens[BgPen];

			/* Set the rendering pens. */

		SetABPenDrMd(RPort,BgPen,BgPen,JAM2);

		RectFill(RPort,Left,Top,Left + 1,Top + Height - 1);

		Left	+= 2;
		Width	-= 2;

		Template = Info->HeaderLen * Info->GlyphWidth;

			/* Determine header length. */

		Len = TextLength(RPort,Header,Info->HeaderLen);

			/* Fill the space to precede the header. */

		if((Delta = Template - Len) > 0)
		{
			SetAPen(RPort,BgPen);
			FillBox(RPort,Left,Top,Delta,Height);
		}

			/* Render the header, right-justified. */

		SetAPen(RPort,FgPen);

		PlaceText(RPort,Left + Delta,Top,Header,Info->HeaderLen);

			/* Adjust width and area left edge. */

		Left	+= Template;
		Width	-= Template;

			/* Determine length of vanilla name. */

		LabelLen = strlen(String);

			/* Try to make it fit. */

		while(LabelLen > 0 && (Len = TextLength(RPort,String,LabelLen)) > Width)
			LabelLen--;

			/* Print the vanilla name if possible. */

		if(LabelLen)
		{
			PlaceText(RPort,Left,Top,String,LabelLen);

			Left	+= Len;
			Width	-= Len;
		}

			/* Fill the area to follow the vanilla name. */

		if(Width > 0)
		{
			SetAPen(RPort,BgPen);
			FillBox(RPort,Left,Top,Width,Height);
		}

			/* If the item happens to be disabled, draw the cross-hatch
			 * pattern across it.
			 */

		ListViewStateFill(Msg);

		return(LVCB_OK);
	}
	else
		return(LVCB_UNKNOWN);
}

STATIC VOID
DisableGadgets(struct LayoutHandle *Handle,BOOL Mode,BOOL SetEntries,BOOL SetTime)
{
	LT_SetAttributes(Handle,GAD_PAY1,
		GA_Disabled,	Mode,
	TAG_DONE);

	LT_SetAttributes(Handle,GAD_MINUTES1,
		GA_Disabled,	Mode,
	TAG_DONE);

	LT_SetAttributes(Handle,GAD_PAY2,
		GA_Disabled,	Mode,
	TAG_DONE);

	LT_SetAttributes(Handle,GAD_MINUTES2,
		GA_Disabled,	Mode,
	TAG_DONE);

	if(SetEntries)
	{
		LT_SetAttributes(Handle,GAD_EDIT,
			GA_Disabled,	Mode,
		TAG_DONE);

		LT_SetAttributes(Handle,GAD_CLONE,
			GA_Disabled,	Mode,
		TAG_DONE);

		LT_SetAttributes(Handle,GAD_REMOVE,
			GA_Disabled,	Mode,
		TAG_DONE);
	}

	if(SetTime)
	{
		LT_SetAttributes(Handle,GAD_TIME,
			GA_Disabled,	Mode,
		TAG_DONE);

		LT_SetAttributes(Handle,GAD_ADDTIME,
			GA_Disabled,	Mode,
		TAG_DONE);

		LT_SetAttributes(Handle,GAD_REMOVETIME,
			GA_Disabled,	Mode,
		TAG_DONE);

		LT_SetAttributes(Handle,GAD_EDITTIME,
			GA_Disabled,	Mode,
		TAG_DONE);
	}
}

BOOL
RatePanel(struct Window *Parent,struct List *PhoneList,struct PhoneEntry *Entry,struct List *TimeDateList)
{
	STATIC struct DoubleInfo TimeInfo;

	STATIC struct Hook TimeHook =
	{
		{NULL},
		(HOOKFUNC)RateListViewRender,
		(HOOKFUNC)NULL,
		&TimeInfo
	};

	STATIC struct DoubleInfo DateInfo;

	STATIC struct Hook DateHook =
	{
		{NULL},
		(HOOKFUNC)RateListViewRender,
		(HOOKFUNC)NULL,
		&DateInfo
	};

	STATIC struct Hook RateHook =
	{
		{NULL},
		(HOOKFUNC)RateEditRoutine
	};

	struct LayoutHandle	*Handle;
	BOOL				 MadeChanges = FALSE;

	if(!TimeDateList)
		TimeDateList = (struct List *)&Entry->TimeDateList;

	if(Handle = LT_CreateHandleTags(Parent->WScreen,
		LH_LocaleHook,	&LocaleHook,
	TAG_DONE))
	{
		STATIC WORD ButtonLabels[] =
		{
			MSG_RATEPANEL_ADD_TIME_GAD,
			MSG_RATEPANEL_REMOVE_TIME_GAD,
			MSG_RATEPANEL_EDIT_TIME_GAD,

			MSG_RATEPANEL_ADD_DATE_GAD,
			MSG_RATEPANEL_ADD_DAYS_GAD,
			MSG_RATEPANEL_EDIT_GAD,

			MSG_RATEPANEL_CLONE_GAD,
			MSG_GLOBAL_REMOVE_GAD,
			MSG_RATEPANEL_IMPORT_GAD
		};

		struct Window	*PanelWindow;
		LONG			 i,Max = 0,Size;
		UBYTE			 SmallString[2];

		SmallString[1] = 0;

		for(i = '0' ; i <= '9' ; i++)
		{
			SmallString[0] = i;

			if((Size = LT_LabelWidth(Handle,SmallString)) > Max)
				Max = Size;
		}

		TimeInfo.GlyphWidth	= Max;
		TimeInfo.HeaderLen	= 2;

		DateInfo.GlyphWidth	= Max;
		DateInfo.HeaderLen	= 7;

		for(i = Max = 0 ; i < NumElements(ButtonLabels) ; i++)
		{
			if((Size = LT_LabelChars(Handle,LocaleString(ButtonLabels[i]))) > Max)
				Max = Size;
		}

		LT_New(Handle,
			LA_Type,	VERTICAL_KIND,
		TAG_DONE);
		{
			LT_New(Handle,
				LA_Type,	HORIZONTAL_KIND,
				LA_LabelID,	MSG_V36_0157,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,	HORIZONTAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,		LISTVIEW_KIND,
						LA_LabelID,		MSG_RATEPANEL_DAYS_AND_DATES_GAD,
						LA_Chars,		30,
						LA_Lines,		10,
						LA_ID,			GAD_LIST,
						GTLV_CallBack,	&DateHook,
						GTLV_MaxPen,	GetListMaxPen(Handle->DrawInfo->dri_Pens),
						GTLV_Labels,	TimeDateList,
						LALV_Link,		NIL_LINK,

						Kick30 ? TAG_IGNORE : LALV_TextAttr, ~0,
					TAG_DONE);

					LT_New(Handle,
						LA_Type,		LISTVIEW_KIND,
						LA_LabelID,		MSG_RATEPANEL_TIME_GAD,
						LA_Chars,		10,
						LA_Lines,		10,
						LA_ID,			GAD_TIME,
						GA_Disabled,	TRUE,
						GTLV_CallBack,	&TimeHook,
						GTLV_MaxPen,	GetListMaxPen(Handle->DrawInfo->dri_Pens),
						LALV_Link,		NIL_LINK,

						Kick30 ? TAG_IGNORE : LALV_TextAttr, ~0,
					TAG_DONE);

					LT_EndGroup(Handle);
				}

				LT_New(Handle,
					LA_Type,	VERTICAL_KIND,
				TAG_DONE);
				{
					LT_New(Handle,
						LA_Type,		VERTICAL_KIND,
						LA_LabelID,		MSG_RATEPANEL_FIRST_UNIT_GAD,
						LAGR_SameSize,	TRUE,
					TAG_DONE);
					{
						LT_New(Handle,
							LA_Type,			STRING_KIND,
							LA_LabelText,		SmallCurrency(),
							LA_ID,				GAD_PAY1,
							LA_Chars,			6,
							GTST_MaxChars,		11,
							GTST_EditHook,		&RateHook,
							GA_Disabled,		TRUE,
						TAG_DONE);

						LT_New(Handle,
							LA_Type,			STRING_KIND,
							LA_LabelID,			MSG_RATEPANEL_SECONDS_PER_UNIT_GAD,
							LA_ID,				GAD_MINUTES1,
							GTST_MaxChars,		11,
							GTST_EditHook,		&RateHook,
							GA_Disabled,		TRUE,
						TAG_DONE);

						LT_EndGroup(Handle);
					}

					LT_New(Handle,
						LA_Type,		VERTICAL_KIND,
						LA_LabelID,		MSG_RATEPANEL_FOLLOWING_UNITS_GAD,
						LAGR_SameSize,	TRUE,
					TAG_DONE);
					{
						LT_New(Handle,
							LA_Type,			STRING_KIND,
							LA_LabelText,		SmallCurrency(),
							LA_ID,				GAD_PAY2,
							GA_Disabled,		TRUE,
							GTST_MaxChars,		11,
							GTST_EditHook,		&RateHook,
						TAG_DONE);

						LT_New(Handle,
							LA_Type,			STRING_KIND,
							LA_LabelID,			MSG_RATEPANEL_SECONDS_PER_UNIT_GAD,
							LA_ID,				GAD_MINUTES2,
							LA_Chars,			6,
							GTST_MaxChars,		11,
							GTST_EditHook,		&RateHook,
							GA_Disabled,		TRUE,
						TAG_DONE);

						LT_EndGroup(Handle);
					}

					LT_EndGroup(Handle);
				}

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		XBAR_KIND,
					LAXB_FullSize,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,LA_Type,HORIZONTAL_KIND,
				LAGR_Spread,	TRUE,
				LAGR_SameSize,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_ADD_TIME_GAD,
					LA_ID,			GAD_ADDTIME,
					LA_Chars,		Max,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_REMOVE_TIME_GAD,
					LA_ID,			GAD_REMOVETIME,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_EDIT_TIME_GAD,
					LA_ID,			GAD_EDITTIME,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,
				LA_Type,	VERTICAL_KIND,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		XBAR_KIND,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,LA_Type,HORIZONTAL_KIND,
				LAGR_Spread,	TRUE,
				LAGR_SameSize,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_ADD_DATE_GAD,
					LA_ID,			GAD_ADDDATE,
					LA_Chars,		Max,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_ADD_DAYS_GAD,
					LA_ID,			GAD_ADDDAY,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_EDIT_GAD,
					LA_ID,			GAD_EDIT,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_New(Handle,LA_Type,HORIZONTAL_KIND,
				LAGR_Spread,	TRUE,
				LAGR_SameSize,	TRUE,
			TAG_DONE);
			{
				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_CLONE_GAD,
					LA_ID,			GAD_CLONE,
					LA_Chars,		Max,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_GLOBAL_REMOVE_GAD,
					LA_ID,			GAD_REMOVE,
					GA_Disabled,	TRUE,
				TAG_DONE);

				LT_New(Handle,
					LA_Type,		BUTTON_KIND,
					LA_LabelID,		MSG_RATEPANEL_IMPORT_GAD,
					LA_ID,			GAD_IMPORT,
					GA_Disabled,	!PhoneList,
				TAG_DONE);

				LT_EndGroup(Handle);
			}

			LT_EndGroup(Handle);
		}

		if(PanelWindow = LT_Build(Handle,
			LAWN_TitleID,		MSG_RATEPANEL_RATES_PREFERENCES_TXT,
			LAWN_IDCMP,			IDCMP_CLOSEWINDOW,
			LAWN_HelpHook,		&GuideHook,
			LAWN_Parent,		Parent,
			WA_DepthGadget,		TRUE,
			WA_CloseGadget,		TRUE,
			WA_DragBar,			TRUE,
			WA_RMBTrap,			TRUE,
			WA_Activate,		TRUE,
			WA_SimpleRefresh,	TRUE,
		TAG_DONE))
		{
			struct IntuiMessage	*Message;
			BOOL				 Done = FALSE;
			ULONG				 MsgClass;
			UWORD				 MsgCode;
			struct Gadget		*MsgGadget;
			LONG				 MsgGadgetID;

			BOOL				 Redisplay;

			struct TimeDateNode	*TimeDateNode,
								*NewNode;
			struct List			*TimeList		= NULL;
			LONG				 Selected		= ~0,
								 Count			=  0,
								 TimeSelected	= ~0;

			UBYTE				 PayString1[20],
								 PayString2[20];
			UBYTE				 TimeString1[20],
								 TimeString2[20];

			GuideContext(CONTEXT_RATES);

			TimeDateNode = (struct TimeDateNode *)TimeDateList->lh_Head;

			while(TimeDateNode->VanillaNode.ln_Succ)
			{
				Count++;

				TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode.ln_Succ;
			}

			PushWindow(PanelWindow);

			Redisplay = FALSE;

			LT_ShowWindow(Handle,TRUE);

			do
			{
				if(Wait(PORTMASK(PanelWindow->UserPort) | SIG_BREAK) & SIG_BREAK)
					break;

				while(Message = (struct IntuiMessage *)LT_GetIMsg(Handle))
				{
					MsgClass	= Message->Class;
					MsgCode		= Message->Code;
					MsgGadget	= (struct Gadget *)Message->IAddress;

					LT_ReplyIMsg(Message);

					if(MsgClass == IDCMP_CLOSEWINDOW)
						Done = TRUE;

					MsgGadgetID = -1;

					if(MsgClass == IDCMP_GADGETUP)
						MsgGadgetID = MsgGadget->GadgetID;

					if(MsgClass == IDCMP_IDCMPUPDATE)
					{
						switch(MsgGadget->GadgetID)
						{
							case GAD_TIME:

								if(Selected != ~0 && TimeSelected != ~0)
									MsgGadgetID = GAD_EDITTIME;

								break;

							case GAD_LIST:

								if(Selected != ~0 && Selected > 0)
									MsgGadgetID = GAD_EDIT;

								break;
						}

						if(MsgGadgetID != -1)
							LT_PressButton(Handle,MsgGadgetID);
					}

					if(MsgGadgetID != -1)
					{
						switch(MsgGadgetID)
						{
							case GAD_TIME:

								TimeSelected = MsgCode;

								if(Selected != ~0)
								{
									Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_FIRST_UNIT],PayString1);

									LT_SetAttributes(Handle,GAD_PAY1,
										GTST_String,	PayString1,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_FIRST_UNIT],TimeString1);

									LT_SetAttributes(Handle,GAD_MINUTES1,
										GTST_String,	TimeString1,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_NEXT_UNIT],PayString2);

									LT_SetAttributes(Handle,GAD_PAY2,
										GTST_String,	PayString2,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_NEXT_UNIT],TimeString2);

									LT_SetAttributes(Handle,GAD_MINUTES2,
										GTST_String,	TimeString2,
									TAG_DONE);
								}

								break;

							case GAD_EDITTIME:

								if(Selected != ~0 && TimeSelected != ~0)
								{
										// Make a backup in case we need to restore it later

									LONG Time = TimeDateNode->Table[TimeSelected].Time;

									LT_LockWindow(PanelWindow);

										// Edit the time

									if(TimePanel(PanelWindow,&TimeDateNode->Table[TimeSelected].Time))
									{
										struct List *NewTimeList;

										MadeChanges = TRUE;

											// Make a mark so we can find it later

										TimeDateNode->Table[TimeSelected].Mark = TRUE;

											// Sort the times in ascending order

										SortTimeTable(TimeDateNode);

											// Find the previously selected item

										for(i = 0 ; i < TimeDateNode->Table[0].Count ; i++)
										{
											if(TimeDateNode->Table[i].Mark)
											{
												TimeSelected = i;
												break;
											}
										}

											// Create a new time display list

										if(NewTimeList = BuildTimeList(TimeDateNode))
										{
												// Update the list display

											LT_SetAttributes(Handle,GAD_TIME,
												GTLV_Labels,	NewTimeList,
												GTLV_Selected,	TimeSelected,
											TAG_DONE);

												// Replace old list with new list

											FreeVecPooled(TimeList);

											TimeList = NewTimeList;
										}
										else
										{
												// So that didn't work; restore the old time

											TimeDateNode->Table[TimeSelected].Time = Time;

												// Bring back the original sorting order

											SortTimeTable(TimeDateNode);

												// Find the original item position

											for(i = 0 ; i < TimeDateNode->Table[0].Count ; i++)
											{
												if(TimeDateNode->Table[i].Mark)
												{
													TimeSelected = i;
													break;
												}
											}

												// And restore the display

											LT_SetAttributes(Handle,GAD_TIME,
												GTLV_Selected,TimeSelected,
											TAG_DONE);

											DisplayBeep(PanelWindow->WScreen);
										}

											// Remove the mark

										TimeDateNode->Table[TimeSelected].Mark = FALSE;
									}

									LT_UnlockWindow(PanelWindow);

									LT_ShowWindow(Handle,TRUE);
								}

								break;

							case GAD_REMOVETIME:

								if(Selected != ~0 && TimeSelected != ~0)
								{
									MadeChanges = TRUE;

									LT_LockWindow(PanelWindow);

									LT_SetAttributes(Handle,GAD_TIME,
										GTLV_Labels,	~0,
									TAG_DONE);

									if(DeleteTimeDateNode(TimeDateNode,TimeSelected))
									{
										FreeVecPooled(TimeList);

										if(TimeList = BuildTimeList(TimeDateNode))
										{
											LT_SetAttributes(Handle,GAD_TIME,
												GTLV_Labels,	TimeList,
												GTLV_Selected,	~0,
												GA_Disabled,	TRUE,
											TAG_DONE);

											TimeSelected = ~0;

											LT_SetAttributes(Handle,GAD_LIST,
												GTLV_Labels,	TimeDateList,
												GTLV_Selected,	~0,
											TAG_DONE);

											DisableGadgets(Handle,TRUE,TRUE,TRUE);

											Selected = ~0;
										}
										else
										{
											LT_SetAttributes(Handle,GAD_TIME,
												GTLV_Labels,	NULL,
												GTLV_Selected,	~0,
											TAG_DONE);

											TimeSelected = ~0;

											DisplayBeep(PanelWindow->WScreen);
										}
									}
									else
									{
										LT_SetAttributes(Handle,GAD_TIME,
											GTLV_Labels,	TimeList,
											GTLV_Selected,	TimeSelected,
										TAG_DONE);

										DisplayBeep(PanelWindow->WScreen);
									}

									LT_UnlockWindow(PanelWindow);
								}

								break;

							case GAD_ADDTIME:

								if(Selected != ~0)
								{
									UBYTE Time = DT_GET_TIME(12,0);

									MadeChanges = TRUE;

									LT_LockWindow(PanelWindow);

										// Get the new time

									if(TimePanel(PanelWindow,&Time))
									{
										BOOL AddIt = TRUE;
										LONG i;

											// Check if this moment already exists

										for(i = 0 ; i < TimeDateNode->Table[0].Count ; i++)
										{
											if(Time == TimeDateNode->Table[i].Time)
											{
												AddIt = FALSE;
												break;
											}
										}

											// Don't add it if it's already in there

										if(AddIt)
										{
											LT_SetAttributes(Handle,GAD_TIME,
												GTLV_Labels,	~0,
											TAG_DONE);

												// Make a mark so we can find this entry later

											TimeDateNode->Table[TimeSelected].Mark = TRUE;

												// Add one new entry

											if(ResizeTimeDateNode(TimeDateNode,TimeDateNode->Table[0].Count + 1,Time))
											{
													// Restore the proper order

												SortTimeTable(TimeDateNode);

													// Find the originally selected item

												for(i = 0 ; i < TimeDateNode->Table[0].Count ; i++)
												{
													if(TimeDateNode->Table[i].Mark)
													{
														TimeSelected = i;
														TimeDateNode->Table[i].Mark = FALSE;
														break;
													}
												}

													// Build new display list

												FreeVecPooled(TimeList);

												if(TimeList = BuildTimeList(TimeDateNode))
												{
													LT_SetAttributes(Handle,GAD_TIME,
														GTLV_Labels,	TimeList,
														GTLV_Selected,	TimeSelected,
														GA_Disabled,	FALSE,
													TAG_DONE);
												}
												else
												{
													LT_SetAttributes(Handle,GAD_TIME,
														GTLV_Labels,	NULL,
														GTLV_Selected,	~0,
													TAG_DONE);

													TimeSelected = ~0;

													DisplayBeep(PanelWindow->WScreen);
												}
											}
											else
											{
													// Clear the mark

												TimeDateNode->Table[TimeSelected].Mark = FALSE;

													// Restore the list

												LT_SetAttributes(Handle,GAD_TIME,
													GTLV_Labels,	TimeList,
													GTLV_Selected,	TimeSelected,
												TAG_DONE);

												DisplayBeep(PanelWindow->WScreen);
											}
										}
									}

									LT_UnlockWindow(PanelWindow);

									LT_ShowWindow(Handle,TRUE);
								}

								break;

							case GAD_PAY1:

								TimeDateNode->Table[TimeSelected].PayPerUnit[DT_FIRST_UNIT] = String2Rate(LT_GetString(Handle,MsgGadgetID));

								MadeChanges = TRUE;

								break;

							case GAD_PAY2:

								TimeDateNode->Table[TimeSelected].PayPerUnit[DT_NEXT_UNIT] = String2Rate(LT_GetString(Handle,MsgGadgetID));

								MadeChanges = TRUE;

								break;

							case GAD_MINUTES1:

								TimeDateNode->Table[TimeSelected].SecPerUnit[DT_FIRST_UNIT] = String2Rate(LT_GetString(Handle,MsgGadgetID));

								MadeChanges = TRUE;

								break;

							case GAD_MINUTES2:

								TimeDateNode->Table[TimeSelected].SecPerUnit[DT_NEXT_UNIT] = String2Rate(LT_GetString(Handle,MsgGadgetID));

								MadeChanges = TRUE;

								break;

							case GAD_LIST:

								LT_SetAttributes(Handle,GAD_TIME,
									GTLV_Labels,~0,
								TAG_DONE);

								FreeVecPooled(TimeList);

								TimeDateNode = (struct TimeDateNode *)GetListNode(MsgCode,(struct List *)TimeDateList);

								if(TimeList = BuildTimeList(TimeDateNode))
								{
									TimeSelected = 0;

									Selected = MsgCode;

									DisableGadgets(Handle,FALSE,FALSE,FALSE);

									TimeDateNode = (struct TimeDateNode *)GetListNode(Selected,(struct List *)TimeDateList);

									Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_FIRST_UNIT],PayString1);

									LT_SetAttributes(Handle,GAD_PAY1,
										GTST_String,	PayString1,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_FIRST_UNIT],TimeString1);

									LT_SetAttributes(Handle,GAD_MINUTES1,
										GTST_String,	TimeString1,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_NEXT_UNIT],PayString2);

									LT_SetAttributes(Handle,GAD_PAY2,
										GTST_String,	PayString2,
									TAG_DONE);

									Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_NEXT_UNIT],TimeString2);

									LT_SetAttributes(Handle,GAD_MINUTES2,
										GTST_String,	TimeString2,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_TIME,
										GTLV_Labels,	TimeList,
										GTLV_Selected,	0,
										GA_Disabled,	FALSE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_ADDTIME,
										GA_Disabled,	FALSE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_REMOVETIME,
										GA_Disabled,	TimeDateNode->Table[0].Count < 2,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_EDITTIME,
										GA_Disabled,	FALSE,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_EDIT,
										GA_Disabled,	!Selected,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_CLONE,
										GA_Disabled,	!Selected,
									TAG_DONE);

									LT_SetAttributes(Handle,GAD_REMOVE,
										GA_Disabled,	!Selected,
									TAG_DONE);
								}
								else
								{
									TimeDateNode = NULL;

									DisplayBeep(PanelWindow->WScreen);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	~0,
									TAG_DONE);

									DisableGadgets(Handle,TRUE,TRUE,TRUE);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	~0,
									TAG_DONE);

									Selected = ~0;

									LT_SetAttributes(Handle,GAD_TIME,
										GTLV_Labels,	NULL,
										GTLV_Selected,	~0,
										GA_Disabled,	TRUE,
									TAG_DONE);

									TimeSelected = ~0;
								}

								break;

							case GAD_IMPORT:

								LT_LockWindow(PanelWindow);

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	~0,
								TAG_DONE);

								if(ImportPanel(PanelWindow,Entry,PhoneList,TimeDateList))
								{
									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	~0,
									TAG_DONE);

									Selected = ~0;

									LT_SetAttributes(Handle,GAD_TIME,
										GTLV_Labels,	TimeList,
										GTLV_Selected,	~0,
									TAG_DONE);

									TimeSelected = ~0;

									DisableGadgets(Handle,TRUE,TRUE,TRUE);

									MadeChanges = TRUE;
								}
								else
								{
									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	Selected,
									TAG_DONE);
								}

								LT_UnlockWindow(PanelWindow);

								LT_ShowWindow(Handle,TRUE);

								break;

							case GAD_ADDDAY:
							case GAD_ADDDATE:

								LT_LockWindow(PanelWindow);

								MadeChanges = TRUE;

								if(NewNode = CreateTimeDateNode(0,1,"",1))
								{
									BOOL Result;

									if(MsgGadgetID == GAD_ADDDAY)
									{
										NewNode->Header.Month	= -1;
										NewNode->Header.Day		= 0;

										Result = DayPanel(PanelWindow,NewNode);
									}
									else
										Result = DatePanel(PanelWindow,NewNode);

									if(Result)
									{
										AdaptTimeDateNode(NewNode);

										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,	~0,
										TAG_DONE);

										AddTail((struct List *)TimeDateList,&NewNode->VanillaNode);

										Selected = Count++;

										LT_SetAttributes(Handle,GAD_LIST,
											GTLV_Labels,		TimeDateList,
											GTLV_Selected,		Selected,
											GTLV_Top,			Selected,
											GTLV_MakeVisible,	Selected,
										TAG_DONE);

										TimeDateNode = NewNode;

										Redisplay = TRUE;
									}
									else
										FreeVecPooled(NewNode);
								}

								LT_UnlockWindow(PanelWindow);

								LT_ShowWindow(Handle,TRUE);

								break;

							case GAD_REMOVE:

								if(--Count)
								{
									if(TimeDateNode->VanillaNode.ln_Succ->ln_Succ)
										NewNode = (struct TimeDateNode *)TimeDateNode->VanillaNode.ln_Succ;
									else
									{
										NewNode = (struct TimeDateNode *)TimeDateNode->VanillaNode.ln_Pred;

										TimeSelected--;
									}
								}

								MadeChanges = TRUE;

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	~0,
								TAG_DONE);

								Remove(TimeDateNode);

								FreeVecPooled(TimeDateNode);

								if(Count > 1)
								{
									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	Count,
									TAG_DONE);

									TimeDateNode = NewNode;

									Redisplay = TRUE;
								}
								else
								{
									DisableGadgets(Handle,TRUE,TRUE,FALSE);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	~0,
									TAG_DONE);

									TimeDateNode = NULL;
								}

								break;

							case GAD_CLONE:

								if(NewNode = CreateTimeDateNode(0,1,"",TimeDateNode->Table[0].Count))
								{
									MadeChanges = TRUE;

									strcpy(NewNode->VanillaNode.ln_Name = NewNode->Buffer,TimeDateNode->Buffer);

									NewNode->Header = TimeDateNode->Header;

									CopyMem(TimeDateNode->Table,NewNode->Table,sizeof(struct TimeDate) * TimeDateNode->Table[0].Count);

									AdaptTimeDateNode(NewNode);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	~0,
									TAG_DONE);

									AddTail((struct List *)TimeDateList,&NewNode->VanillaNode);

									LT_SetAttributes(Handle,GAD_LIST,
										GTLV_Labels,	TimeDateList,
										GTLV_Selected,	Count++,
									TAG_DONE);

									TimeDateNode = NewNode;

									Redisplay = TRUE;
								}

								break;

							case GAD_EDIT:

								LT_LockWindow(PanelWindow);

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	~0,
								TAG_DONE);

								if(TimeDateNode->Header.Month == -1)
									MadeChanges |= DayPanel(PanelWindow,TimeDateNode);
								else
									MadeChanges |= DatePanel(PanelWindow,TimeDateNode);

								AdaptTimeDateNode(TimeDateNode);

								LT_SetAttributes(Handle,GAD_LIST,
									GTLV_Labels,	TimeDateList,
									GTLV_Selected,	Selected,
								TAG_DONE);

								LT_UnlockWindow(PanelWindow);

								LT_ShowWindow(Handle,TRUE);

								break;
						}
					}

					if(Redisplay)
					{
						Redisplay = FALSE;

						LT_SetAttributes(Handle,GAD_TIME,
							GTLV_Labels,	~0,
						TAG_DONE);

						FreeVecPooled(TimeList);

						if(TimeList = BuildTimeList(TimeDateNode))
						{
							if(TimeSelected == ~0)
								TimeSelected = 0;

							DisableGadgets(Handle,FALSE,TRUE,FALSE);

							Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_FIRST_UNIT],PayString1);

							LT_SetAttributes(Handle,GAD_PAY1,
								GTST_String,	PayString1,
							TAG_DONE);

							Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_FIRST_UNIT],TimeString1);

							LT_SetAttributes(Handle,GAD_MINUTES1,
								GTST_String,	TimeString1,
							TAG_DONE);

							Rate2String(TimeDateNode->Table[TimeSelected].PayPerUnit[DT_NEXT_UNIT],PayString2);

							LT_SetAttributes(Handle,GAD_PAY2,
								GTST_String,	PayString2,
							TAG_DONE);

							Rate2String(TimeDateNode->Table[TimeSelected].SecPerUnit[DT_NEXT_UNIT],TimeString2);

							LT_SetAttributes(Handle,GAD_MINUTES2,
								GTST_String,	TimeString2,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_TIME,
								GTLV_Labels,	TimeList,
								GTLV_Selected,	TimeSelected,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_ADDTIME,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_REMOVETIME,
								GA_Disabled,	TimeDateNode->Table[0].Count < 2,
							TAG_DONE);

							LT_SetAttributes(Handle,GAD_EDITTIME,
								GA_Disabled,	FALSE,
							TAG_DONE);

							LT_Activate(Handle,GAD_PAY1);
						}
						else
						{
							TimeDateNode = NULL;

							LT_SetAttributes(Handle,GAD_LIST,
								GTLV_Labels,	TimeDateList,
								GTLV_Selected,	~0,
							TAG_DONE);

							Selected = ~0;

							LT_SetAttributes(Handle,GAD_TIME,
								GTLV_Labels,	NULL,
								GTLV_Selected,	~0,
							TAG_DONE);

							TimeSelected = ~0;

							DisableGadgets(Handle,TRUE,TRUE,TRUE);

							DisplayBeep(PanelWindow->WScreen);
						}
					}
				}
			}
			while(!Done);

			PopWindow();

			FreeVecPooled(TimeList);
		}

		LT_DeleteHandle(Handle);
	}

	return(MadeChanges);
}
