/*************************************************************************
**   File:  phone.c
**      contains phone library manipulation
**
**   Functions:
**	do_phlib() - presents and processes phone library requester
**	init_req() - initializes phone library requester structures
**	sav_phlib() - writes current phone library to disk file
**	load_phlib() - loads phone library from disk file
**	dial() - calls number from phone library
**	bld_bbs_men() - rebuilds phone library sub-menu for quick-dial
**
*************************************************************************/
#include "term.h"

extern int emits();
extern int emit();
extern struct Window *mywindow;
extern struct Menu menu[];
extern struct MenuItem PHItem[];


/*********************************************************************
*      Structures to define Requester and it's gadgets
*********************************************************************/

struct IntuiText ph_req_txt3 = {
	3,1,		/* front pen, back */
	JAM1,		/* draw mode */
	140,0,		/* relative start */
	NULL,		/* font */
	(UBYTE *) " Phone Library ", /* text */
	NULL		/* chain */
	};

struct IntuiText ph_req_txt2 = {
	3,1,		/* front pen, back */
	JAM1,		/* draw mode */
	48,30,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Name:", /* text */
	&ph_req_txt3	/* chain */
	};

struct IntuiText ph_req_txt1 = {
	3,1,		/* front pen, back */
	JAM1,		/* draw mode */
	218,30,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Number:", /* text */
	&ph_req_txt2	/* chain */
	};

struct IntuiText l_txt = {
	2,3,		/* front pen, back */
	JAM1,		/* draw mode */
	2,1,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Load", /* text */
	NULL		/* chain */
	};

struct IntuiText s_txt = {
	2,3,		/* front pen, back */
	JAM1,		/* draw mode */
	2,1,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Save", /* text */
	NULL		/* chain */
	};

struct IntuiText c_txt = {
	2,3,		/* front pen, back */
	JAM1,		/* draw mode */
	2,1,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Quit", /* text */
	NULL		/* chain */
	};

struct IntuiText d_txt = {
	2,0,		/* front pen, back */
	JAM1,		/* draw mode */
	2,1,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "DIAL", /* text */
	NULL		/* chain */
	};

struct IntuiText ph_nm_txt = {
	2,1,		/* front pen, back */
	JAM1,		/* draw mode */
	-48,0,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "File: ", /* text */
	NULL		/* chain */
	};

struct IntuiText pfx_txt = {
	2,1,		/* front pen, back */
	JAM1,		/* draw mode */
	-96,0,		/* relative start */
	NULL,		/* font */
	(UBYTE *) "Dial Prefix:", /* text */
	NULL		/* chain */
	};

#define Fil_Nam_Sz 128
#define Bbs_Ent_Sz 21
#define MAX_NUM 10

UBYTE fil_nam[Fil_Nam_Sz] = "Term.Phn";
UBYTE pfx_nam[Bbs_Ent_Sz] = "ATDT";
UBYTE undo_buf[Fil_Nam_Sz];
UBYTE bbs_name[MAX_NUM][Bbs_Ent_Sz+1];
UBYTE bbs_num[MAX_NUM][Bbs_Ent_Sz+1];

struct StringInfo ph_nm_buf = {
	fil_nam,	/* buffer */
	undo_buf,	/* undo buffer */
	0,		/* buf pos */
	Fil_Nam_Sz,	/* Max chars */
	0,		/* first disp pos */
	0,		/* Undo pos */
	13,		/*  current char count */
	0,0,0,
	NULL,NULL
	};

struct StringInfo pfx_buf = {
	pfx_nam,	/* buffer */
	undo_buf,	/* undo buffer */
	0,		/* buf pos */
	Bbs_Ent_Sz,	/* Max chars */
	0,		/* first disp pos */
	0,		/* Undo pos */
	4,		/*  current char count */
	0,0,0,
	NULL,NULL
	};

struct StringInfo bbs_name_s [MAX_NUM];

struct StringInfo bbs_num_s [MAX_NUM];

SHORT bord_cords[] = 
	{0,0,35,0,35,10,0,10,0,0};

struct Border bord = {
	0,-1,		/* left, top */
	2,1,JAM1,
	5,bord_cords,
	NULL
	};

/*   Macros for identifying gadgets   */

#define C_GAD		200
#define S_GAD		201
#define L_GAD		202
#define PH_NM_GAD	203
#define PFX_GAD		204

#define UP_C_GAD (gad->GadgetID == C_GAD)
#define UP_S_GAD (gad->GadgetID == S_GAD)
#define UP_L_GAD (gad->GadgetID == L_GAD)
#define UP_PH_NM_GAD (gad->GadgetID == PH_NM_GAD)
#define UP_PFX_GAD (gad->GadgetID == PFX_GAD)
#define UP_DIAL_GAD ((gad->GadgetID % 3) == 0)
#define UP_NAME_GAD ((gad->GadgetID % 3) == 1)
#define UP_NUM_GAD ((gad->GadgetID % 3) == 2)

