

#include	"sysdef.h"
#include	"scterm.h"

/*	schelp()	help for the screen editor		*/
/*								*/
/*	file format						*/
/*	vbn 1-4		index, fixed 16 byte records		*/
/*	vbn 4-end	text,  fixed 64 byte records		*/
/*								*/
/*	index record format					*/
/*								*/
/*	0..5		6..10		11..15			*/
/*	topic name	offset,64 byte	record count		*/
/*			in ascii	in ascii		*/

#define	SYS_NORMAL	1

#define	IDXBLKS		4
#define	IDXSIZE		16
#define	IDXBLOCK	32
#define	TXTSIZE		64
#define	TXTBLOCK	8

#define	then
#define	CR	015
#define	LF	012
#define	SPACE	040
#define	ESC	033
#define	ESCLEAD	'$'
#define	LITCHAR	'_'
#define	CONTSYM	0134
#define	PAGCHAR	'%'
/*	Help file names. Let the routine OPNHLP insert filetype and	*/
/*	location (logical name for uic and device			*/

static char tedhfile[] = "TEDHELP" ;


static
char *mapindex[] = {
		"cm1"	,"cm2"	,
		"cm3"	,"cm4"	,
		"cm5"	,"cm6"	,
		"cm7"	,"cm8"	,
		"cm9"	,"cm10"	,
		"cm11"	,"cm12"	,
		"cm13"	,"cm14"	,
		"cm15"	,"cm16"	,
		"cm17"	,"cm18"	,
		"cm19"	,"cm20"	,
		"cm21"	,"cm22"	,
		"cm23"	,"cm24"	,
		"cm25"	,"cm26"	,
		"cm27"	,"cm28"	,
		"cm29"	,"cm30"	,
		"cm31"	,"cm32"	,
		"cm33"	,"cm34"	,
		"cm35"	,"cm36"	,
		"cm37"	,"cm38"	,
		"cm39"	,"cm40"	,
		"cm41"  ,"cm42" ,
		"cm43"  ,"cm44" ,
		"cm45"  ,"cm46" ,
		"cm47"  ,"cm48" ,
		"cm49"  ,"cm50" ,
		"cm51"  ,"cm52" ,
		"cm53"  ,"cm54"  } ;

struct idxrec	{
		char nm[6] ;
		char offset[5] ;
		char rcount[5] ;
		} ;


struct txtrec	{
		char c[TXTSIZE] ;
		} ;

union buf	{
		struct txtrec txtbuffer[TXTBLOCK] ;
		struct idxrec idxbuffer[IDXBLOCK] ;
		} ;

extern union buf *hlbuffer ;
extern int hlpctx[] ;
static struct idxrec eofrec = { ".....",0,0 } ;
static char nulltopic[] = "\01" ;
static char notopic[] = "" ;



#define	VTOPEN	1
#define	TEDOPEN	2


static
char vtprm[] = "Type a KEYPAD or FUNCTION key for help, or a SPACE to exit" ;

static char tedprm[]= "Topic ? " ;


char *gettopic(type)
int type ;
{
	register char ch ;
	register int cmdindex ;
	char s[64] ;
	register char *cp ;
	int len ;
	extern char *expcommand() ;

	if ( type == VTOPEN )
	  then	{
		ceol24() ;
		putasciz(vtprm) ;
		if ( (ch=getbin()) == 033 )
		  then	ch = getfuncommand() ;
		cmdindex = fcnlookup(ch) ;
		if ( ch == CR || ch == LF || ch == SPACE )
		  then	return(&nulltopic) ;
		  else	return( (cmdindex) ? mapindex[cmdindex]:&notopic ) ;
		}
	  else	{
		if ( (len = lgetbin(s,tedprm)) == 0 || s[0]==CR )
		  then	return( &nulltopic ) ;
		  else	{
			cp = expcommand(s) ;
			return( (*cp == 0) ? &notopic:cp ) ;
			}
		}		
}






static char contprompt[] = "Type a character to continue" ;
#define	PAGESIZE	20

