/***********************************************
	IDCMP Handler For Contact97
************************************************/

void ShowAboutContact97(void);
void ShowEditContact97(char *name);
void ShowFindContact97(void);
void WriteDataFile(void);
void updateStrGad(struct Window *win, struct Gadget *gad, UBYTE *newstr);
void AddName(struct List *, struct List *, UBYTE *);
void FreeNameNodes(struct List * list, int type);
void UpdateLVList(struct Window *win,struct Gadget *gad,struct List *list,int num);
struct List *FindAddrName(struct List *list, UBYTE *name);
void AddAddr(struct List *list, struct AddressAddress *addrnode);
void DeleteAddressLine(struct List *list,long number, int DelMode);
void DeleteAddressName(struct List *list, UBYTE *name, int type);
void NewAddrName(struct List *list, UBYTE *name);
void LoadContactData(struct List *list1, struct List *list2);
int ReadLine(char *s, int sdblim, FILE *input);
char *substr(char *from, long start,long cnt);
long ScanField(char *line,long start);
void SaveDataFile(FILE *output,struct List *list, long DelMode);
void DummyProjectIDCMP(struct Window *wnd);
void AddTempName(struct List *list, struct NameNode *addrnode);
void CheckName(struct List *list, UBYTE *name, struct Node *node);
void CheckString(struct List *list, UBYTE *item, UBYTE *name, struct Node *node);
struct List *FindItThen(UBYTE *name);
void FindItWhen(struct List *list,UBYTE *name);
void CheckAddress(struct List *list, UBYTE *name, struct Node *node);
char *LocateFoundNode(struct List *list,long item);
void PrintAddrNodes(struct List *list, char type[]);
int WaitForPrinter(void);
int PrintItNow(char *title,char *text);
int PrintNameTitles(void);
int PrintAddrNodes2(char *name, char type[]);
int PrintItLine(char *title,char *text);

/***********************************************
	Check for DblClick on Main Listview
************************************************/

int NameList01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	long result=0;
	long selected=-1;

	result=GT_GetGadgetAttrs(Project0Gadgets[4],Project0Wnd,NULL,GTLV_Selected,&selected,TAG_END);
	if(result==1 && selected_g==selected)
	{
		Name01Clicked();
		selected =-1;
	}
	selected_g=selected;

	ActivateGadget(Project0Gadgets[3],Project0Wnd,NULL);
			
}

/***********************************************
	Add New Name Record Clicked
************************************************/

int Add01Clicked( void )
{
	/* routine when gadget "Add" is clicked. */

	if(Contact97Request(Project0Wnd,"Ok To Add New Name??\0","Ok|Cancel\0")==100)
	{
		if (FindName(NameList010List,GetString(Project0Gadgets[3]))==0)
		{
			AddName(NameList010List,AddrList010List,GetString(Project0Gadgets[3]));
			Edit01Clicked();
			UpdateLVList(Project0Wnd,Project0Gadgets[4],NameList010List,1);


		}
		else
		{
			Contact97Request(Project0Wnd,"Duplicate Name - Unable To Add\0","Ok\0");
		}
	}
}

/***********************************************
	Edit Record Clicked
************************************************/

int Edit01Clicked( void )
{
	/* routine when gadget "Edit" is clicked. */

	ShowEditContact97(GetString(Project0Gadgets[3]));

}

/***********************************************
	Quit Contact97 Clicked	
************************************************/

int Quit01Clicked( void )
{
	/* routine when gadget "Quit" is clicked. */
	return Project0CloseWindow();
}

/***********************************************
	Main LView entry box selected
************************************************/

int Name01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	if(Project0RawKey()!=95)
	{
		if(FindName(NameList010List,GetString(Project0Gadgets[3]))==0)
		{
			Add01Clicked();
		}
		else
		{
			Edit01Clicked();
		}
	}
}

/***********************************************
	Find Button Clicked
************************************************/

int Find01Clicked( void )
{
	/* routine when gadget "Find" is clicked. */

	ShowFindContact97();

}

/***********************************************
	Address LView Clicked
************************************************/

int Address01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	ActivateGadget(Project1Gadgets[12],Project1Wnd,NULL);
	
}

/***********************************************
	Add New Address Line Clicked
************************************************/

int AddAddress01Clicked( void )
{
        struct AddressAddress *addrnode=AllocMem(sizeof(struct AddressAddress),MEMF_CLEAR);

	AddAddr(addrlist_g, addrnode);

	UpdateLVList(Project1Wnd,Project1Gadgets[13],addrlist_g,1);

	GT_SetGadgetAttrs(Project1Gadgets[13],Project1Wnd,NULL,GTLV_Selected,999,GTLV_Top,999,TAG_END);

	ActivateGadget(Project1Gadgets[12],Project1Wnd,NULL);

}

/***********************************************
	Delete Selected Address Line
************************************************/