#define GAD_LINE (gad->GadgetID / 3)


struct Gadget d_gad [MAX_NUM];

struct Gadget nam_gad [MAX_NUM];

struct Gadget num_gad [MAX_NUM];

struct Gadget pfx_gad = {
	&d_gad[0],	/* chain to next */
	100,22,		/* left, top */
	160,11,		/* width, height */
	GADGHCOMP,	/* flags */
	RELVERIFY,
	REQGADGET |
	STRGADGET,	/* gadget type */
	NULL, NULL,	/* render ptrs */
	&pfx_txt,	/* gadget label */
	NULL,		/* exclude */
	(APTR)&pfx_buf,	/* string buffers */
	PFX_GAD,		/* gadget id */
	NULL		/* user data */
	};

struct Gadget c_gad = {
	&pfx_gad,	/* chain to next */
	330,10,		/* left, top */
	35,11,		/* width, height */
	GADGHCOMP,	/* flags */
	RELVERIFY |
	ENDGADGET,
	REQGADGET |
	BOOLGADGET,	/* gadget type */
	(APTR)&bord, NULL,	/* render ptrs */
	&c_txt,		/* gadget label */
	NULL,		/* exclude */
	NULL,
	C_GAD,		/* gadget id */
	NULL		/* user data */
	};

struct Gadget s_gad = {
	&c_gad,		/* chain to next */
	288,10,		/* left, top */
	35,11,		/* width, height */
	GADGHCOMP,	/* flags */
	RELVERIFY,	/* activation */
	REQGADGET |
	BOOLGADGET,	/* gadget type */
	(APTR)&bord, NULL,	/* render ptrs */
	&s_txt,		/* gadget label */
	NULL,		/* exclude */
	NULL,
	S_GAD,		/* gadget id */
	NULL		/* user data */
	};

struct Gadget l_gad = {
	&s_gad,		/* chain to next */
	245,10,		/* left, top */
	35,11,		/* width, height */
	GADGHCOMP,	/* flags */
	RELVERIFY,	/* activation */
	REQGADGET |
	BOOLGADGET,	/* gadget type */
	(APTR)&bord, NULL,	/* render ptrs */
	&l_txt,		/* gadget label */
	NULL,		/* exclude */
	NULL,
	L_GAD,		/* gadget id */
	NULL		/* user data */
	};

struct Gadget ph_nm_gad = {
	&l_gad,		/* chain to next */
	60,10,		/* left, top */
	160,11,		/* width, height */
	GADGHCOMP,	/* flags */
	RELVERIFY,
	REQGADGET |
	STRGADGET,	/* gadget type */
	NULL, NULL,	/* render ptrs */
	&ph_nm_txt,	/* gadget label */
	NULL,		/* exclude */
	(APTR)&ph_nm_buf,	/* string buffers */
	PH_NM_GAD,		/* gadget id */
	NULL		/* user data */
	};

struct Requester ph_req = {
	NULL,		/* backwards chain */
	30,10,		/* left, top */
	400,160,	/* width, height */
	NULL,NULL,	/* pointer relatives */
	&ph_nm_gad,	/* first gadget */
	NULL,		/* border */
	&ph_req_txt1,	/* Requester text */
	NULL,		/* flags */
	1,		/* backfill */
	NULL,		/* clip req */
	NULL,		/*  bit map */
	NULL		/* bit map */
	};


/*********************************************************************
*      Structures to define Dial Sub-menu
*********************************************************************/
struct MenuItem bbs_men[MAX_NUM];
struct IntuiText bbs_txt[MAX_NUM];

/********************************************************************
*   Function to handle PhoneLib Requester                           *
********************************************************************/

