/*        ***   *   *    *    ****   ****   ****     *    *       *
         *   *  *   *   * *   *   *  *   *  *   *   * *   *   *   *
         *      *****  *   *  ****   *   *  ****   *   *   * * * *
         *   *  *   *  *****  *  *   *   *  *  *   *****   * * * *
          ***   *   *  *   *  *   *  ****   *   *  *   *    *   *
*/
/* this file creates a character set */

#include	"equs.c"
#include	"data.c"

main ()
{	char	result;
	struct cellbuild CB;
	int	i;
	char	UsaveDone;	/* is another save needed flag */



/*	/* INIT */
	keyinit();
	biginit();
	/*flush buff  DEBUG */
	while (dummy = gtstch ())
		;
*/

	/* set up prompt line value */
	drPromLine = PROMPTLINE;
	if (isHoriz)
		{ if (st.isSmall) drPromLine +=  18;
		}
	else
		drPromLine += 37;
	/* variable init */
	fillbuild();
	/* end init */
	if (!setuplang ()) goto sessabort;

	while (1)
		{		/* getting chars loop */
		UsaveDone == TRUE; /* dont force save unless there's activity */
		clearsc();
		CHmode();
 		chdisp();
		chcurpos (4,1);
		putz (ms14ptr); /* enter char or return to leave */
		putz (ms15ptr);
		putz (ms16ptr);
		result = gtch ();
		if (result == CR) 
			{ if (UsaveDone) break;
			  /* comfirm leave without saving */
			  clrCHdisp();
			  PA.PAptr [1] = ms6ptr;
			  PA.PAptr [0] = ms91ptr;
			  dosPrompt (2,PA,drPromLine);
			  if (consPrompt (ms91ptr,drPromLine)) break;
			  clrCHdisp ();
			}
		else if (result == F1) 
			{ clrCHdisp();
			  if (Usave())
			  	UsaveDone = TRUE;
			}
		else if ((result >= ' ') & (result <= DEL))
			{  /* actaully define a char */	
			if (gtOneChar (&CB,result)) 
				{  	/* good def */
				result -= (' '); /* result is num of char in table */
				if (!cs.Usmall) movechar (&cs.langbuffer [(result * (charbytes))],&CB.charmap [0],NOROT);
				else  movechar (&cs.langbuffer [(result * (VERTBYTES))],&CB.charmap [0],HtoV);
				descenders [result] = CB.isDescend;
				UsaveDone = FALSE;
				}  	/* got a good definition */
			} /* defining a char */
		}  /* getting char loop */
	
	charsuc = TRUE;  /* return value, sinc overlay can't return */
	return;
  sessabort:
	charsuc = FALSE;
	return;

}	/* end of main program */






/* load up language buffer, get basic settings, and open file
	to save character set to */
char	setuplang ()
{	char	result,holdef,holdres,i,res2;

	setupSize();

/* now load in language base */	
whatlang:
while (1)
	{
	clearsc ();
	strcpy (lstring,lStrBase);
	strcat (lstring, "U*"); 
  
	PA.PAptr [0] = ms18ptr;
	PA.PAptr [1] = ms17ptr;
	doPrompt(2,PA);
	/* center menu */
	for (i = 0; i < MENMAX; i++)
		mens [Olang].MENchCol [i] -= MENCENT;
	mens [Olang].MENheadCol -= MENCENT;
	holdef = mens [Olang].MENdefChoice [0];
	mens [Olang].MENdefChoice [0] = 0;  /* ascii */
	mens [Olang].MENchoice [findplace ('*',lstring) - 1] = "None";
	
	menDisp (mens [Olang]);
	res2 = subControl (Olang);
	clrPrompt (2);
	holdres = mens [Olang].MENdefChoice [0];
	result = lstring [holdres];
	mens [Olang].MENdefChoice [0] = holdef;
	/* set menu back */
	for (i = 0; i < MENMAX; i++)
		mens [Olang].MENchCol[i] += MENCENT;
	mens [Olang].MENheadCol += MENCENT;
	if (res2 == ESC) return (FALSE);

	mens [Olang].MENchoice [findplace ('*',lstring) - 1] = noneptr;
	/* if user don't confirm cause too many questions */
	if (result == 'U') goto chlangLoopEnd;
	PA.PAptr [0] = ms20ptr;
	PA.PAptr [1] = ms19ptr;
	clrPrompt (3);
	doPrompt (2,PA);
	curpos ((PROMPTLINE-1),(PROMCOL + strlen (ms19ptr)));
	putz (mens [Olang].MENchoice [holdres]);  /* CONFIRM READING IN	*/
	if (conPrompt (ms20ptr))
		goto chlangLoopEnd;
	} /* end of choose lang loop  (while 1) */

chlangLoopEnd:

	if (!loadlang (result))
		return (FALSE);

	setupsize();  /* in case it was changed */
	return (TRUE);


} /* end of setlang */