int DelAddress01Clicked( void )
{
	/* routine when gadget "-" is clicked. */

	long result=0;
	long selected=0;

	result=GT_GetGadgetAttrs(Project1Gadgets[13],Project1Wnd,NULL,GTLV_Selected,&selected,TAG_END);
	if(result==1)
	{
		DeleteAddressLine(addrlist_g,selected,0);
		UpdateLVList(Project1Wnd,Project1Gadgets[13],addrlist_g,1);
	}
}

/***********************************************
	Keep Changes to Name / Address
************************************************/

int OkNew01Clicked( void )
{
	/* routine when gadget "Ok" is clicked on Edit Window. */

	struct NameNode *namenode;

	if((namenode=(struct NameNode *)FindName(NameList010List,GetString(Project1Gadgets[10])))!=0)
	{
		strcpy(namenode->nn_Address.AddrComp, GetString(Project1Gadgets[11]));
		strcpy(namenode->nn_Address.AddrEmail, GetString(Project1Gadgets[14]));
		strcpy(namenode->nn_Address.AddrTel, GetString(Project1Gadgets[15]));
		strcpy(namenode->nn_Address.AddrFax, GetString(Project1Gadgets[16]));

		DeleteAddressName(AddrList010List,GetString(Project1Gadgets[10]),0);
		NewAddrName(addrlist_g, GetString(Project1Gadgets[10]));
	}
return 100;	
}

/***********************************************
	Cancel Changes to name /address
************************************************/

int AddCancel01Clicked( void )
{
	/* routine when gadget "Cancel" is clicked. */
	return 100;
}

/***********************************************
	Ignore Next 2 routines
************************************************/


int ContactName01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	Project1RawKey();
}

int CompanyName01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	Project1RawKey();
}

/***********************************************
	Update Address Item
************************************************/

int AddressText01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	long result=0;
	long selected=0;

	result=GT_GetGadgetAttrs(Project1Gadgets[13],Project1Wnd,NULL,GTLV_Selected,&selected,TAG_END);
	
	if(result==1 && Project1RawKey()!=95)
	{
		DeleteAddressLine(addrlist_g,selected,1);
		UpdateLVList(Project1Wnd,Project1Gadgets[13],addrlist_g,1);
	}
}

/***********************************************
	Ignore next 3 routines
************************************************/

int EmailEntry01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	Project1RawKey();
}

int PhoneEntry01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	Project1RawKey();
}

int FaxEntry01Clicked( void )
{
	/* routine when gadget "" is clicked. */

	Project1RawKey();
}


int AboutOk1Clicked( void )
{
	/* routine when gadget "Continue" is clicked. */
	return 100;
}

int Project0Item0( void )
{
	/* routine when (sub)item "Add" is selected. */

	Add01Clicked();

}

int Project0Edit01( void )
{
	/* routine when (sub)item "Edit" is selected. */

	Edit01Clicked();

}

int Project0Find01( void )
{
	/* routine when (sub)item "Find" is selected. */

	ShowFindContact97();

}

int Project0About01( void )
{
	/* routine when (sub)item "About" is selected. */

	ShowAboutContact97();
return 0;
}

int Project0Quit01( void )
{
	/* routine when (sub)item "Quit" is selected. */
	return Project0CloseWindow();
}

int Project0CloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */

	int reply=0;

	reply=Contact97Request(Project0Wnd,"Save Contact97 Data Changes??\0","Yes|No\0");

	if(reply !=0)
	{
		WriteDataFile();
	}

	return Contact97Request(Project0Wnd,"Quit Contact97??\0","Ok|Cancel\0");
}

int Project1CloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */

	return 100;
}

int Project2CloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */
	return 100;
}

int Project3CloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */
	return 100;
}



/***********************************************
	Show Contact97 AboutBox
************************************************/

void ShowAboutContact97(void)
{
	int runninga=0;

	OpenProject3Window();

	while(runninga!=100)
	{
		runninga=HandleProject3IDCMP();
		DummyProjectIDCMP(Project0Wnd);
	}

	CloseProject3Window();

}



/***********************************************
	Kill Contact97 (Ok|Cancel)
************************************************/

int Contact97Request(struct Window *Win, char *MessageRequest, char *ReplyGadget)
{
	struct EasyStruct Contact97ES = {
		sizeof (struct EasyStruct),
		0,
		"Contact97 Request",
		MessageRequest,
		ReplyGadget
		};
	int reply =0;

	reply=EasyRequest( Win, &Contact97ES, NULL, NULL);

	if(reply ==1)
	{
		reply =100;
	}
	return reply;
}

/***********************************************
	Show Contact97 Edit Window
************************************************/

