/*
 *
 *	Copyright (C) 1989 by the Massachusetts Institute of Technology
 *    	Developed by the MIT Student Information Processing Board (SIPB).
 *    	For copying information, see the file mit-copyright.h in this release.
 *
 */
/*
 *	$Source: /afs/sipb.mit.edu/project/discuss/.cvsroot/discuss/source/client/rn.c,v $
 *	$Author: srz $
 *	$Header: /afs/sipb.mit.edu/project/discuss/.cvsroot/discuss/source/client/rn.c,v 1.16 1995/03/18 07:15:00 srz Exp $
 *
 *	$Log: rn.c,v $
 * Revision 1.16  1995/03/18  07:15:00  srz
 * Change index() to strchr().  Fix up weird >>>>>> stuff.
 *
 * Revision 1.15  1994/09/24  04:05:50  srz
 * Changed source tree to use configure instead of Imake.  Added WEAK_REALM
 * authentication.  Fixed up includes, etc, for new configure...  still needs
 * more testing.
 *
 * Revision 1.14  1994/09/19  04:13:33  raeburn
 * for netbsd, define USE_OLD_TTY
 *
 * Revision 1.13  1993/05/16 01:35:21  raeburn
 * Use str*chr, not *index.
 * Trailing-whitespace cleanup everywhere.
 *
 * Revision 1.12  1992/06/26  02:13:37  raeburn
 * getting in sync with current source tree
 *
 * Revision 1.11  92/06/13  02:15:44  srz
 * Added 's' option when asking for next transaction (to skip meeting).
 *
 * Revision 1.10  91/07/05  20:30:09  bjaspan
 * ported to svr4
 *
 * Revision 1.9  89/06/02  23:38:39  srz
 * Added standard copyright notice.
 *
 * Revision 1.8  89/05/19  16:58:18  srz
 * Declared static functions in advance.
 *
 * Revision 1.7  89/05/08  02:47:31  srz
 * jik's fix to stop printing twice.
 *
 * Revision 1.6  89/01/05  01:58:44  raeburn
 * replaced included header files with <discuss/discuss.h>
 *
 * Revision 1.5  88/04/21  16:04:46  srz
 * Added ^R to redisplay current transaction (courtesy of jik)
 *
 * Revision 1.4  88/04/20  16:34:04  srz
 * Added catchup, loop for '?' on first prompt.
 *
 * Revision 1.3  88/01/15  23:11:33  srz
 * Fixed bug where new meetings caused problems for "next"
 *
 * Revision 1.2  87/11/07  02:50:38  srz
 * Added new commands ('r', 't', 'p', '?'), and fixed bug that Mark reported
 * about trying to reprint the same transaction over and over again when
 * quitting out of 'more'.
 *
 * Revision 1.1  87/10/24  19:48:02  srz
 * Initial revision
 *
 */

#ifndef lint
static char rcsid_update_c[] =
    "$Header: /afs/sipb.mit.edu/project/discuss/.cvsroot/discuss/source/client/rn.c,v 1.16 1995/03/18 07:15:00 srz Exp $";
#endif /* lint */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include <discuss/discuss.h>
#include "globals.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <string.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#else
#ifdef SVR4
#define BSD_COMP
#include <sys/ioctl.h>
#endif
#endif
#ifdef __NetBSD__
#define USE_OLD_TTY
#endif
#include <sys/ioctl.h>
#undef BSD_COMP
#undef USE_OLD_TTY

static unseen_transactions();

/*  ss_execute_line() overwrites the string it's given so it should
 *  not be given a constant (compile-time) string.  */
static char ss_buf[512];

static changed_meetings()
{
	int code, n_matches, i;
	name_blk *set, *nbp;

	dsc_expand_mtg_set(user_id, "*", &set, &n_matches, &code);
	for (i = 0; i < n_matches; i++) {
		nbp = &set[i];
		if (nbp->status & DSC_ST_CHANGED) {
			free(set);
			return 1;
		}
	}
	free(set);
	return 0;
}

