/*
 * hearts - human interface to hearts program
 *
 * All smarts are in heartsd, which is invoked by initial caller of hearts.
 *
 * Private messages, last-play, auto-play added by:
 *      Mike Yang of Silicon Graphics (mikey@sgi.com)
 *
 * By Bob Ankeney or Generic Computer Products
 * Bug reports to:
 * ...!tektronix!reed!bob
 *
 *
 * Commands to hearts client (r = rank, s = suit):
 *
 * Ars		Add card to hand.
 * Rrs		Remove card from hand.
 * En		Erase window n.
 * G		Get a card.
 * Pnrs<name>	Play card from player n, whose name is <name>.
 * Snpptt<name>	Score points (pp) and total points (tt) for player n.
 * Mn<text>	Message <text> is placed in window n.
 * X		Go away.
 *
 * Messages from client:
 *
 * Prs		Pass/Play card from hand.
 * M<text>		Send message <text> to all players.
 *
 */

#define SYSV
#include <curses.h>
#include <stdlib.h>
#include <sys/errno.h>
#include "misc.h"
#include "defs.h"
#include "local.h"
#include "client.h"
#ifdef SYSV
#include <sys/termio.h>
#endif

typedef struct node *ptr;

struct node {
	ptr	llink, rlink;
	int	rank;
};

struct	suit_list {
	ptr	head, tail;
	int	length;
} 
my_hand[MAX_SUIT + 1];

WINDOW	*card_window[MAX_SUIT + 1],
	*round_window, *lead_window, *inp_window, *text_window,
	*play_window, *tplay_window, *mesg_window, *tmesg_window,
	*header_window, *score_window, *opening_window,
  	*play_save,
	**window_ptr[MESG_WINDOW + 1];

int	mesg_bottom,	/* Bottom line of lower message window */
	tmesg_bottom;	/* Bottom line of upper message window */
char	show_play,	/* TRUE = show play/score window, FALSE = show mesg */
	show_old;

char got_char;

mikey_save_swap()
{
  WINDOW *temp;

  temp = play_window;
  play_window = play_save;
  play_save = temp;
  touchwin(play_window);
}

mikey_old(ref)
int ref;
{
  mikey_save_swap();
  if (ref)
    wrefresh(play_window);
  show_old = !show_old;
}

init_suit(list)
struct suit_list *list;
{
	list->length = 0;
	list->head = (ptr) malloc(sizeof(struct node));
	list->tail = (ptr) malloc(sizeof(struct node));
	list->head->llink = NULL; 
	list->tail->rlink = NULL;
	list->head->rlink = list->tail; 
	list->tail->llink = list->head;
	list->head->rank = MAX_RANK + 1; 
	list->tail->rank = 0;
}

init(argc_p, argv)
int *argc_p;
char **argv;
{
	int	wimp_out();
	int	suit;
	char	ch;
	char	buffer[128];
	char	*pager;

	initscr();
	clearok(stdscr, FALSE);
	crmode();
	init_windows();

	mvwaddstr(opening_window, 0, 0, 
		  "      ***************************************     ");
	mvwaddstr(opening_window, 1, 0, 
		  "      ***  Welcome to the Game of Hearts  ***     ");
	mvwaddstr(opening_window, 2, 0, 
		  "      ***************************************     ");
	if (MIKEYJ)
	  mvwaddstr(opening_window, 4, 0,
		  "     Note that the Jack of Diamonds scores -10    ");
	mvwaddstr(opening_window, 6, 0,
		  "Typing 'L' shows the contents of the previous hand");
	mvwaddstr(opening_window, 8, 0,
		  "  This version (supposedly) has improved strategy ");
	mvwaddstr(opening_window, 9, 0,
		  "      for the computer players.  Send computer    ");
	mvwaddstr(opening_window, 10, 0,
		  "         mistakes and suggestions to mikey.       ");
	mvwaddstr(opening_window, 12, 0,
		  "            Do you need instructions? ");
	wrefresh(opening_window);
	ch = get_char();
	if ((ch == 'y') || (ch == 'Y')) {
		clear();
		refresh();
		(void) fflush(stdout);
		endwin();
		if (!(pager = getenv ("PAGER")))
			pager = "more";
		(void) sprintf (buffer, "%s %s/%s", pager, HEARTSLIB, INSTRUCT);
		(void) system(buffer);
		crmode();
		printf ("Press return to continue: "); 
		(void) fflush (stdout);
		(void) get_char();
	}
	noecho();

	for (suit = CLUBS; suit <= SPADES; suit++)
		init_suit(&my_hand[suit]);
}