void ShowEditContact97(char *name)
{
	int runninga=0;

	struct NameNode *namenode;
	struct List *addrnode;

	if((namenode=(struct NameNode *)FindName(NameList010List,name))!=0)
	{
		addrnode=FindAddrName(AddrList010List,name);
		addrlist_g=addrnode;

		OpenProject1Window();

		updateStrGad(Project1Wnd,Project1Gadgets[10],name);
		updateStrGad(Project1Wnd,Project1Gadgets[11],namenode->nn_Address.AddrComp);
		updateStrGad(Project1Wnd,Project1Gadgets[14],namenode->nn_Address.AddrEmail);
		updateStrGad(Project1Wnd,Project1Gadgets[15],namenode->nn_Address.AddrTel);
		updateStrGad(Project1Wnd,Project1Gadgets[16],namenode->nn_Address.AddrFax);

		UpdateLVList(Project1Wnd,Project1Gadgets[13],addrnode,1);
		
		while(runninga!=100)
		{
			runninga=HandleProject1IDCMP();

			if(Project0Wnd!=NULL)
			{
				DummyProjectIDCMP(Project0Wnd);
			}

			if(Project2Wnd!=NULL)
			{
				DummyProjectIDCMP(Project2Wnd);
			}
		
		}

		CloseProject1Window();

		addrlist_g=NULL;
	}
}

/***********************************************
	Show Contact97 Find Window
************************************************/

void ShowFindContact97(void)
{
	int runninga=0;
	OpenProject2Window();

	ActivateGadget(Project2Gadgets[4],Project2Wnd,NULL);

	while(runninga!=100)
	{
		runninga=HandleProject2IDCMP();
		DummyProjectIDCMP(Project0Wnd);		
	}

	CloseProject2Window();
}

/***********************************************
	Open Contact97.dat for Write Access
************************************************/

void WriteDataFile(void)
{
	FILE *output;

	output=fopen("s:contact97.dat","w");
	if(output >0)
	{
		SaveDataFile(output,NameList010List,0);
		SaveDataFile(output,AddrList010List,1);
		fclose(output);
	}
	else
	{
		Contact97Request(Project0Wnd,"Unable to Save Contact97 Data\0","Ok\0");
	}
}
	

/************************************************
	Load Contact97 Data File (contact97.dat)
*************************************************/

void LoadContactData(struct List *list1, struct List *list2)
{
	char *arg;
	char line[141];
	long start=0;
	long end=0;
	struct NameNode *namenode;
	struct AddressAddress *addrnode;

	int i=0;
	FILE *input=fopen("s:contact97.dat","r");
	
	if(input >0)
	{
		while(!feof(input))
		{
			ReadLine(line,140,input);
			
			start=ScanField(line,0);
			arg=substr(line,0,start);

			if(strcmp("01",arg)==0 || strcmp("02",arg)==0)
			{
				start++;

				if(strcmp("01",arg)==0)
				{
					free(arg);

					namenode=AllocMem(sizeof(struct NameNode),MEMF_CLEAR);
					if(!(namenode))
					{
					}
					else
					{
				/************************************************
					Data field 1
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(namenode->nn_Address.AddrName,arg);

						start=start+end+1;
						free(arg);

				/************************************************
					Data field 2
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(namenode->nn_Address.AddrComp,arg);

						start=start+end+1;

						free(arg);

				/************************************************
					Data field 3
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(namenode->nn_Address.AddrEmail,arg);

						start=start+end+1;

						free(arg);

				/************************************************
					Data field 4
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(namenode->nn_Address.AddrTel,arg);

						start=start+end+1;

						free(arg);

				/************************************************
					Data field 5
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(namenode->nn_Address.AddrFax,arg);

						start=start+end+1;

						free(arg);
        					namenode->nn_Node.ln_Name = namenode->nn_Address.AddrName;
        					namenode->nn_Node.ln_Type = NAMENODE_ID;
        					namenode->nn_Node.ln_Pri  = 0;
        					AddTail((struct List *)list1,(struct Node *)namenode);
					}

				}
				if(strcmp("02",arg)==0)
				{
					free(arg);

					addrnode=AllocMem(sizeof(struct AddressAddress),MEMF_CLEAR);
					if(!(addrnode))
					{
					}
					else
					{
				/************************************************
					Data field 1
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						addrnode->nn_Node.ln_Name=((struct NameNode *)FindName(list1,arg))->nn_Address.AddrName;

						start=start+end+1;
						free(arg);

				/************************************************
					Data field 2
				*************************************************/
										
						end=ScanField(line,start);
						arg=substr(line,start,end);

						strcpy(addrnode->nn_Data,arg);

						start=start+end+1;

						free(arg);

        					addrnode->nn_Node.ln_Type = ADDRNODE_ID;
        					addrnode->nn_Node.ln_Pri  = 0;
        					AddTail((struct List *)list2,(struct Node *)addrnode);
					}
				}
			}
			else
			{
				free(arg);
			}

		}
		fclose(input);
	}
}

/************************************************
	Read a line from the Contact Data file
*************************************************/

int ReadLine(char *s, int sdblim, FILE *input)
{
	int c,i;
	for(i=0;i<sdblim-1 && (c=getc(input))!=EOF && c!='\n';i++)
	{
		s[i]=c;
	}
	s[i]='\0';
return i;
}

/************************************************
	Obtain a sub string from string
*************************************************/

char *substr(char *from,long start,long cnt)
{
	char *arg;
	arg=calloc(sizeof(char),cnt+1);
	strncpy(arg,&from[start],cnt);
	arg[cnt]='\0';
return arg;
}


/************************************************
	Find Length of Data Field
*************************************************/