do_phlib()
{
	static short init_ok = 0;

	int looping = TRUE;
	short dirty = 0;
	struct IntuiMessage *mes;
	struct Gadget *gad;
	ULONG class;

	if (!init_ok) {
		init_req();
		init_ok = 1;
	}

	if (Request(&ph_req,mywindow) != 1) {
		emits("Requester Failed\n");
		return(0);
	}
	while (looping) {
		if ((mes = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) == 0) {
			(VOID) Wait(1<<mywindow->UserPort->mp_SigBit);
			continue;
		}
		class = mes->Class;
		gad = (struct Gadget *)mes->IAddress;
		(VOID) ReplyMsg(mes);
		if (class!=GADGETUP) continue;
		if UP_C_GAD {
			looping = FALSE;
			continue;
		}
		if UP_S_GAD {
			if (sav_phlib() == 1) {
				EndRequest(&ph_req,mywindow);
				emits("Save of Phone Library failed\n");
				looping = FALSE;
			}
			continue;
		}
		if UP_L_GAD {
			load_phlib(1);
			RefreshGadgets(&ph_nm_gad,mywindow,&ph_req);
			continue;
		}
		if UP_PH_NM_GAD {
			continue;
		}
		if UP_PFX_GAD {
			continue;
		}
		if UP_DIAL_GAD {
			dial(GAD_LINE);
			looping = FALSE;
			continue;
		}
		if UP_NAME_GAD {
			dirty = 1;
			continue;
		}
		if UP_NUM_GAD {
			continue;
		}
	}   /*  end while */

	if (dirty) {
		ClearMenuStrip(mywindow);
		bld_bbs_men();
		SetMenuStrip(mywindow,&menu[0]);
	}

	return(0);
}

init_req()
{
	int i;
	USHORT g_num = 0;

	for (i = 0;i < MAX_NUM;i++) {
		d_gad[i].NextGadget = &nam_gad[i];
		d_gad[i].LeftEdge = 2;
		d_gad[i].TopEdge = 38 + (11 * i);
		d_gad[i].Width = 35;
		d_gad[i].Height = 11;;
		d_gad[i].Flags = GADGHCOMP;
		d_gad[i].Activation = RELVERIFY | ENDGADGET;
		d_gad[i].GadgetType = REQGADGET | BOOLGADGET;
		d_gad[i].GadgetRender = (APTR)&bord;
		d_gad[i].SelectRender = NULL;
		d_gad[i].GadgetText = &d_txt;
		d_gad[i].MutualExclude = NULL;
		d_gad[i].SpecialInfo = NULL;
		d_gad[i].GadgetID = g_num++;
		d_gad[i].UserData = NULL;
		nam_gad[i].NextGadget = &num_gad[i];
		nam_gad[i].LeftEdge = 40;
		nam_gad[i].TopEdge = 39 + (11 * i);
		nam_gad[i].Width = 160;
		nam_gad[i].Height = 11;;
		nam_gad[i].Flags = GADGHCOMP;
		nam_gad[i].Activation = RELVERIFY;
		nam_gad[i].GadgetType = REQGADGET | STRGADGET;
		nam_gad[i].GadgetRender = NULL;
		nam_gad[i].SelectRender = NULL;
		nam_gad[i].GadgetText = NULL;
		nam_gad[i].MutualExclude = NULL;
		nam_gad[i].SpecialInfo = (APTR)&bbs_name_s[i];
		nam_gad[i].GadgetID = g_num++;
		nam_gad[i].UserData = NULL;
		num_gad[i].NextGadget = &d_gad[i]+1;
		num_gad[i].LeftEdge = 210;
		num_gad[i].TopEdge = 39 + (11 * i);
		num_gad[i].Width = 160;
		num_gad[i].Height = 11;;
		num_gad[i].Flags = GADGHCOMP;
		num_gad[i].Activation = RELVERIFY;
		num_gad[i].GadgetType = REQGADGET | STRGADGET;
		num_gad[i].GadgetRender = NULL;
		num_gad[i].SelectRender = NULL;
		num_gad[i].GadgetText = NULL;
		num_gad[i].MutualExclude = NULL;
		num_gad[i].SpecialInfo = (APTR)&bbs_num_s[i];
		num_gad[i].GadgetID = g_num++;
		num_gad[i].UserData = NULL;
		bbs_name_s[i].Buffer = (UBYTE *)&bbs_name[i];
		bbs_name_s[i].UndoBuffer = undo_buf;
		bbs_name_s[i].BufferPos = 0;
		bbs_name_s[i].MaxChars = Bbs_Ent_Sz;
		bbs_name_s[i].DispPos = 0;
		bbs_name_s[i].UndoPos = 0;
		bbs_name_s[i].NumChars = 0;
		bbs_name_s[i].DispCount = 0;
		bbs_name_s[i].CLeft = 0;
		bbs_name_s[i].CTop = 0;
		bbs_name_s[i].LayerPtr = NULL;
		bbs_name_s[i].LongInt = 0;
		bbs_name_s[i].AltKeyMap = NULL;
		bbs_num_s[i].Buffer = (UBYTE *)&bbs_num[i];
		bbs_num_s[i].UndoBuffer = undo_buf;
		bbs_num_s[i].BufferPos = 0;
		bbs_num_s[i].MaxChars = Bbs_Ent_Sz;
		bbs_num_s[i].DispPos = 0;
		bbs_num_s[i].UndoPos = 0;
		bbs_num_s[i].NumChars = 0;
		bbs_num_s[i].DispCount = 0;
		bbs_num_s[i].CLeft = 0;
		bbs_num_s[i].CTop = 0;
		bbs_num_s[i].LayerPtr = NULL;
		bbs_num_s[i].LongInt = 0;
		bbs_num_s[i].AltKeyMap = NULL;
	}
	num_gad[MAX_NUM-1].NextGadget = NULL;
	return(0);
}