setupSize()
{

	cs.Usmall = st.isSmall;
	if (st.isSmall) 
		{ gdheight = SMALHEIGHT;
		  gdwidth = SMALWIDTH;
		  langsize = VERTBYTES * NUMCHARS;
		  if (isHoriz)
			charbytes = HORZBYTES;
		  else charbytes = VERTBYTES;
		}
	else
		{ gdheight = BIGHEIGHT;
		  gdwidth = BIGWIDTH;
		  langsize = BIGLANG;
		  charbytes = BIGBYTES;
		}

}



/* dispays current character set at bottom of screen */
/* download char set, dispay it then return to standard lg setting */
chdisp()
{	char	i;
	chcurpos (22,0);
	putz (ms22ptr);
	dnldUCHset();
	for (i = ' '; i <= DEL; i++)
		ptch (i);
	ptch (ESC);ptch ('L');ptch (standLang);
		
}


clrCHdisp()
{ char	i;
	for (i = 21; i < 24; i++)
		{ chcurpos (i,0);
		  putz (clrtoeolseq);
		}
	
}


/* input a character,  if abort return false, else return true */
char	gtOneCHar (cb,curchar)
	struct	cellbuild   *cb;
	char	curchar;
{	char	result,inchar;

	cb->isDescend = FALSE;
	clearsc();
	chdisp();
	chcurpos (0,1);
	cellclear (cb);
	inchar = curchar - ' ';
	if (!st.isSmall) movechar (&cb->charmap[0],&cs.langbuffer[(inchar * (charbytes))],NOROT);
	else movechar (&cb->charmap[0],&cs.langbuffer[(inchar * (VERTBYTES))],VtoH);
	cb->isDescend = descenders [inchar];
	 /* load new char in grid */
	printz ("%s%c%s%x\n",ms23ptr,curchar,ms24ptr,curchar);
	putz (ms25ptr);
	putz (ms26ptr);
	putz (ms27ptr);
	putz (ms28ptr);
	putz (ms29ptr);
	putz (ms30ptr);
	putz (ms31ptr);
	putz (ms32ptr);

	putz (crinvseq);
	cb->wcell = 0;
	cb->hcell = 0;
	GRmode();
	drawgrid (cb);
	griddisp (cb);
	/* set to cell 1,1 and position cursor */
	/* loop for inputting */
	while (1)
		{
		result = Ggtch();
		switch (result)
			{
			case (CR)      : goto	inpdone;
			case (UPCUR)   : if (cb->hcell < (gdheight -1))
			     			movcurse (cb,1,0);
			                 else gptch (BELL);
			                 break;
			case (DOWNCUR) : if (cb->hcell > 0)
						movcurse (cb,-1,0);
			                  else gptch (BELL);
			                  break;
			case (LEFTCUR) : if (cb->wcell > 0)
						movcurse (cb,0,-1);
			                  else gptch (BELL);
			                  break;
			case (RIGHTCUR): if (cb->wcell < (gdwidth -1))
						movcurse (cb,0,1);
			                  else gptch (BELL);
			                  break;
			case (URCUR)   : if ((cb->hcell < (gdheight -1)) & (cb->wcell < (gdwidth - 1)))
						movcurse (cb,1,1);
			                 else gptch (BELL);
			                 break;
			case (ULCUR)   : if ((cb->hcell < (gdheight -1)) & (cb->wcell > 0))
						movcurse (cb,1,-1);
			                 else gptch (BELL);
			                 break;
			case (DRCUR)   : if ((cb->hcell > 0) & (cb->wcell < (gdwidth - 1)))
						movcurse (cb,-1,1);
			                 else gptch (BELL);
			                 break;
			case (DLCUR)   : if ((cb->hcell > 0 ) & (cb->wcell > 0))
						movcurse (cb,-1,-1);
			                 else gptch (BELL);
			                 break;
				/* ABORT */
			case (ESC) :   goto  gcabort;
				/* BLANK OUT GRID */
			case (F3) :   cellclear (cb);
			                 drawgrid (cb);
					 griddisp (cb);
					 break;	
			   	/* TOGGLE DESCENDER */
			case (F4) :   cb->isDescend = (!(cb->isDescend));
			                 drawgrid (cb);
			                 sampledisp (cb);
			                 GRcurse (cb->wcell,cb->hcell);
					 break;
				/* READ CHAR INTO GRID */ 
			case (F2)   :   inchar = gtch();
			                 if ((inchar >= ' ') & (inchar <= DEL))
						{ inchar -= ' ';
			                          if (!st.isSmall) movechar (&cb->charmap[0],&cs.langbuffer[(inchar * (charbytes))],NOROT);
						  else movechar (&cb->charmap[0],&cs.langbuffer[(inchar * (VERTBYTES))],VtoH);
						  cb->isDescend = descenders [inchar];
			                          drawgrid (cb);
			                          griddisp (cb);
						} /* load new char in grid */
			                 break;

			case (' ')   :   blankcell (cb);
			                 GRcurse (cb->wcell,cb->hcell);
			                 break;
			default        : fillcell (cb);
			                 GRcurse (cb->wcell,cb->hcell);
			}  /* case result */
		}  /* inputing cells loop*/
inpdone:
	CHmode();
	putz (crvisseq);
	return (TRUE);
gcabort:
	CHmode();
	putz (crvisseq);
	return (FALSE);

}  /* end of gtOneChar */