long ScanField(char *line,long start)
{
return	strcspn(&line[start],",\n");
}

/************************************************
	Update string gadget to show new entry
*************************************************/

void updateStrGad(struct Window *win, struct Gadget *gad, UBYTE *newstr)
{

/************************************************
	remove gadget from display before changing contents
*************************************************/

	RemoveGList(win,gad,1);

/************************************************
	Change contents and reset current cursor positions in string
*************************************************/
	
	strcpy(((struct StringInfo *) (gad->SpecialInfo))->Buffer,newstr);

	((struct StringInfo *)(gad->SpecialInfo))->BufferPos =0;
	((struct StringInfo *)(gad->SpecialInfo))->DispPos =0;

/************************************************
	Add Gadget back to display and refresh
*************************************************/

	AddGList(win,gad,~0,1,NULL);
	RefreshGList(gad,win,NULL,1);

/************************************************
	Finally re-activate string gadget
*************************************************/

	ActivateGadget(gad,win,NULL);

}

/***********************************************
	Add New Record to List(s)
************************************************/

void AddName(struct List *list, struct *list2, UBYTE *name)
{
	struct NameNode *namenode;
	struct AddressAddress *addrnode;

	namenode = AllocMem(sizeof(struct NameNode),MEMF_CLEAR);
	addrnode = AllocMem(sizeof(struct AddressAddress),MEMF_CLEAR);

    	if (!(namenode) || !(addrnode))
	{
	}
    	else
	{
        	strcpy(namenode->nn_Address.AddrName,name);
        	namenode->nn_Node.ln_Name = namenode->nn_Address.AddrName;
        	namenode->nn_Node.ln_Type = NAMENODE_ID;
        	namenode->nn_Node.ln_Pri  = 0;
        	AddHead((struct List *)list,(struct Node *)namenode);

		addrnode->nn_Node.ln_Name = namenode->nn_Address.AddrName; 
        	addrnode->nn_Node.ln_Type = ADDRNODE_ID;
        	addrnode->nn_Node.ln_Pri  = 0;
        	AddTail((struct List *)list2,(struct Node *)addrnode);
    	}
}

void UpdateLVList(struct Window *win,struct Gadget *gad,struct List *list,int num)
{
	/************************************************
		Remove Gadget prior to update
	*************************************************/

	RemoveGList(win,gad,num);

	/************************************************
		Update ListView Display
	*************************************************/

	GT_SetGadgetAttrs(gad,win,NULL,GTLV_Labels,~0,TAG_DONE);
	GT_SetGadgetAttrs(gad,win,NULL,GTLV_Labels,list,TAG_DONE);

	/************************************************
		Gadget updated now add back to window
	*************************************************/

	AddGList(win,gad,~0,num,NULL);
	RefreshGList(gad,win,NULL,num);

	/*
		Done???
	*/
}

/***********************************************
 	Find Name in Address Master and create temp list of Address
************************************************/

struct List *FindAddrName(struct List *list, UBYTE *name)
{
	struct AddrAddress *node2;

	struct List *list2;

	list2=AllocMem(sizeof(struct List),MEMF_CLEAR);

	NewList(list2);

	if (node2 =(struct AddressAddress *) FindName(list,name)) 
	{
		while(node2>0)
		{
			AddAddr(list2,node2);
			node2 = (struct AddressAddress *)FindName(node2,name);
		}
       		
	
    	}
return list2;
}

/***********************************************
	Allocate a AddrNode structure, copy the given name into the structure,
	then add it the specified list.  
************************************************/

void AddAddr(struct List *list, struct AddressAddress *addrnode)
{
	struct AddressAddress *namenode=AllocMem(sizeof(struct AddressAddress),MEMF_CLEAR);
	if(!(namenode))
	{
	}
	else
	{
        	namenode->nn_Node.ln_Name = addrnode->nn_Data;
        	namenode->nn_Node.ln_Type = NAMENODE_ID;
        	namenode->nn_Node.ln_Pri  = 0;
        	AddTail((struct List *)list,(struct Node *)namenode);
	}
}

/***********************************************
	Delete / Update the Address Line Selected in a list.
************************************************/

void DeleteAddressLine(struct List *list,long number, int DelMode)
{
struct Node *node;

	long count=0;

	if (list->lh_TailPred == (struct Node *)list)
	{
	} 
	else
	{
		for (node = list->lh_Head ; node->ln_Succ ; node = node->ln_Succ)
		{
			if(count==number && count >=0)
			{
				if(DelMode ==0)
				{
					Remove(node);
					FreeMem(node,sizeof(struct AddressAddress));
				}
				else
				{
					strcpy(node->ln_Name,GetString(Project1Gadgets[12]));
				}
			}
			count++;
		}
	}
}

/***********************************************
	Delete ALL Address Nodes with a specified name.
************************************************/

void DeleteAddressName(struct List *list, UBYTE *name, int type)
{
	struct Node *node;

	if (node = FindName(list,name))
	{
		while(node>0)
		{
			Remove(node);
			if(type==0)
			{
				FreeMem(node,sizeof(struct AddressAddress));
			}
			else
			{
				FreeMem(node,sizeof(struct NameNode));
			}
			node = FindName(list,name);
		}
	}
}