/*
 *			Screen window layout
 *
 *                   2             4             6             7
 *     0             0             0             0             9
 *      --------------------------------------------------------
 *   0 |             |             |             |             |
 *   1 | card_window | card_window | card_window | card_window |
 *   2 |   [CLUBS]   |  [DIAMONDS] |   [HEARTS]  |   [SPADES]  |
 *     ~             ~             ~             ~             ~
 *     ~             ~             ~             ~             ~
 *  16 |             |             |             |             |
 *     |-------------------------------------------------------|
 *     |                                                       |
 *                         if show_play:
 *
 *                    2                      5                 7
 *     0              2                      8                 9
 *     |                                                       |
 *     ---------------------------------------------------------
 *  17 | round_window |                      |score_text_window|
 *     |--------------|                      |-----------------|
 *  18 |              |                      |                 |
 *     |--------------|                      |                 |
 *  19 | lead_window  |                      |                 |
 *     |--------------|                      |                 |
 *  20 | inp_window   |    play_window       |                 |
 *     |--------------|                      |                 |
 *  21 |              |                      |                 |
 *     |--------------|                      |                 |
 *  22 | text_window  |                      |                 |
 *     |--------------|----------------------------------------|
 *  23 |              |                                        |
 *     ~              ~                 mesg_window            ~
 *     ~              ~                                        ~
 *LINES|              |                                        |
 *     ---------------------------------------------------------
 *
 *                         if !show_play:
 *
 *                    2                      5                 7
 *     0              2                      8                 9
 *     |                                                       |
 *     ---------------------------------------------------------
 *  17 | round_window |     tplay_window     |                 |
 *     |--------------|----------------------------------------|
 *  18 |              |                                        |
 *     |--------------|                                        |
 *  19 | lead_window  |                                        |
 *     |--------------|                                        |
 *  20 | inp_window   |                tmesg_window            |
 *     |--------------|                                        |
 *  21 |              |                                        |
 *     |--------------|                                        |
 *  22 | text_window  |                                        |
 *     |--------------|----------------------------------------|
 *  23 |              |                                        |
 *     ~              ~                 mesg_window            ~
 *     ~              ~                                        ~
 *LINES|              |                                        |
 *     ---------------------------------------------------------
 */
init_windows()
{
	int i;

	for (i = CLUBS; i <= SPADES; i++) {
		card_window[i] = newwin(17, 20, 0, (i - 1) * 20);
		leaveok(card_window[i], TRUE);
		werase(card_window[i]);
	}
	round_window	= newwin(1, 22, 17,  0);
	lead_window	= newwin(1, 22, 19,  0);
	inp_window	= newwin(1, 22, 20,  0);
	text_window	= newwin(1, 22, 22,  0);
	play_window	= newwin(6, 35, 17, 23);
	tplay_window	= newwin(1, 57, 17, 23);
	header_window	= newwin(1, 22, 17, 58);
	score_window	= newwin(5, 22, 18, 58);
	mesg_window	= newwin(0, 57, 23, 23);
	tmesg_window	= newwin(5, 57, 18, 23);
	opening_window	= newwin(14,50,  5, 15);
	play_save	= newwin(6, 35, 17, 23);
	mesg_bottom = LINES - 24;
	tmesg_bottom = 4;
	scrollok(mesg_window, TRUE);
	scrollok(tmesg_window, TRUE);
	window_ptr[ROUND_WINDOW] = &round_window;
	window_ptr[LEAD_WINDOW]  = &lead_window;
	window_ptr[INP_WINDOW]   = &inp_window;
	window_ptr[TEXT_WINDOW]  = &text_window;
	window_ptr[PLAY_WINDOW]  = &play_window;
	window_ptr[SCORE_WINDOW] = &score_window;
	window_ptr[MESG_WINDOW]  = &mesg_window;
}