movcurse (cb,ht,wd)
	struct	cellbuild *cb;
	int	ht,wd;
{
	GRcurse (cb->wcell,cb->hcell);
	cb->wcell += wd;
	cb->hcell += ht;
	GRcurse (cb->wcell,cb->hcell);
}





/* actually loads language buffer */
char loadlang (result)
	char	result;
{	struct	tranfileDir CHS [TFDSIZE + 10];
	char	i,searchstr[3],*entptr,*entnumptr;
	int	fd,charEntsize,exLength,k;

	if (result == '*') 
		{ ldlangnull();
		  return (TRUE);
		}

	/* if user file try to open it */
	if (result =='U') 
		{ if (!(loaduserfile ())) 
			  return (FALSE);
		  else 
			{ isUseLang = TRUE;
			  if (SZresetCheck()) STsize();
			}
		  clrPrompt (3);
		}	
	else	/* load a language file */
		{
		/* first load basix ascii character set */
		if ((fd = ropenfile ("CHARSET.CST")) == -1) goto nofind;

		/* first read in file table and then find offset. 
		   Table is made of strings with first char of language
			followed by a S or L for SMALL or LARGE char sets,
			then is number of record offset to set 
	 	BASIC ASCII set is full set, others are changes to chars
		    in ASCII set. Format for others is one integer with
		    number of entries, then each entries has one byte
		    whiich is number of character it defines, then the 
		    string for that char 
		DESCENDER tables are stored at the end of all character set
			definitions  */
		
		if (read (fd,&CHS,1) == -1)
			goto nofind;
		searchstr [0] = 'A';
		if (st.isSmall)
			searchstr [1] = 'S';   
		else searchstr [1] = 'L';   
		searchstr [2] = '\0';
		/* search table for string, if not found go to not found */
		for (i = 0; i < TFDSIZE; i++)
			{ if (strmatch (searchstr,CHS[i].entname)) 
				goto entfound;
			}
			goto nofind;
		entfound:
		if (seek (fd,CHS[i].entoff,0) == -1) goto nofind;
		if (read (fd,&cs.langbuffer [0],((langsize+DESCENDBYTES)/128 + 1)) == -1) 
			goto nofind;

		/* move descender table to descender array */
		movmem (&cs.langbuffer[langsize],&descenders[0],DESCENDBYTES);

		if (result != 'A')
			{
			/* if char set choice is not "A" load up change table 
			  and make changes with new descenders */
			searchstr [0] = result;
			if (st.isSmall)
				searchstr [1] = 'S';   
			else searchstr [1] = 'L';   
			searchstr [2] = '\0';
			/* search table for string, if not found go to not found */
			for (i = 0; i < TFDSIZE; i++)
				{ if (strmatch (searchstr,CHS[i].entname)) 
					goto ent2found;
				}
			goto nofind;

		   ent2found:
			/* now read  first recordto lang2buff, first entry is
			 length of table in entries.   Determine how many records 
			 need be read and read them in */
			if (seek (fd,CHS[i].entoff,0) == -1) goto nofind;
			if (read (fd,&filebuffer [0],1) == -1) 
				goto nofind;

			entnumptr = &filebuffer[0]; /* points to number of entries */
			entptr = entnumptr + 1; /* points to first entry */
			if (st.isSmall) charEntsize = VERTBYTES;
			else charEntsize = BIGBYTES;
		
			/* see if we need to read in more records*/     /*  char size \/  */
			exLength = DESCENDBYTES + (*entnumptr * charEntsize) + sizeof (result);
			exLength -= 128;
			if (exLength > 0)
				if (read (fd,&filebuffer [128],((exLength/128) + 1)) == -1)
					goto nofind;

			for (i = 0; i < *entnumptr; i++)
				{ k = ((*entptr - 0x20) * charEntsize);
				  entptr++; 	/* points to first byte in entry */
				  movmem (entptr,&cs.langbuffer [k],charEntsize);
				  entptr += charEntsize;
				}  /* i to number of entires */	
			
			/* move in new descneder table */
			movmem (entptr,&descenders[0],DESCENDBYTES);
		
			}  /* end  if result != A */
	
		fabort (fd);

		}      /* end of else (load language file) */ 
	
	/* now down load language */
	return (TRUE);

   nofind:
	clrprompt (3);
	ptch (BELL);
	doPrompt (1,&ms33ptr);
	fabort (fd);
	return (FALSE);

} /* end of load lang */