/***********************************************
	Add Back changes to Address list for Name
************************************************/

void NewAddrName(struct List *list, UBYTE *name)
{
	struct NameNode *namenode;
	struct Node *node;
	struct AddressAddress *addrname;

	namenode=(struct NameNode *)FindName(NameList010List,name);

	while (list->lh_TailPred!=(struct List *)list) 
	{
		node=(struct node *)list->lh_Head;
		Remove(node);

		addrname=(struct AddressAddress *)node;
		strcpy(addrname->nn_Data,addrname->nn_Node.ln_Name);
		addrname->nn_Node.ln_Name = namenode->nn_Address.AddrName;
		
        	AddTail((struct List *)AddrList010List,(struct Node *)addrname);		
    	}
}

/***********************************************
	Save Data File to Contact97.dat
************************************************/

void SaveDataFile(FILE *output,struct List *list, long DelMode)
{
	struct Node *node;
	struct NameNode *namenode;
	struct AddressAddress *addrnode;

	if (list->lh_TailPred == (struct Node *)list)
	{
	} 
	else
	{
		for (node = list->lh_Head ; node->ln_Succ ; node = node->ln_Succ)
		{
			if(DelMode ==0)
			{
				namenode=(struct NameNode *)node;
				fprintf(output,"01,%s,%s,%s,%s,%s\n",namenode->nn_Address.AddrName,namenode->nn_Address.AddrComp,namenode->nn_Address.AddrEmail,namenode->nn_Address.AddrTel,namenode->nn_Address.AddrFax);
			}
			else
			{
				addrnode=(struct AddressAddress *)node;
				fprintf(output,"02,%s,%s\n",addrnode->nn_Node.ln_Name,addrnode->nn_Data);
			}
		}
	}
}

/***********************************************
	Delete Selected Name from Names/Address
************************************************/

int Delete01Clicked( void )
{
	/* routine when gadget "Delete" is clicked. */

	int reply=0;

	reply=Contact97Request(Project0Wnd,"*** Delete Selected Name?? ***\0","Ok|Cancel\0");

	if(reply !=0)
	{
		if (FindName(NameList010List,GetString(Project0Gadgets[3]))!=0)
		{
			DeleteAddressName(AddrList010List,GetString(Project0Gadgets[3]),0);
			DeleteAddressName(NameList010List,GetString(Project0Gadgets[3]),1);
			UpdateLVList(Project0Wnd,Project0Gadgets[4],NameList010List,1);
		}
			
	}


}

/***********************************************
	Delete Name selected (menu)
************************************************/

int Project0Delete01( void )
{
	/* routine when (sub)item "Delete Name" is selected. */

	return Delete01Clicked();
}

/***********************************************
	Disable Project Window Gadgets
************************************************/

void DummyProjectIDCMP(struct Window *wnd )
{
	struct IntuiMessage	*m;

	while( m = GT_GetIMsg( wnd->UserPort ))
	{

		GT_ReplyIMsg( m );

	}
}

/***********************************************
	Free List Nodes of type Name / Address
************************************************/

void FreeNameNodes(struct List *list,int type)
{
	struct Node *node;

	while(list->lh_TailPred!=(struct Node *)list)
	{
		node=(struct Node *)list->lh_Head;
		Remove(node);

		if(type==0)
		{
			FreeMem(node,sizeof(struct AddressAddress));
		}
		else
		{
			FreeMem(node,sizeof(struct NameNode));
		}
	}

}

/***********************************************
	Find sub-string entered
************************************************/

int FindContact01Clicked( void )
{
	/* routine when gadget "Find" is clicked. */

	if(Project2RawKey()!=95)
	{
		GT_SetGadgetAttrs(Project2Gadgets[2],Project2Wnd,NULL,GTLV_Labels,~0,TAG_DONE);

		namelist_g=FindItThen(GetString(Project2Gadgets[4]));

		UpdateLVList(Project2Wnd,Project2Gadgets[2],namelist_g,1);	
	
		ActivateGadget(Project2Gadgets[4],Project2Wnd,NULL);
	}	
}

/***********************************************
	Cancel Find window
************************************************/

int CancelFind01Clicked( void )
{
	/* routine when gadget "Cancel" is clicked. */
	return 100;
}

/***********************************************
	Find Item Found Selection
************************************************/

int FindResult01Clicked( void )
{
	/* routine when gadget "Result" is clicked. */

	char *name=NULL;
	long result=0;
	long selected=-1;

	result=GT_GetGadgetAttrs(Project2Gadgets[2],Project2Wnd,NULL,GTLV_Selected,&selected,TAG_END);

	if(result==1 && selected_g==selected)
	{
		name=LocateFoundNode(namelist_g,selected);
		
		if(name!=NULL) ShowEditContact97(name);

		selected =-1;
	}
	selected_g=selected;

	ActivateGadget(Project2Gadgets[4],Project2Wnd,NULL);	

}

/***********************************************
	Find sub-string entered
************************************************/