/*
 * toggle_mesg - toggle whether showing message window or score/play windows
 */
toggle_mesg()
{
	if (show_play) {
		touchwin(tplay_window);
		touchwin(tmesg_window);
		wrefresh(tplay_window);
		wrefresh(tmesg_window);
	}
	else {
		touchwin(play_window);
		touchwin(header_window);
		touchwin(score_window);
		wrefresh(play_window);
		wrefresh(header_window);
		wrefresh(score_window);
	}
	show_play = !show_play;
}

/*
 * ovl_refresh - refresh window only if visible
 */
ovl_refresh(window_num)
int	window_num;
{
	switch (window_num) {
	case PLAY_WINDOW:
		if (show_play)
			wrefresh(play_window);
		break;
	case SCORE_WINDOW:
		if (show_play)
			wrefresh(score_window);
		break;
	default:
		wrefresh(*window_ptr[window_num]);
	}
}

/*
 * scroll_mesg - scroll mesg_window onto tmesg_window
 */
scroll_mesg()
{
	int	i;
	char	ch;
	int     x,y;

/*
	wmove(tmesg_window, tmesg_bottom, 56);
	scroll(tmesg_window);
*/

	for (x = 0; x < tmesg_bottom; x++) {
	  for (y = 0; y < 56; y++) {
	    wmove(tmesg_window,x+1,y);
	    ch = winch(tmesg_window);
	    wmove(tmesg_window,x,y);
	    waddch(tmesg_window, ch);
	  }
	}

	wmove(tmesg_window, tmesg_bottom, 0);

	for (i = 0; i < 56; i++) {
		wmove(mesg_window, 0, i);
		ch = winch(mesg_window);
		waddch(tmesg_window, ch);
	}
	scroll(mesg_window);
	if (!show_play)
		wrefresh(tmesg_window);
}
	
put_card(window, y, x, rank, suit)
WINDOW	*window;
int	y, x,
rank, suit;
{
	mvwaddstr(window, y,     x, "+-----+");
	mvwaddstr(window, y + 1, x, "|     |");
	mvwaddstr(window, y + 2, x, "|     |");
	mvwaddstr(window, y + 3, x, "|     |");
	mvwaddstr(window, y + 4, x, "+-----+");
	if ((suit == HEARTS) || (suit == DIAMONDS))
		wstandout(window);
	mvwaddch(window, y + 1, x + 1, rnames[rank]);
	waddch(window, *snames[suit]);
	mvwaddch(window, y + 3, x + 4, rnames[rank]);
	waddch(window, *snames[suit]);
	wstandend(window);
}

print_cards(suit)
int	suit;
{
	int y, x;
	ptr p;

	werase(card_window[suit]);
	x = y = 0;
	p = my_hand[suit].head->rlink;
	while (p->rank) {
		if (x == 7) {
			++x;
			y = 0;
		}
		put_card(card_window[suit], y, x++, p->rank, suit);
		y += 2;
		p = p->rlink;
	}
	wrefresh(card_window[suit]);
}

get_char()
{
	char	ch;

	if (read(0, &ch, 1) == -1) {
		perror("read");
		abort();
	}
	return(ch);
}

read_char()
{
	char	ch;

	while (!got_char)
		scan();
	ch = got_char;
	got_char = FALSE;
	return(ch);
}