/* load up cs.langbuffer from a user file */

char loaduserfile ()
{	int	fd;
	char	result,fname[15];
	
	if (isUseLang)
		{  	/* should we use current loaded language */
		PA.PAptr [0] = ms34ptr; 
		doPrompt (1,PA);
		if (conPrompt (ms34ptr)) 
			return (TRUE);
		clrprompt (2);
		} /* is isUSE Lang */
	
loadU1:
	while (1)	  /* read query */
		{
		if (strlen (UfileName) == 0)
			{ if (!gtUfileName (TRUE))
				return (FALSE);
			  clrPrompt (3);
			}
		else  /* don't confirm if we already queried for user name */	
			{
			clrCHdisp();
			PA.PAptr [1] = ms35ptr;  /* confirm using current file */
			PA.PAptr [0] = ms20ptr;
			clrPrompt (3);
			doPrompt (2,PA);
			curpos (PROMPTLINE - 1,(strlen (ms35ptr) + PROMCOL));
			putz (UfileName);
			if (conPrompt (ms20ptr)) break;
			UfileName [0] = '\0';
			clrPrompt (3);
			}
		} /* read in query loop  (while 1) */

   	/* now that we got a name let's try and read */
	if (!(readChset (UfileName)))
		{ UfileName [0] = '\0';
		  curpos ((PROMPTLINE - 2),PROMCOL);
		  putz (ms36ptr);
		  ptch (BELL);
		  goto loadU1;
		}

	return (TRUE);

}  /* loadUserFile */