int FindEdit01Clicked( void )
{
	/* routine when gadget "" is clicked. */

return	FindContact01Clicked();
}

/***********************************************
	Allocate a AddrNode structure, copy the given name into the structure,
	then add it the specified list.  
************************************************/

void AddTempName(struct List *list, struct NameNode *addrnode)
{
	struct Node *namenode=AllocMem(sizeof(struct Node),MEMF_CLEAR);
	if(!(namenode))
	{
	}
	else
	{
        	namenode->ln_Name = addrnode->nn_Address.AddrName;
        	namenode->ln_Type = NAMENODE_ID;
        	namenode->ln_Pri  = 0;
        	AddTail((struct List *)list,(struct Node *)namenode);
	}
}

struct List *FindItThen(UBYTE *name)
{
	struct Node *node;
	struct List *list2;
	long selected;
	long result;

	list2=AllocMem(sizeof(struct List),MEMF_CLEAR);

	NewList(list2);

	namelist_g=list2;

	if(node=FindName(NameList010List,name))
	{
		result=GT_GetGadgetAttrs(Project2Gadgets[12],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckName(list2,name,node);
		}
	}
	else
	{
		FindItWhen(list2,name);
	}
return list2;
}

void FindItWhen(struct List *list,UBYTE *name)
{
	struct Node *node;
	long selected;
	long result;

	for(node=NameList010List->lh_Head;node->ln_Succ;node=node->ln_Succ)
	{
		result=GT_GetGadgetAttrs(Project2Gadgets[12],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckString(list,((struct NameNode *)node)->nn_Address.AddrName,name,node);	
		}

		result=GT_GetGadgetAttrs(Project2Gadgets[6],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckString(list,((struct NameNode *)node)->nn_Address.AddrComp,name,node);	
		}

		result=GT_GetGadgetAttrs(Project2Gadgets[8],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckString(list,((struct NameNode *)node)->nn_Address.AddrEmail,name,node);	
		}

		result=GT_GetGadgetAttrs(Project2Gadgets[9],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckString(list,((struct NameNode *)node)->nn_Address.AddrTel,name,node);	
		}

		result=GT_GetGadgetAttrs(Project2Gadgets[10],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckString(list,((struct NameNode *)node)->nn_Address.AddrFax,name,node);	
		}

		result=GT_GetGadgetAttrs(Project2Gadgets[7],Project2Wnd,NULL,GTCB_Checked,&selected,TAG_END);
		if(result==1 && selected==TRUE)
		{
			CheckAddress(list,name,node);
		}
	}
}

void CheckString(struct List *list, UBYTE *item, UBYTE *name, struct Node *node)
{
	char *item1;
	char *name1;
	int i;

	item1=calloc(strlen(item)+1,sizeof(char));
	name1=calloc(strlen(name)+1,sizeof(char));


	for(i=0;i<=strlen(item);i++)
	{
		item1[i]=ToUpper(item[i]);
	}

	for(i=0;i<=strlen(name);i++)
	{
		name1[i]=ToUpper(name[i]);
	}

	if(strstr(item1,name1)!=NULL)
	{
		CheckName(list,node->ln_Name,node);
	}

	if(item1!=NULL) free(item1);
	if(name1!=NULL) free(name1);
}

void CheckName(struct List *list, UBYTE *name, struct Node *node)
{
	if(FindName(namelist_g,name)!=0)
	{
	}
	else
	{
		AddTempName(namelist_g,(struct NameNode *)FindName(NameList010List,name));
	}
}

/***********************************************
 	Find sub-string in Address Master
************************************************/

void CheckAddress(struct List *list, UBYTE *name, struct Node *node)
{
	struct Node *node2;

	if (node2 =FindName(AddrList010List,((struct NameNode *)node)->nn_Node.ln_Name)) 
	{
		while(node2>0)
		{
			CheckString(list,((struct AddressAddress *)node2)->nn_Data,name,node);
			node2 = FindName(node2,((struct NameNode *)node)->nn_Node.ln_Name);
		}
       		
	
    	}
}

int fndchk01Clicked( void )
{
	/* routine when gadget "Company" is clicked. */
	ActivateGadget(Project2Gadgets[4],Project2Wnd,NULL);	
}

int fndchk02Clicked( void )
{
	/* routine when gadget "Address" is clicked. */

return fndchk01Clicked();
}

int fndchk03Clicked( void )
{
	/* routine when gadget "Email" is clicked. */

return fndchk01Clicked();
}

int fndchk04Clicked( void )
{
	/* routine when gadget "Phone" is clicked. */

return fndchk01Clicked();
}

int fndchk05Clicked( void )
{
	/* routine when gadget "Fax" is clicked. */

return fndchk01Clicked();
}

int fndchk06Clicked( void )
{
	/* routine when gadget "Name" is clicked. */

return fndchk01Clicked();
}

char *LocateFoundNode(struct List *list,long item)
{
	struct Node *node;
	char *name=NULL;
	long count=0;

	if (list->lh_TailPred == (struct Node *)list)
	{
	} 
	else
	{
		for (node = list->lh_Head ; node->ln_Succ ; node = node->ln_Succ)
		{
			if(count==item && count >=0)
			{
				name=node->ln_Name;
			}
			count++;
		}
	}
return name;
}