dsptopic(str)
char *str ;
{
	int cur,docrlf,j,n,found,firstrec,nprinted,reccount,temp ;
	extern struct idxrec *getindex() ;
	extern struct txtrec *gettext() ;
	register struct idxrec *ip ;
	register struct txtrec *tp ;
	register int i ;
	char s[TXTSIZE] ;
	char topicname[6] ;
	char ch,lastch ;

	sclear() ;
	if ( (j=strlen(str)) > 5 ) then j = 5 ;
	for ( i=0; i<j; i++ ) topicname[i] = str[i] ;
	topicname[i] = 0 ;
	n = 0 ;
	while ( (ip=getindex(n))!=0 && chkeof(ip->nm)==0 ) {
		 n++ ;
		 ip->nm[5] = 0 ;
		 for (i=0;i<6;i++) if (ip->nm[i] == SPACE) then ip->nm[i]= 0 ;
		 if ( (found=match( ip->nm,topicname )) ) then break ;
		}
	if ( found == 0 )
	  then	{
		ceol24() ;
		putasciz("Help not found for that topic\015\012") ;
		suspend(2);
		return(0) ;
		}
	  else	{
		firstrec = gval( ip->offset ) ;
		reccount = gval( ip->rcount ) ;
		home() ;
		nprinted = PAGESIZE ;
		for (j=reccount; j>0 && testcc() == 0 ; j--) {
			if ( (tp=gettext(firstrec++)) == 0 )
			  then	{
				ceol24() ;
				putasciz("EOF on HELP file read") ;
				suspend(2) ;
				return(0) ;
				}
			  else	{
				temp = cvtstring(tp->c,TXTSIZE,0204) ;
				lastch = 0 ;
				cur = 0 ;
				docrlf = 1 ;
				for (i=0; i<temp; i++ ) {
				  switch( ch = tp->c[i] ) {
				    case CONTSYM:
					if (lastch == LITCHAR)
					  then s[cur++] = ch ;
					  else docrlf = 0 ;
					break ;
				    case ESCLEAD:
					if (lastch == LITCHAR)
					  then s[cur++] = ch ;
					  else s[cur++] = ESC ;
					break ;
				    case LITCHAR:
					if (lastch == LITCHAR)
					  then s[cur++] = ch ;
					break ;
				    case PAGCHAR:
					if (lastch == LITCHAR)
					  then s[cur++] = ch ;
					  else nprinted = 0 ;
					break ;
				    default:
					s[cur++] = ch ;
					break ;
					}
				  lastch = ch ;
				}
				if ( cur ) then putbin(s,cur) ;
				if ( docrlf ) then putbin("\015\012",2) ;
				if ( docrlf && nprinted-- == 0 )
				  then	{
					kpnormal() ;
					putasciz(contprompt) ;
					getbin() ;
					putbin("\015\012",0) ;
					sclear() ;
					kpapplication() ;
					nprinted = PAGESIZE ;
					}
				}
			}
		}

}



static struct txtrec *gettext(n)
int n ;
{
	register int vbn,off,status ;

	vbn = n / (512/TXTSIZE) + IDXBLKS + 1 ;
	off = n % TXTBLOCK ;
	if ( vbn != hlpctx[0] )
	  then	{
		if ( (status=reahlp(hlbuffer->txtbuffer,vbn))==SYS_NORMAL )
		  then	hlpctx[0] = vbn ;
		  else	return(0) ;
		}
	return( &hlbuffer->txtbuffer[off] ) ;
}


static struct idxrec *getindex(n)
int n ;
{
	register int vbn,off,status ;
	int i ;

	vbn = (n * IDXSIZE)/512 + 1 ;
	off = n % IDXBLOCK ;
	if ( vbn != hlpctx[0] )
	  then	{
		if ( (status=reahlp(hlbuffer->idxbuffer,vbn))==SYS_NORMAL )
		  then	hlpctx[0] = vbn ;
		  else	return(0) ;
		}
	return( &hlbuffer->idxbuffer[off] ) ;
}	



static chkeof(s)
register char *s ;
{
	return( *s == '.' || *s == SPACE ) ;
}


static match(s1,s2)
register char *s1,*s2 ;
{
	int len1,len2 ;
	register int i ;
	extern char toupper() ;

	if (  (len1=strlen(s1)) != (len2=strlen(s2)) )
	  then	return(0) ;
	  else	{
		for (i=len1; i>0;i-- )
		  if (toupper(*s1++) != toupper(*s2++))
			then return(0) ;
		return(1) ;
		}
}


static gval(s)
register char *s;
{
	register int i,res ;

	res = 0 ;
	for (i=5; i>0 && *s == SPACE; i--) s++ ;
	if ( i == 0 ) then return(0) ;
	for ( ; i>0; i--) res = res*10 + (*s++ - '0') ;
	return(res) ;
}


static putasciz(s)
char *s ;
{
	putbin(s,0) ;
}


static prsys_error()
{
	char s[80] ;
	geterror(s) ;
	xprintf("%s\n",s) ;
}




#if	RSX

/*	local copy of GETFUNCOMMAND()				*/
/*								*/
/*	GETFUNCOMMAND() is located in an adjacent overlay	*/
/*								*/
/*	For VT100 and ANSI, return the third character from the	*/
/*	escape sequence. For the VT220, return the 3rd character*/
/*	if it's not a digit, else look ahead for another digit.	*/
/*	Return numeric value of the digit string, 1..34		*/

static int getfuncommand()
{
	register int ch,ch1 ;
	extern int termtype ;

	switch( termtype ) {
	  case _ANSI:
	  case _VT100:
	  case _VT220:
		vtgetc() ;
		ch = vtgetc() ;
		if ( isdigit(ch) )
		  then	{
			ch1 = vtgetc() ;
			if ( isdigit(ch1) )
			  then	{
				vtgetc() ;
				return( (ch-'0')*10 + (ch1-'0') ) ;
				}
			  else	return( ch-'0' ) ;
			}
		  else	return( ch ) ;
		}
}

#endif