/* save user file name */
Usave()
{	int	fd,size;
	struct	filtable	*tabptr;

saveU1:
	clrCHdisp ();
	while (1)	  /* save name query */
		{
		if (strlen (UfileName) == 0)
			{ if (!gtUfilename (FALSE)) return (FALSE);
			  clrCHdisp ();
			}
		else  /* don't confirm if we already queried for user name */	
			{
			PA.PAptr [1] = ms40ptr;  /* confirm using current file */
			PA.PAptr [0] = ms20ptr;
			dosPrompt (2,PA,drPromLine);
			curpos (drPromLine - 1,(strlen (ms40ptr) + PROMCOL));
			putz (UfileName);
			if (consPrompt (ms20ptr,drPromLine)) break;
			UfileName [0] = '\0';
			clrCHdisp ();
			}
		} /* save name  query */
	tabptr = filebuffer;

	fd = open (UfileName,2);
	if (fd == -1)
		{
		fd = creat (UfileName);
		if (fd == -1)
			{ clrCHdisp();
			  dosPrompt (1,&ms45ptr,drPromLine);
			  ptch (BELL);
			  return (FALSE);
			}
		
		/* now create a dummy table and file */
		ft.justUse = TRUE;
		strcpy (ft.headstring,"CUSTOMIZ VER");
		ft.kbdloc = 0;
		ft.chsloc = 256;
		if (write (fd,ft,2) == -1) goto cantsave;
		}   /* new file */
	else  
		{ if (readtable (fd) == -1) goto cantsave;
		/* NOTE readtable is both in filebuffer
			and ft */
		  /* figure where to put the charset in */
		  if (tabptr -> chsloc == 0)
			{ 
			if (tabptr -> justUse)
				tabptr ->chsloc = 256;
			else		/* not just use */
				tabptr ->chsloc = roundup (tabptr -> fkloc + tabptr -> fksize);
			if (seek (fd,0,0) == -1) goto cantsave;
			if (write (fd,filebuffer,1) == -1) 
				goto cantsave;
			/* goto last existent record and do a read to 
		  	set pointer to the pace to start wrting */
			if (seek (fd, ((tabptr -> chsloc /128) - 1),0) == -1)
				goto cantsave;
			if (read (fd,&filebuffer [256],1) == -1)
				goto cantsave;	/* dummy reed */
			}  /* no charset in file now */
		  else
			{ if (seek (fd,((tabptr -> chsloc/128)),0) == -1) 
				goto cantsave;
			}  /* char set is in there already */
		}  /* reading into old file */

	  if (cs.Usmall) size = NUMCHARS * VERTBYTES + 1;
	  else size = NUMCHARS * BIGBYTES + 1;
	  movmem (cs,filebuffer,size);
	  movmem (descenders,&filebuffer [size],DESCENDBYTES);
	  if (write (fd,filebuffer,(roundup (size + DESCENDBYTES)/128)) == -1) 
		goto cantsave;

	close (fd);
	return (TRUE);

cantsave:
	fabort (fd);
	ptch (BELL);
	return (FALSE);
}	/* end save User file */



char	gtUfileName (read)
	char	read;  /* flag */
{char	result;

	PA.PAptr [0] = ms38ptr;
	if (read) PA.PAptr [1] = ms37ptr;
	else PA.PAptr [1] = ms39ptr;
	if (read) 
		{ doPrompt (2,PA);
		  result = inpPrompt (PROMPTLINE,strlen (ms38ptr));
		}
	else 
		{ dosPrompt (2,PA,drPromLine);
		  result = inpPrompt (drPromLine,strlen (ms38ptr));
		}

	if ((result == CR) | (result == ESC)) return (FALSE);
	ungtch (result);
	if (read) GTfilename (UfileName);
	else GTSfilename (UfileName,drPromLine);
	if (strlen (UfileName) == 0) return (FALSE);
	return (TRUE);

}  /* end of gtUfileName */




/* read a character set from a user file */

char	readCHset (name)
	char	*name;
{	int	fd;

	if ((fd = open (name,0)) == -1) return (FALSE);
	if (readtable (fd) == -1) return (FALSE);
	if (readUchar (fd) == -1) return (FALSE);
	fabort (fd);
	return (TRUE);
}   /* end of readCHSet */




/* load character set with zeroes */
ldlangnull()
{ int i;
	for (i = 0; i < langsize;i++)
		cs.langbuffer [i] = '\0';
	for (i = 0; i < DESCENDBYTES;i++)
		descender [i] = '\0';
}   /* ldlangnull */



abort()
{   exit();
}