read_card()
{
	int	rank, suit;
	char	buf[64];

	do {
		do {
			werase(inp_window);
			wrefresh(inp_window);
			buf[0] = 'P';
			buf[1] = read_char();	/* Get rank (not smelly) */
			if (buf[1] >= 'a')
				buf[1] += 'A' - 'a';
			if ((buf[1] != '?') && (!(rank = get_rank(buf[1])))) {
				werase(text_window);
				waddstr(text_window, "Bad rank!");
				wrefresh(text_window);
			}
			if (buf[1] == '?')
			  rank = 1;
		} 
		while (!rank);
		werase(text_window);
		wrefresh(text_window);
		wprintw(inp_window, "%c ", buf[1]);
		wrefresh(inp_window);
		if (show_old)
		  mikey_old(TRUE);
		if (buf[1] == '?')
		  suit = HEARTS;
		else {
		buf[2] = read_char();		/* Get suit (not tuxedo) */
		if ((buf[2] >= 'A') && (buf[2] <= 'Z'))
			buf[2] += 'a' - 'A';
		if (!(suit = get_suit(buf[2])) &&
#ifndef SYSV
		    (buf[2] != _tty.sg_erase) && (buf[2] != _tty.sg_kill)) {
#else
		    (buf[2] != VERASE) && (buf[2] != VKILL)) {
#endif
			werase(text_window);
			waddstr(text_window, "Bad suit!");
			wrefresh(text_window);
		}
	      }
	} 
	while (!suit);
	if (buf[1] != '?')
	  wprintw(inp_window, "of %s", snames[suit]);
	wrefresh(inp_window);
	if (buf[1] == '?')
	  send_auto();
	else
	  send_card(buf[1], buf[2]);
}

enter_card0(rank, suit)
int	rank, suit;
{
	ptr p, p1;

	p = my_hand[suit].head;
	++my_hand[suit].length;
	while (p->rank > rank)
		p = p->rlink;
	p1 = (ptr) malloc(sizeof(struct node));
	p1->llink = p->llink;
	p1->llink->rlink = p1;
	p->llink = p1;
	p1->rlink = p;
	p1->rank = rank;
}

remove_node(p)
ptr	p;

{
	p->llink->rlink = p->rlink;
	p->rlink->llink = p->llink;
	free((char *) p);
}


ptr
find_card(rank_to_play, suit_to_play)
int	rank_to_play, suit_to_play;
{
	ptr	card_to_play;

	card_to_play = my_hand[suit_to_play].head->rlink;
	while (card_to_play->rank != rank_to_play)
		card_to_play = card_to_play->rlink;
/*
	remove_node(card_to_play);
*/
	--my_hand[suit_to_play].length;
	return(card_to_play);
}

enter_card(rank, suit)
int rank, suit;
{
  enter_card0(rank, suit);
  print_cards(suit);
}

remove_card(rank, suit)
int rank, suit;
{
  remove_node(find_card(rank, suit));
  print_cards(suit);
}

erase_window(window_num)
int window_num;
{
  if (window_num == PLAY_WINDOW) {
    if (show_old)
      mikey_old(TRUE);
    mikey_save_swap();
    werase(tplay_window);
    if (!show_play)
      wrefresh(tplay_window);
  }
  werase(*window_ptr[window_num]);
  ovl_refresh(window_num);
}

play_card(player, rch, sch, msg)
int player, rch, sch;
char *msg;
{
  /*
   * Update standard play window
   */
  if (show_old) {
    mikey_old(FALSE);
    put_card(play_window, 0, (player - 1) * 9,
	     get_rank(rch), get_suit(sch));
    if (*msg != '\0')
      mvwaddstr(play_window, 5, (player - 1) * 9, msg);
    mikey_old(FALSE);
  } else {
    put_card(play_window, 0, (player - 1) * 9,
	     get_rank(rch), get_suit(sch));
    if (*msg != '\0')
      mvwaddstr(play_window, 5, (player - 1) * 9, msg);
  }
  /*
   * Update alternate play window
   */
  if ((sch == 'h') || (sch == 'd'))
    wstandout(tplay_window);
  mvwaddch(tplay_window, 0, (player - 1) * 9, rch);
  waddch(tplay_window, sch);
  wstandend(tplay_window);
  if (show_play)
    wrefresh(play_window);
  else
    wrefresh(tplay_window);
  sleep(1);
}