sav_phlib()
{
	int i;
	FILE *fptr;


	if ((fptr = fopen(fil_nam,"w")) == NULL)
		return(1);	/*  NOTE: file cannot open */

	if ((fputs(pfx_nam,fptr) == EOF) ||
	    (fputc('\n',fptr) == EOF)) {
		fclose(fptr);
		return(1);
	}
	
	for (i = 0;i<MAX_NUM;i++) {
		if ((fputs(bbs_name[i],fptr) == EOF) ||
		    (fputc('\n',fptr) == EOF)) {
			fclose(fptr);
			return(1);
		}
		if ((fputs(bbs_num[i],fptr) == EOF) ||
		    (fputc('\n',fptr) == EOF)) {
			fclose(fptr);
			return(1);
		}
	}
	fclose(fptr);
	return(0);
}
		

load_phlib(menu_act)
	int	menu_act;
{
	int i, j;
	int error = 0;
	FILE *fptr;

	if (menu_act)
		ClearMenuStrip(mywindow);

	for (i = 0;i < MAX_NUM;i++) {
		bbs_name[i][0] = '\0';
		bbs_num[i][0] = '\0';
	}

	if ((fptr = fopen(fil_nam,"r")) == NULL) {
		error = 1;
	}

	if (!error) {
		if (fgets(pfx_nam,Bbs_Ent_Sz+1,fptr) == NULL) 
			pfx_nam[0] = '\0';
		else {
			j = strlen(pfx_nam);
			if (j) pfx_nam[j-1] = '\0';
			for (i = 0;i<MAX_NUM;i++) {
				if ((fgets(bbs_name[i],Bbs_Ent_Sz+1,fptr) == NULL) ||
				    (fgets(bbs_num[i],Bbs_Ent_Sz+1,fptr) == NULL)) {
					bbs_name[i][0] = '\0';
					bbs_num[i][0] = '\0';
					i = MAX_NUM + 1;
				}
				j = strlen(bbs_name[i]);
				if (j) bbs_name[i][j-1] = '\0';	/*  note: drop \n */
				j = strlen(bbs_num[i]);
				if (j) bbs_num[i][j-1] = '\0';	/*  note: drop \n */
			}
		}
		fclose(fptr);
	}
	bld_bbs_men();

	if (error) 
		PHItem[1].Flags &= (0xff - ITEMENABLED);
	else
		PHItem[1].Flags |= ITEMENABLED;

	if (menu_act)
		SetMenuStrip(mywindow,&menu[0]);

	return(0);
}
		
dial(ent)
	int ent;
{
	emits("Calling ");
	emits(bbs_name[ent]);
	emits("\n");

	dial_str(pfx_nam);
	dial_str(bbs_num[ent]);
	dial_str("\x0d");
	return(0);
}

bld_bbs_men()
{
	int i, j;

	for (i = 0;i<MAX_NUM;i++) {
		bbs_men[i].NextItem = &bbs_men[i]+1;
		bbs_men[i].LeftEdge = 60;
		bbs_men[i].TopEdge = i * 11;
		bbs_men[i].Width = 160;
		bbs_men[i].Height = 11;
		bbs_men[i].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
		bbs_men[i].MutualExclude = NULL;
		bbs_men[i].ItemFill = (APTR)&bbs_txt[i];
		bbs_men[i].SelectFill = NULL;
		bbs_men[i].Command = 0;
		bbs_men[i].SubItem = NULL;
		bbs_men[i].NextSelect = 0;

		bbs_txt[i].FrontPen = 0;
		bbs_txt[i].BackPen = 1;
		bbs_txt[i].DrawMode = JAM1;
		bbs_txt[i].LeftEdge = 0;
		bbs_txt[i].TopEdge = 1;
		bbs_txt[i].IText = (UBYTE *)&bbs_name[i];
		if (bbs_name[i][0] == '\0')
			bbs_men[i].Flags = ITEMTEXT | HIGHCOMP; /* disabled */
		bbs_txt[i].ITextFont = NULL;
		bbs_txt[i].NextText = NULL;
	}

	bbs_men[MAX_NUM-1].NextItem = NULL;
	
	return(0);
}