int Project0RawKey( void )
{
	/* routine for "IDCMP_RAWKEY". */

	if(Project0Msg.Code ==95)
	{
		SendAmigaGuideCmd(Contact97Guide,"Main",AGA_Context,NULL,TAG_DONE);
	}
return Project0Msg.Code;
}

int Project1RawKey( void )
{
	/* routine for "IDCMP_RAWKEY". */

	if(Project1Msg.Code ==95)
	{
		SendAmigaGuideCmd(Contact97Guide,"Main",AGA_Context,NULL,TAG_DONE);
	}
return Project1Msg.Code;
}

int Project2RawKey( void )
{
	/* routine for "IDCMP_RAWKEY". */

	if(Project2Msg.Code ==95)
	{
		SendAmigaGuideCmd(Contact97Guide,"Main",AGA_Context,NULL,TAG_DONE);
	}
return Project2Msg.Code;
}

int Project3RawKey( void )
{
	/* routine for "IDCMP_RAWKEY". */

	if(Project3Msg.Code ==95)
	{
		SendAmigaGuideCmd(Contact97Guide,"Main",AGA_Context,NULL,TAG_DONE);
	}
return Project3Msg.Code;
}

/***********************************************
	Print Button on Edit Screen
************************************************/

int PrintIt01Clicked( void )
{
	/* routine when gadget "Print" is clicked. */

	struct NameNode *namenode;

	int reply=0;
	
	if(!(open_printer()))
	{
		
		if((namenode=(struct NameNode *)FindName(NameList010List,GetString(Project1Gadgets[10])))!=0)
		{
			init_printer();

			prt_ok_g=0;

			prt_ok_g=PrintItNow("Contact Name :", namenode->nn_Address.AddrName);

			if(prt_ok_g==0) prt_ok_g=PrintItNow("Company Name :", namenode->nn_Address.AddrComp);

			if(prt_ok_g==0) prt_ok_g=PrintItNow("Address      :",NULL);

			if(prt_ok_g==0) PrintAddrNodes(addrlist_g,"              ");

			if(prt_ok_g==0) prt_ok_g=PrintItNow("\nEmail        :", namenode->nn_Address.AddrEmail);

			if(prt_ok_g==0) prt_ok_g=PrintItNow("Telephone    :", namenode->nn_Address.AddrTel);

			if(prt_ok_g==0) prt_ok_g=PrintItNow("Fax          :", namenode->nn_Address.AddrFax);

			if(prt_ok_g==0) prt_ok_g=PrintItNow("--------------------------------------------------\n",NULL);

			if(prt_ok_g==0)
			{
				reply=Contact97Request(Project0Wnd,"FormFeed Printer??\0","Yes|No\0");

				if(reply !=0)
				{
					PrintItNow("\x0c",NULL);
				}
			}

		}
	}	
	close_printer();
}

/***********************************************
	Print Names + Numbers Menu item
************************************************/

int Project0Item1( void )
{
	/* routine when (sub)item "Names + Numbers" is selected. */

	struct PrinterData *PD;
	struct Preferences *prefs;
	struct Node *node;
	int cnt =3;

	prt_ok_g=0;

	int reply=0;
	reply=Contact97Request(Project0Wnd,"Print Names + Numbers??\0","Yes|No\0");

	if(reply !=0)
	{

		if(!(open_printer()))
		{
			init_printer();

			PD = (struct PrinterData *) pio->ios.io_Device;

			prefs = &PD->pd_Preferences;

			prt_ok_g=PrintNameTitles();

        		for (node=NameList010List->lh_Head; node->ln_Succ ; node = node->ln_Succ)
			{

				if(prt_ok_g==0) prt_ok_g=PrintItLine(((struct NameNode *)node)->nn_Address.AddrName, ((struct NameNode *)node)->nn_Address.AddrTel);
				if(prt_ok_g==0) prt_ok_g=PrintItNow("----------------------------------------------------\n",NULL);

				cnt+=2;

				if(prt_ok_g==0 && cnt >(prefs->PaperLength-2))
				{
					prt_ok_g=PrintItNow("\x0c",NULL);
					prt_ok_g=PrintNameTitles();
					cnt=3;
				}
	
			}

			if(prt_ok_g==0)
			{
				reply=Contact97Request(Project0Wnd,"FormFeed Printer??\0","Yes|No\0");
	
				if(reply !=0)
				{
					PrintItNow("\x0c",NULL);
				}
			}
		}
		close_printer();
	}
}

/***********************************************
	Print Names + Addresses Menu Item
************************************************/

