/*****************************************************************
 * Articles/Notes, Misc. other functions overlay
 *
 *	File: MEMISC.C
 *
 *	Metal and Metal Message System are Trademarks and
 *	   Copyright (c) 1984, 1985, 1986  Tim Gary
 *	     	      All Rights Reserved.
 *
 ******************************************************************
 *
 * 1.50xx 04/12/86 Fixed features bug from lbr code conversion..
 * 1.50xx 04/06/86 Sysop not prompted to leave comments for entering CP/M..
 *		   library stuff added to articles routines.
 * 1.40xx 02/21/86 Start extended help command..
 * 1.40xx 02/11/86 Time command changed a bit..
 * 1.40xx 02/03/86 Fixed articles/features..
 * 1.40xx 01/26/86 Fixed for new user/date stuff..
 * 1.31a  10/13/85 Release version.  Changes:
 *		   go_os() routine called from cpm()..
 *		   deleted 'readrange' routine (moved to MEREAD.C)
 *		   hangup() called when done (bye,g)
 * 1.30xx 6/23/85  Cosmetic change in getrange text.
 * 1.30xx 6/19/85  A very few changes in feature(), cpm(), etc..
 * 1.30xx 5/05/85  Comments routine fixed.
 * 1.30xx 3/07/85  Fixed for chaining to BYE program on exit..
 * 1.30xx 3/03/85  ZCPR stuff added..
 * 1.20b 01/18/85  Showtime put here..
 * 1.20b 01/16/85  Recursive use of notes/features allowed...
 * 1.20b 01/06/85  Allow 'Q' as in 'K' for read silent mode.
 * 1.20a 11/11/84  Comments messages made more universal, and Goodbye
 *		  routine made to not display info if  G;N thing
 *		  typed.
 * 1.20a 11/07/84  Comments routine fixed for two CONSECUTIVE CR's
 *		  to stop.
 * 1.10e 11/01/84  Getrange now allows to read dead msgs.
 * 1.10e 10/29/84  Added chat(), cpm() and goodbye() to this overlay.
 *
 * 1.10c 10/12/84  Created from MEFEAT.C  4 parameters passed
 *		   to all of these routines.
 *
 ******************************************************************/

#include "xpm.h"	/* CPMIO header file for i/o operations.*/
#include "megen.h"	/* general defines		*/
#include "meglob.h"	/* global variable definitions	*/
#include "meovfn.h"	/* overlay function numbers	*/
#include "mefiles.h"	/* file names			*/

#include "ctype.h"

#define	COMMHELP "MECOMM  HLP"	/* comments help info	*/

/**********************************************************
 * Overlay main program, dispatches to contained routines.
 **********************************************************/

ovmain(routine,p1)	/* ,p2,p3,p4) */
 int routine,p1;	/* ,p2,p3,p4; */
{
switch(routine)
	{
	case FEATURE:
		return feature(p1,(char *)0,1);
	case CHAT:
		return chat(p1);
	case GOODBYE:
		return goodbye(p1);
	case GOCPM:
		return cpm(p1);
	case SHOWTIME:
		return showtime();
	case MEHELP:
		return more_help();
	default:
		send("\nUnknown routine called for.\n");
		break;
	}
} /* ovmain */


/********************************************
 * More extensive help stuff..  takes topics
 * from main library...
 ********************************************/

more_help()
{
int flag=FALSE;
char temp[12],t[12];		/* 11 chars usable, +1 for null terminator */

if (!strloc) ltype(METHELP,"MEHELP     ");  /* display '?' list by default */
  else flag=TRUE;
do {
   if (user.flags&EXPERT) ask("\nSubject (or ?): ",temp,6,UP);
    else ask("\nWhat subject would you like help on (? for list)? ",temp,6,UP);
   if (!(*temp)) return;
   if (*temp=='?') strcpy(t,"MEHELP     ");
     else sprintf(t,"ME%-6sHLP",temp);	/* make exactly 11 chars */

   putchar('\n');
   if (ltype(METHELP,t)==ERROR)
	printf("\n[No help available for %s]\n",temp);

   } while (!flag);	/* while */

}


/*****************************************
 * Show current time, and time on system *
 *****************************************/

showtime()
{
if (O.RTC)
  {
  int mins;	/* mins on system */
  readclock();
  mins=timecomp(time,user.time,date,user.date);
  printf("\nToday is %s.  The time is %s.",ascdate(date),asctime(time));
  printf("\nLogged in at %s (%d minutes ago).\n",asctime(user.time),mins);
 if (user.minutes)
  printf("You've used the system for %d minutes today.\n",mins+user.minutes);
  if (user.tot_hours || user.tot_mins)
	{
	unsigned hours;
	mins+=user.tot_mins;
	hours=user.tot_hours+(mins/60);
	mins%=60;
	printf("To date, you have spent %d hour(s) and %d minute(s) on the system.\n",hours,mins);
	}
  }
  else send("\nNo clock installed on this system.\n");
}