rn(argc, argv, ss_idx)
	int argc;
	char **argv;
        int ss_idx;
{
	int code = 0;
	int cmd;

	printf("Checking meetings...\n");
	fflush(stdout);

	strcpy (ss_buf, "ckm");
	ss_execute_line(ss_idx, ss_buf, &code);
	if (code != 0) goto punt;

	flag_interrupts();
	printf("\n");

	if (!changed_meetings())
	     return;

	for (;;) {
	     cmd = more_break("Hit space to go to next meeting: ", " qn?");
	     if (interrupt)
		  goto done;
	     printf("\n");
	     switch(cmd) {
	     case 'q':
		  goto done;
	     case ' ':
	     case 'n':
		  goto first_meeting;
	     case '?':
		  printf("List of possible responses:\n\n");
		  printf("<space>,n\tNext meeting\n");
		  printf("q\t\tQuit from read_new\n");
		  printf("?\t\tShow this list\n\n");
		  break;
	     }
	}
first_meeting:
	strcpy (ss_buf, "nm");
	ss_execute_line(ss_idx, ss_buf, &code);
	if (code != 0) goto punt;

	while (1) {			/* we get out when changed_meetings is false */
	        if (interrupt)
		     break;
		
		while (unseen_transactions()) {
		        if (interrupt)
			     break;

			cmd = more_break("Hit space for next transaction: ", " qcnp\022tr?hs");
			if (interrupt)
			     break;
		        printf("\n");
			switch (cmd) {
			case 'q':
				goto done;
			case ' ':
			case 'n':
				if (dsc_public.current == 0)
				        strcpy (ss_buf, "pr first");
				else
				        strcpy (ss_buf, "next");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;
			case 'c':
				catchup(0,0);
				break;
			case 'p':
				strcpy (ss_buf, "");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;
			case '\022':
				strcpy (ss_buf, "pr");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;
			case 'r':
				strcpy (ss_buf, "reply");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;
			case 't':
				strcpy (ss_buf, "talk");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;
			case 's':
				strcpy (ss_buf, "nm");
				ss_execute_line(ss_idx, ss_buf, &code);
				if (code != 0) goto punt;
				break;

			case 'h':
			case '?':
				printf("List of possible responses:\n\n");
				printf("<space>,n\tNext transaction\n");
				printf("c\t\tCatch up on transactions in meeting\n");
				printf("p\t\tPrevious transaction\n");
				printf("^R\t\tReview current transaction\n");
				printf("q\t\tQuit from read_new\n");
				printf("r\t\tReply to current transaction\n");
				printf("t\t\tEnter a new transaction\n");
				printf("s\t\tSkip this meeting\n");
				printf("?,h\t\tShow this list\n\n");
				break;
			}
		}

		if (!changed_meetings())
		     break;

		cmd = more_break("Hit space to go to next meeting: ", " qn?hptr\022");
		if (interrupt)
		     break;
		printf("\n");
		switch(cmd) {
		case 'q':
		     goto punt;
		case ' ':
		case 'n':
		     strcpy (ss_buf, "nm");
		     ss_execute_line(ss_idx, ss_buf, &code);
		     if (code != 0) goto punt;
		     break;
		case 'p':
		     strcpy (ss_buf, "prev");
		     ss_execute_line(ss_idx, ss_buf, &code);
		     if (code != 0) goto punt;
		     break;
                case '\022':
		     strcpy (ss_buf, "pr");
		     ss_execute_line(ss_idx, ss_buf, &code);
		     if (code != 0) goto punt;
		     break;
		case 'r':
		     strcpy (ss_buf, "reply");
		     ss_execute_line(ss_idx, ss_buf, &code);
		     if (code != 0) goto punt;
		     break;
		case 't':
		     strcpy (ss_buf, "talk");
		     ss_execute_line(ss_idx, ss_buf, &code);
		     if (code != 0) goto punt;
		     break;
		case 'h':
		case '?':
		     printf("List of possible responses:\n\n");
		     printf("<space>,n\tNext meeting\n");
		     printf("p\t\tPrevious transaction\n");
		     printf("^R\t\tReview the current transaction\n");
		     printf("q\t\tQuit from read_new\n");
		     printf("r\t\tReply to current transaction\n");
		     printf("t\t\tEnter a new transaction\n");
		     printf("?\t\tShow this list\n\n");
		     break;
		}
	}

done:
	return;

punt:
	dont_flag_interrupts();
	ss_perror(ss_idx, code, 0);
}

/*
 * Flames to /dev/null
 */

#ifndef HAVE_TERMIOS_H

more_break(prompt, cmds)
	char *prompt;
	char *cmds;
{
	struct sgttyb tty, ntty;
	int arg;
	char buf[1];

	arg = FREAD;				/* Flush pending input */
	ioctl(0, TIOCFLUSH, &arg);
	ioctl(0, TIOCGETP, &tty);		/* Get parameters.. */
	ntty = tty;
	ntty.sg_flags |= CBREAK;
	ntty.sg_flags &= ~ECHO;
	ioctl(0, TIOCSETP, &ntty);		/* go to cbreak, ~echo */
	write(1, prompt, strlen(prompt));
	for (;;)  {
		if (read(0, buf, 1) != 1) {
			buf[0] = 'q';
			break;
		}
		if (strchr(cmds, buf[0]))
			break;
		write(1, "\7", 1);
	}
	ioctl(0, TIOCSETP, &tty);
	write(1, "\n", 1);
	return buf[0];
}

#else /* HAVE_TERMIOS_H */

more_break(prompt, cmds)
	char *prompt;
	char *cmds;
{
	int arg;
	char buf[1];
	struct termios tty, ntty;

	(void) tcflush(0, TCIFLUSH);
	(void) tcgetattr(0, &tty);
	ntty = tty;
	ntty.c_cc[VMIN] = 1;
	ntty.c_cc[VTIME] = 0;
        ntty.c_iflag &= ~(ICRNL);
        ntty.c_lflag &= ~(ICANON|ISIG|ECHO);
	(void) tcsetattr(0, TCSANOW, &ntty);
	write(1, prompt, strlen(prompt));
	for (;;)  {
		if (read(0, buf, 1) != 1) {
			buf[0] = 'q';
			break;
		}
		if (strchr(cmds, buf[0]))
			break;
		write(1, "\7", 1);
	}
	(void) tcsetattr(0, TCSANOW, &tty);
	write(1, "\n", 1);
	return buf[0];
}

#endif

static
unseen_transactions()
{
     return (dsc_public.current < dsc_public.m_info.last);
}