int Project0Item2( void )
{
	/* routine when (sub)item "Names + Addresses" is selected. */

	struct PrinterData *PD;
	struct Preferences *prefs;
	struct Node *node;
	int cnt =0;

	prt_ok_g=0;

	int reply=0;
	reply=Contact97Request(Project0Wnd,"Print Names + Addresses??\0","Yes|No\0");

	if(reply !=0)
	{

		if(!(open_printer()))
		{
			init_printer();

			PD = (struct PrinterData *) pio->ios.io_Device;

			prefs = &PD->pd_Preferences;

        		for (node=NameList010List->lh_Head; node->ln_Succ ; node = node->ln_Succ)
			{

				PrintItNow("Contact Name :",((struct NameNode *) node)->nn_Address.AddrName);

				if(prt_ok_g==0) prt_ok_g=PrintItNow("Company Name :",((struct NameNode *) node)->nn_Address.AddrComp);

				if(prt_ok_g==0) prt_ok_g=PrintItNow("Address      :",NULL);

				if(prt_ok_g==0) cnt +=PrintAddrNodes2(((struct NameNode *) node)->nn_Address.AddrName,"              ");

				if(prt_ok_g==0) prt_ok_g=PrintItNow("\nEmail        :", ((struct NameNode *) node)->nn_Address.AddrEmail);

				if(prt_ok_g==0) prt_ok_g=PrintItNow("Telephone    :", ((struct NameNode *) node)->nn_Address.AddrTel);

				if(prt_ok_g==0) prt_ok_g=PrintItNow("Fax          :", ((struct NameNode *) node)->nn_Address.AddrFax);

				if(prt_ok_g==0) prt_ok_g=PrintItNow("--------------------------------------------------\n",NULL);


				cnt+=9;

				if(prt_ok_g==0 && cnt >=(prefs->PaperLength -9))
				{
					prt_ok_g=PrintItNow("\x0c",NULL);
					cnt=0;
				}
	
			}

			if(prt_ok_g==0)
			{
				reply=Contact97Request(Project0Wnd,"FormFeed Printer??\0","Yes|No\0");
	
				if(reply !=0)
				{
					PrintItNow("\x0c",NULL);
				}
			}
		}
		close_printer();
	}

}

/***********************************************
	Print Address Nodes for name
************************************************/

void PrintAddrNodes(struct List *list, char type[])
{
	struct Node *node;
	int cnt =0;

        for (node = list->lh_Head ; node->ln_Succ ; node = node->ln_Succ)
	{

		if(cnt!=0)
		{
			if(prt_ok_g==0) prt_ok_g=PrintItNow(type,((struct AddressAddress *)node)->nn_Node.ln_Name);			
		}
		else
		{
			if(prt_ok_g==0) prt_ok_g=PrintItNow(NULL,((struct AddressAddress *)node)->nn_Node.ln_Name);	
		}
		cnt++;
	}

}

/***********************************************
	Wait for Printer Messages
************************************************/

int WaitForPrinter(void)
{
	long signal=0;

	signal=Wait(1 << printMsgPort->mp_SigBit | SIGBREAKF_CTRL_C);

	if(signal & (1 << SIGBREAKF_CTRL_C))
	{
		AbortIO((struct IORequest *)pio);
		WaitIO((struct IORequest *)pio);
	}

	if(signal & (1 << printMsgPort->mp_SigBit))
	{
		while(GetMsg(printMsgPort));
	}
return pio->iodrp.io_Error;
}

/***********************************************
	Print Text to Printer
************************************************/
 
int PrintItNow(char *title,char *text)
{
	char buffer[100];
	if(title!=NULL && text!=NULL)
	{
		sprintf(buffer,"%s\t%s\n",title, text);
	}

	if(title==NULL && text!=NULL)
	{
		sprintf(buffer,"\t%s\n", text);
	}
	if(title!=NULL && text==NULL)
	{
		sprintf(buffer,"%s", title);
	}

	queue_write(buffer);

return WaitForPrinter();
}

/***********************************************
	Print Text to Printer
************************************************/
 
int PrintItLine(char *title,char *text)
{
	char buffer[100];
	if(title!=NULL && text!=NULL)
	{
		sprintf(buffer,"%-30s\t%20s\n",title, text);
	}

	queue_write(buffer);

return WaitForPrinter();
}

/***********************************************
	Print Titles for Names + Numbers
************************************************/

int PrintNameTitles(void)
{
	if(prt_ok_g==0) prt_ok_g=PrintItLine("Name", "Telephone");
	
	if(prt_ok_g==0) prt_ok_g=PrintItLine("====", "=========");

	if(prt_ok_g==0) prt_ok_g=PrintItNow("\n\n",NULL);	

return prt_ok_g;
}

/***********************************************
	Print Address Nodes for name 2
************************************************/

int PrintAddrNodes2(char *name, char type[])
{
	struct Node *node;
	int cnt =0;

        for (node =FindName(AddrList010List,name) ; node!=0 ; node = FindName((struct List *)node,name))
	{

		if(cnt!=0)
		{
			if(prt_ok_g==0) prt_ok_g=PrintItNow(type,((struct AddressAddress *)node)->nn_Data);			
		}
		else
		{
			if(prt_ok_g==0) prt_ok_g=PrintItNow(NULL,((struct AddressAddress *)node)->nn_Data);	
		}
		cnt++;
	}
return cnt-1;
}