/******************************************************************
 * Articles function to list files in the Articles/Features ('A')
 * or Notes ('N') index file.  Index file has a fixed format of:
 *
 *   o  filename/location of file (C format)
 *	   (my also be library:  libname#membername  (note '#'!!))
 *   o  a space character (required!)
 *   o  rest of line = Description of file (displayed in the menu)
 *
 * Each line must have at least 6 characters in it.  A standard text
 * editor may be used to create the index file.  Each line is
 * the index for one file.  A line may NOT exceed 128 chars.
 *
 * A maximum of 25 articles may be contained in the index files.
 *
 * If the line begins with a ';', it is considered a comment line
 * and will be ignored..
 *
 * If the line starts with a * then the line is printed during
 * the menu display.
 *
 * Squeezed articles may be displayed, however menus may NOT be squeezed.
 *
 ******************************************************************/

feature(ch,file_name,level)
 int ch;
 char *file_name;
 int level;			/* level number */
{
char *in[25];	/* pointer array to each filename */
char level_name[81];
char name[32];
register int i,n;
char tot,*tp,*space;
FILE *indfile,*tf;
int ret_flag;

ret_flag=NULL;

space=malloc(800);		/* get space for filenames */
if (!space) return ERROR;	/* error, return to previos level */
for (i=0; i<25; i++) in[i]=space+(32*i);	/* setup pointer array */

tot=0;
if (level==1) strcpy(level_name,"main");
 else *level_name='\0';

do {
   *name='\0';
   if (ch=='A') strcpy(name,FEATFILE);
   else {
	if (ch=='N') strcpy(name,NOTEFILE);
	   else strcpy(name,file_name);
	}

   if (!index(name,'#'))	/* if not library open */
      {
	if ( (indfile=open(name,0)) == NULL)
	 	{
		send("\nSorry, nothing in menu.\n");
		ret_flag=ERROR;
		break;		/* free space, and return ERROR flag */
		}
      }
   else {
	tp=index(name,'#');
	*tp='\0';
	if ( (indfile=lopen(name,tp+1)) == NULL )
		{
		send("\nSorry, nothing in menu.\n");
		ret_flag=ERROR;
		*tp='#';
		break;
		}
	*tp='*';
	}

read(indfile,1);

for (i=0; i<25; ++i)
	{
	int file_flag;
	do {
	   file_flag=FALSE;	/* flag for valid file to type.. */
	   if (fgets(buffer,indfile)==ERROR) break;
	   for (tp=buffer; *tp=='\n' || *tp=='\r'; tp++);    /* ignore cr/lf */
	   if (!ustrncmp(tp,";MENU ",6))
		    strcpy(level_name,tp+6);	/* new level name */
	   if (*tp==';') continue;
	   if (*tp=='*')		/* display line in menu		*/
		{
		putchar('\n');
		if (send(tp+1)==ERROR) break;
		continue;
		}
	   if (*tp<' ' || strlen(tp)<6) break;	/* logical or phys. eof? */
	   strncpy(in[i],tp,index(tp,' ') ? (index(tp,' ')-tp) : 31);
	   if (index(tp,' '))
		{
		in[i][index(tp,' ')-tp]='\0';
	   	tp=index(tp,' ');	/* search to item descr. */
		}
	     else in[i][31]='\0';	/* make SURE it's terminated */

	   for ( ; tp && *tp==' '; tp++);
	   sprintf(buffer,"\n%2d. %s",i+1,tp);
	   if (!strloc) if (send(buffer)==ERROR) break;	/* allow abort */
	   file_flag=TRUE;	/* only ok at bottom of loop */
	   } while (!file_flag);
	if (!file_flag) break;	/* true abort of menu... */
	}	/* for */

if (index(name,'#')) lclose(indfile);	/* That's all we need here for now */
   else close(indfile);

if (i==0)	/* nothing found */
	{
	ret_flag=ERROR;
	break;
	}

if (tot<i) tot=i;	/* tot=total # of items.. */

if (!strloc)
	{
	putchar('\n');
	if ( !(user.flags&EXPERT) )
		{			/* novice explaination */
		sprintf(buffer,"\nPress the RETURN key to %s.",
			level!=1 ? "return to PREVIOUS menu level" :
				   "return to Message System command mode");
		send(buffer);
		if (level!=1) send("\nEnter 0 to return to Metal command mode.");
		}
	 else if (level!=1) send("\nEnter 0 to abort command, RETURN to goto previous menu level.");
	}

sprintf(buffer,"\n\n[%d][%s] Select menu item number? ",level,level_name);
ask(buffer,buffer,2,UPLOW);
if (*buffer=='\0') break;	/* ret_flag default is NULL */

n=atoi(buffer);
if (!isdigit(*buffer) ||  n>tot) continue;
if (n==0)
	{
	ret_flag=TRUE;
	break;
	}

if (tp=index(in[n-1],'#'))
	{
	*tp='\0';
	if (!(tf=lopen(in[n-1],tp+1)) )
		{
		send("\nSorry, that item is empty (L).\n");
		*tp='#';
		continue;
		}
	*tp='#';
	}
 else if (!(tf=open(in[n-1],0)))	/* open file, test for ';MENU' */
	{
	send("\nSorry, that item is empty.\n");
	continue;
	}

  read(tf,0);
  for (i=0; i<6; i++) buffer[i]=getc(tf);

  if (!ustrncmp(buffer,";MENU",5))
	{			/* another menu, do recursive.. */
	ret_flag=feature(0,in[n-1],level+1);	/* recursive */
	if (ret_flag==TRUE) break;		/* massive withdrawl */
	}
    else type_from(tf);	/*  type the file if not menu */

  if (tp) lclose(tf);	/* close lib, or normal file */
    else close(tf);

  } while (1);	/* just a loop forever */


free(space);
return ret_flag;
}


