#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifdef __GNUC__
#include "clib.h"
#endif
#include "othello.h"
#include "io.h"
#include "global.h"


/* external functions */
extern void   count_pieces();
extern bool   can_move();
extern int    num_legal_moves();


/*
 * Initialize the io package.
 */

void
init_io(argc, argv)
int    *argc;
char   *argv[];
{
}



/*
 * Print some statistics about the state PLAYSTATE.
 */

void
print_statistics(state)
State   *state;
{
    int   mypieces;
    int   yourpieces;
    
    count_pieces(state, &mypieces, &yourpieces);
    printf("me:\t%d\n", mypieces);
    printf("you:\t%d\n", yourpieces);
    fflush(stdout);
}



void
print_my_move(sq)
Square   sq;
{
    if (!quietmode)
	printf("My move: ");
    print_move(sq);
}



/*
 * Print a move in text format.
 */

void
print_move(sq)
Square   sq;
{
    if (sq == PASS)
	puts("pass");
    else
	printf("%c%c\n", COL(sq) + 'a' - 1, ROW(sq) + '0');
    fflush(stdout);
}



void
print_message(msg, force)
char   *msg;
bool   force;
{
    if (!quietmode || force) {
	printf("%s", msg);
	fflush(stdout);
    }
}



/*
 * Print a much simplified and somewhat formatted summary of the
 * position in 'state'.
 */

void
print_state(state)
State   *state;
{
    int   my;
    int   yours;
    
    print_board(&(state->board[0]));

    count_pieces(state, &my, &yours);
    printf("I have %d. \tYou have %d.\n\n", my, yours);
    fflush(stdout);
}



/*
 * Print a board with a little extra info.
 */

void
print_board(board)
Board   board;
{
    int   row;
    int   col;
    
    puts("   A B C D E F G H");
    for (row = 1; row <= 8; ++row) {
	putchar(' ');
	putchar(row + '0');
	putchar(' ');
	for (col = 1; col < 9; ++col) {
	    switch (board[SQ(col, row)]) {
	      case EMPTY:
		putchar('.');
		break;
	      case MYCOLOR:
		putchar(mycolor == WHITE ? 'O' : 'X');
		break;
	      case YOURCOLOR:
		putchar(yourcolor == WHITE ? 'O' : 'X');
		break;
	    }
	    putchar(' ');
	}
	putchar(row + '0');
	putchar('\n');
    }
    puts("   A B C D E F G H");
    fflush(stdout);
}


/* ======================= Input =========================*/


/*
 * Print help about commands to the user.
 */

static void
printhelp()
{
    puts("[a-hA-H][1-8]\tput a piece on the location.");
    puts("0\t\tpass - don't move (illegal if you can move)");
    puts("u\t\tundo your last move");
    puts("p\t\tprint the board");
    puts("l[1-9]\t\tset the playing level to the number. 1 is easiest.");
    puts("?\t\tprint this help.");
    fflush(stdout);
}



/*
 * Receive input from the user on stdin and check it. Don't return
 * until something legal was entered. All input is made lower case
 * prior to returning.
 *
 * If EOF was entered, the program stops short.
 */

static void
get_input(buffer)
char   buffer[];
{
    char   linebuf[100];
    bool   ok;

    ok = FALSE;
    do {
	if (!quietmode) {
	    putchar('>');
	    fflush(stdout);
	}

	(void) fgets(linebuf, 100, stdin);
	if (feof(stdin)) {
	    print_message("Giving up, eh?\n", FALSE);
	    exit(0);
	}

	if (strlen(linebuf) <= 3) {
	    if (isupper(linebuf[0]))
		linebuf[0] = tolower(linebuf[0]);

	    buffer[0] = linebuf[0];
	    buffer[1] = linebuf[1];
	    switch(buffer[0]) {
	      case 'a':    case 'b':    case 'c':    case 'd':
	      case 'e':    case 'f':    case 'g':    case 'h':
		if ('1' <= buffer[1] && buffer[1] <= '8')
		    ok = TRUE;
		break;

	      case 'u':
	      case 'p':
	      case '0':
	      case '?':
		if (buffer[1] = '\n')
		    ok = TRUE;
		break;

	      case 'l':
		if ('1' <= buffer[1] && buffer[1] <= '9')
		    ok = TRUE;
		break;

	      default:
		break;
	    }
	}

	if (!ok)
	    print_message("eh?\n", FALSE);

    } while (!ok);
}



/*
 * Get the users move, and return it. For getting the users input,
 * the function get_input is called. Also take care of other
 * user requests such as print the board, get help etc.
 */

Square
get_users_move(state)
State   *state;
{
    char       buffer[2];
    Square     sq;
    bool       ok;

    ok = FALSE;
    do {
	get_input(buffer);
	switch (buffer[0]) {
	  case 'a':    case 'b':    case 'c':    case 'd':
	  case 'e':    case 'f':    case 'g':    case 'h':
	    sq = SQ(buffer[0] - 'a' + 1, buffer[1] - '0');
	    ok = can_move(state, sq, YOURCOLOR);

	    if (!ok) {
		printf("no!\n");
		fflush(stdout);
	    }
	    break;

	  case '0':
	    if (num_legal_moves(state, YOURCOLOR) == 0) {
		ok = TRUE;
		sq = PASS;
	    } else {
		printf("no!\n");
		fflush(stdout);
	    }
	    break;

	  case 'u':
	    ok = TRUE;
	    sq = UNDO;
	    break;

	  case 'p':
	    print_state(state);
	    break;

	  case 'l':
	    level = buffer[1] - '0';
	    break;

	  case '?':
	    printhelp();
	    break;

	  default:
	    break;
	}
    } while (!ok);

    return sq;
}



bool
another_game()
{
    if (quietmode)
	return FALSE;

    printf("another game (y/n)?");
    do {
	answer = getchar();
    } while (answer != 'y' && answer != 'n');

    return answer == 'y';
}