score_points(player, pts, total_pts, msg)
int player, pts, total_pts;
char *msg;
{
  mvwaddstr(score_window, player - 1, 1, "        ");
  mvwaddstr(score_window, player - 1, 1, msg);
  mvwprintw(score_window, player - 1, 9, "% 3d    % 3d",
	    pts, total_pts);
  
  ovl_refresh(SCORE_WINDOW);
}

display_message(window_num, msg)
int window_num;
char *msg;
{
  int	temp_y, temp_x;

  getyx(curscr, temp_y, temp_x);
  if (window_num == MESG_WINDOW) {
    scroll_mesg();
    mvwaddstr(mesg_window, mesg_bottom, 0, msg);
    wclrtoeol(mesg_window);
  }
  else {
    werase(*window_ptr[window_num]);
    mvwaddstr(*window_ptr[window_num], 0, 0, msg);
  }
  ovl_refresh(window_num);
  move(temp_y, temp_x);
  refresh();
}

game_is_over()
{
  if (!show_play)
    toggle_mesg();
  werase(round_window);
  wrefresh(round_window);
  werase(lead_window);
  wstandout(lead_window);
  mvwaddstr(lead_window, 0, 0, "--More--");
  wstandend(lead_window);
  wrefresh(lead_window);
  (void) get_char();
}

start_game()
{
  werase(play_window);
  mvwaddstr(header_window, 0, 1, "player  score  total");
  show_play = show_old = FALSE;
  toggle_mesg();			/* Show play and score windows */
}

/*
 * Scan input for redraw screen requests or ':' messages.
 * Also scan socket for incoming commands.
 */