/************************************
 * Ask user if he wishes to leave comments to sysop
 ************************************/

askcomments(str)
 char *str;
{
char temp[5];

if (user.status==SYSOP) return NULL;

if ( !(user.flags&EXPERT) && !strloc) ltype(METHELP,COMMHELP);

do {
   if (!str) ask("\nLeave private comments to the Sysop (y/n)? ",temp,2,UP);
     else ask(str,temp,2,UP);
   if (*temp=='?') ltype(METHELP,COMMHELP);
   }
   while (*temp=='?');	/* while he's still confused.. */

if (*temp=='Y') ovovload(OVSEND,2,0);	  /* this in now priv msg to sysop */
  else if (*temp!='N')
		{
		send("\n[Returning..]\n");
		return ERROR;	/* didn't want to leave */
		}

return NULL;
}


/*******************
 * chat with sysop *
 *******************/

chat(mode)
 int mode;
{
register int a,cfast;
register char temp;
int col;		/* current column count for auto wrap */

if (mode)
	{		/* display user if no 25th status line */
	putchar('\n');
	if (!O.STATUSLINE) printf("%s ",user.name);
	 else wustat("  [CHAT]");
	send("Paging Sysop  ");
	globalchar='\0';
	for (temp=0; temp<25; temp++)
		{
		if (send("\07 .\07 .\07 .")==ERROR) return;	/* bell */
		for (cfast=0; cfast<1000; cfast++)
			if (breakkey()) return;
			 else if ((a=globalchar)==0x1b)	/* ESC hit by sysop? */
				{
				wustat(0);	/* put back just user info */
				send("\nThe Sysop is available, please go ahead...\n");
				break;
				}
		if (send("\b\07\b\b\07\b\b\07")==ERROR) return;	/* backup most of the way */
		if (a==0x1b) break;	/* ESCAPE is Sysop's "I'm here" char */
		}
	if (!a)	
		{
      		send("\nThe Sysop is currently not available.\n");
		askcomments("Would you like to leave a private message to the System Operator? ");
		return;
		}
	} /* end mode check... if mode=0 then just start chat mode */
globalchar=0;	/* for next pass through */
send("\n** [^K to abort chat] **\n");

col=1;	/* first column */
while((cfast=getchar())!=11)		/* while not ^K */
	{
	if (cfast=='\r')
		{
		col=1;
		putchar('\n');
		}
	 else if (cfast=='\b' || cfast==0x7f)
		  {
		  --col;
		  send(" \b");
		  }
	  else {
	       if ( ( ++col>user.width-7 &&
		     (isspace(cfast) || ispunct(cfast)) )
		  || (col>user.width-1) )
			{
			col=1;
			send("\n");	/* force CRLF */
			}
		}
	}
putchar('\n');
}


/* Write user status line info (name, stat, time called, city).. */

wustat(s)
 char *s;
{
char buf[128];
sprintf(buf,"%8s -- %s - '%c' %s -- %s",s ? s : "",user.name,
	user.status,asctime(time),user.city);
writestat(buf);
}


/*******************
 * jump to CP/M... *
 *******************/

cpm(mode)
 register int mode;	/* if mode=1 then ask if leave comments */
{

if (user.type_ptr->maxuser==0 ||
	!index("+snxabcde",user.status) )
	{ send("\nYou don't have access to the operating system."); return; }

if (mode==1)	
	if (askcomments(0)==ERROR) return;	/* didn't want to leave */

go_os(YES);

}


/*******************************
 * Leave the system
 *******************************/

goodbye(mode)
 register int mode;
{
if (mode==1)	/* if 'g' entered. else no comments */
	if (askcomments(0)==ERROR) return;	/* didn't want to leave */

hangup(YES);	/* display copyright and hangup.. */

}


/* EOF MEMISC.C */