scan()
{
	int		i, temp_y, temp_x;
	char		buf[64];
	fd_type	read_fd;
	int		nready;
	extern int	errno;

	int     mikey;
        char    remember[57];

	fd_init(dealer_socket, &read_fd);
	if (!got_char)
		fd_set(0, &read_fd);
	do {
		nready = select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
		(struct timeval *) 0);
	}
	while (nready == -1 && errno == EINTR);
	if (nready == 0)
		return;
	if (fd_isset(0, read_fd)) {
		got_char = get_char();
		getyx(curscr, temp_y, temp_x);
		switch (got_char) {
		case '\f' :
			wrefresh(curscr);	/* Redraw screen */
			got_char = FALSE;
			break;

		case ' '  :
		case '\t' :
		case '\n' :
		case '\r' :
			got_char = FALSE;	/* Ignore white space */
			break;

		case 'M' :
		case 'm' :
			toggle_mesg();
			got_char = FALSE;
			break;

		case 'L' :
		case 'l' :
		  	if (show_play) {
			  mikey_old(TRUE);
			}
			got_char = FALSE;
			break;

		case ':' :
  		        for (mikey = 0; mikey < 56; mikey++) {
			  wmove(mesg_window, 0, mikey);
			  remember[mikey] = winch(mesg_window);
			}
/*
  scroll_mesg();       
*/
			/* Message to all players */

			mvwaddstr(mesg_window, mesg_bottom, 0, "message: ");
			wmove(mesg_window, mesg_bottom, 9);
			wclrtoeol(mesg_window);
			wrefresh(mesg_window);
			buf[0] = 'M';
			for (i = 1; (i < 48) && ((buf[i] = get_char()) != '\n') && buf[i] != '\r';
					i++) {
#ifndef SYSV
				if (buf[i] == _tty.sg_erase) {
#else
				if (buf[i] == VERASE) {
#endif
					i -= 2;
					if (i < 0)
						i = 0;
					else {
						wmove(mesg_window, mesg_bottom, i+9);
						wdelch(mesg_window);
					}
				} 
				else {
#ifndef SYSV
					if (buf[i] == _tty.sg_kill) {
#else
					if (buf[i] == VKILL) {
#endif
						wmove(mesg_window, mesg_bottom, 9);
						wclrtoeol(mesg_window);
						i = 0;
					} 
					else
					  if (buf[i] <= 27) {
					    i -= 1;
					    if (i < 0)
					      i = 0;
					    else {
					      wmove(mesg_window, mesg_bottom, i+9);
					      wdelch(mesg_window);
					    }
					  }
					  else
						mvwaddch(mesg_window, mesg_bottom, i + 8, buf[i]);
				}
				wrefresh(mesg_window);
			}

			wmove(mesg_window, 0, 0);
  		        for (mikey = 0; mikey < 56; mikey++) {
			  waddch(mesg_window, remember[mikey]);
			}

			buf[i] = '\0';
			send_message(buf+1);
			got_char = FALSE;
			break;

		case '~' :
		        toggle_private_messages();
			break;

		case ';' :
  		        for (mikey = 0; mikey < 56; mikey++) {
			  wmove(mesg_window, 0, mikey);
			  remember[mikey] = winch(mesg_window);
			}
/*
  scroll_mesg();       
*/
			/* Private message */

			mvwaddstr(mesg_window, mesg_bottom, 0, "player; ");
			wmove(mesg_window, mesg_bottom, 8);
			wclrtoeol(mesg_window);
			wrefresh(mesg_window);
			buf[0] = ';';
			buf[1] = get_char();
			mvwaddstr(mesg_window, mesg_bottom, 0, "message; ");
			wmove(mesg_window, mesg_bottom, 9);
			wclrtoeol(mesg_window);
			wrefresh(mesg_window);
			for (i = 2; (i < 49) && ((buf[i] = get_char()) != '\n') && buf[i] != '\r';
					i++) {
#ifndef SYSV
				if (buf[i] == _tty.sg_erase) {
#else
				if (buf[i] == VERASE) {
#endif
					i -= 2;
					if (i < 0)
						i = 0;
					else {
						wmove(mesg_window, mesg_bottom, i+8);
						wdelch(mesg_window);
					}
				} 
				else {
#ifndef SYSV
					if (buf[i] == _tty.sg_kill) {
#else
					if (buf[i] == VKILL) {
#endif
						wmove(mesg_window, mesg_bottom, 8);
						wclrtoeol(mesg_window);
						i = 0;
					} 
					else
					  if (buf[i] <= 27) {
					    i -= 1;
					    if (i < 0)
					      i = 0;
					    else {
					      wmove(mesg_window, mesg_bottom, i+8);
					      wdelch(mesg_window);
					    }
					  }
					  else
						mvwaddch(mesg_window, mesg_bottom, i + 7, buf[i]);
				}
				wrefresh(mesg_window);
			}

			wmove(mesg_window, 0, 0);
  		        for (mikey = 0; mikey < 56; mikey++) {
			  waddch(mesg_window, remember[mikey]);
			}

			buf[i] = '\0';
			send_private_message((int) buf[1]-'0', buf+2);
			got_char = FALSE;
		}
		move(temp_y, temp_x);
		refresh();
	}
	if (fd_isset(dealer_socket, read_fd)) {
	  do_socket();
	}
}

terminate()
{
	clear();
	refresh();
	(void) fflush(stdout);
	endwin();
}

/*
 * show_table - display table which is position table_pos on screen.
 */
show_table(cur_ptr, table_pos)
table_ptr	cur_ptr;
int		table_pos;
{
	int	window_num, window_pos;
	int 	i;

	window_num = table_pos % 4 + 1;
	window_pos =  (table_pos + 4) & 8;
	for (i = 0; i < 6; i++) {
		wmove(card_window[window_num], window_pos + i, 0);
		wclrtoeol(card_window[window_num]);
	}
	mvwprintw(card_window[window_num], window_pos++, 0,
		"     Table %d", table_pos + 1);
	if (cur_ptr->closed)
		mvwaddstr(card_window[window_num], window_pos++, 0,
			"    <game over>");
	else {
		if (cur_ptr->hand == 0)
			mvwaddstr(card_window[window_num], window_pos++, 0,
				"     <starting>");
		else
			mvwprintw(card_window[window_num], window_pos++, 0,
					"Hand: %d  Round: %d",
					cur_ptr->hand, cur_ptr->round);
		for (i = 0; i <4; i++)
			mvwaddstr(card_window[window_num], window_pos++, 5,
				cur_ptr->player_name[i]);
	}
	wrefresh(card_window[window_num]);
}

/*
 * show_tables - display up to 8 tables starting with table # start_id.
 */
show_tables(start_id)
int	start_id;
{
	table_ptr	cur_ptr;
	int		cur_id, i;

	for (i = 0; i < 8; i++)
		screen_table_id[i] = 0;
	werase(round_window);
	if (table_count)
		mvwprintw(round_window, 0, 0, "Page %d of %d",
				(start_id + 7) / 8, (table_count + 7) / 8);
	wrefresh(round_window);
	cur_ptr = first_table;
	for (cur_id = 1; cur_id < start_id; cur_id++)
		cur_ptr = cur_ptr->next_table;
	for (cur_id = 0; (cur_id < 8) && cur_ptr;
			cur_ptr = cur_ptr->next_table) {
		screen_table_id[cur_id] = cur_ptr->table_id;
		show_table(cur_ptr, cur_id++);
	}
	show_options();
}

ask_option()
{
	werase(lead_window);
	mvwaddstr(lead_window, 0, 0, "Option: ");
	wrefresh(lead_window);
}

show_options()
{
	werase(play_window);
	mvwaddstr(play_window, 0, 0, "Options are:");
	if (!first_game)
		mvwaddstr(play_window, 1, 0, "<A>nother game");
	mvwaddstr(play_window, 2, 0, "<N>ew game");
	if ((table_count) && (first_game))
		mvwaddstr(play_window, 3, 0, "<J>oin game");
	if (table_count > 8)
		mvwaddstr(play_window, 4, 0, "<M>ore games");
	mvwaddstr(play_window, 5, 0, "<Q>uit");
	wrefresh(play_window);
	ask_option();
}

option_scan(another)
char *another;
{
  fd_type read_fd;
  int i;
  char ch;

  *another = FALSE;
  fd_init(0, &read_fd);		/* stdin */
  fd_set(dist_socket, &read_fd);
  if (select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
	     (struct timeval *) 0) == -1)
    if (select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
	       (struct timeval *) 0) == -1)
      dist_died(2);
  if (fd_isset(dist_socket, read_fd)) {
    do_dist();
  }
  if (fd_isset(0, read_fd)) {
    ch = get_char();
    werase(text_window);
    wrefresh(text_window);
    switch (ch) {
    case 'Q' :
    case 'q' :
      wimp_out();
    case 'A' :
    case 'a' :
      *another = TRUE;
      if (!first_game)
	joined = TRUE;
      break;
    case 'N' :
    case 'n' :
      start_new_game();
      joined = TRUE;
      break;
    case 'J' :
    case 'j' :
      if ((table_count) && (first_game)) {
	mvwaddstr(lead_window, 0, 0, "Join table #:");
	wrefresh(lead_window);
	joining = TRUE;
      }
      break;
    case 'M' :
    case 'm' :
      if (table_count > 8) {
	if ((cur_screen_table += 8) > table_count)
	  cur_screen_table = 1;
	for (i = CLUBS; i <= SPADES; i++) {
	  werase(card_window[i]);
	  wrefresh(card_window[i]);
	}
	show_tables(cur_screen_table);
      }
      break;
    default:
      if (joining && (ch >= '1') && (ch <= '8')) {
	if (i = screen_table_id[ch - '1']) {
	  join_game(i);
	  joined = TRUE;
	}
	else {
	  mvwaddstr(text_window, 0, 0, "Table not open.");
	  wrefresh(text_window);
	  ask_option();
	}
      }
      else {
	mvwaddstr(text_window, 0, 0, "Huh?");
	wrefresh(text_window);
	ask_option();
      }
      joining = FALSE;
      break;
    }
  }
}

option_init()
{
  clear();
  refresh();
}

init_socket()
{
}

close_socket(s)
int s;
{
}

option_clear()
{
}
