/*----------------------------------------------------------------------
 | IO.C								940420
 |
 | Contains the I/O-routines.
 +----------------------------------------------------------------------*/


#include "var.h"


static int CDECL CompareHistory(const void *h1, const void *h2);


/*----------------------------------------------------------------------
 | PrintBoard							940421
 |
 | Prints the board.
 +----------------------------------------------------------------------*/
void            PrintBoard(void)
{
    Signed2         i,
                    j;
    SquareType      square;
    char            s[MaxCommandLength];

    printf("%s\t", moveColorString[toMove]);
    if (epSquare[nrGamePlies] != NoEp) {
        SPrintSquare(s, epSquare[nrGamePlies]);
        printf("%s\t", s);
    }
    if (castling[nrGamePlies] & WhiteShort) {
        printf("WS ");
    }
    if (castling[nrGamePlies] & WhiteLong) {
        printf("WL ");
    }
    if (castling[nrGamePlies] & BlackShort) {
        printf("BS ");
    }
    if (castling[nrGamePlies] & BlackLong) {
        printf("BL ");
    }
    printf("%ld%c%d %ld%c%d", material[White],
        positionalValue[White] < 0 ? '-' : '+', abs(positionalValue[White]),
           material[Black], positionalValue[Black] < 0 ? '-' : '+',
           abs(positionalValue[Black]));
    printf("\t(%lx,%lx)", hashValue[nrGamePlies][0],
           hashValue[nrGamePlies][1]);
    printf("\n  +------------------------+\n");
    for (i = 8; i >= 1; i--) {
        printf("%d |", i);
        for (j = A; j <= H; j++) {
            square = Square(j, i);
            if (WhiteSquare(j, i)) {
                printf(":");
            } else {
                printf(" ");
            }
            if (IsEmpty(board[square])) {
                if (WhiteSquare(j, i)) {
                    printf(":");
                } else {
                    printf(" ");
                }
            } else {
                printf("%c", pieceSymbol[board[square]]);
            }
            if (WhiteSquare(j, i)) {
                printf(":");
            } else {
                printf(" ");
            }
        }                       /* for j */
        printf("|\n");
    }                           /* for i */
    printf("  +------------------------+\n");
    printf("    A  B  C  D  E  F  G  H\n");
}                               /* PrintBoard */


/*----------------------------------------------------------------------
 | PrintMoveList						940425
 |
 | Prints all moves from a move list.
 +----------------------------------------------------------------------*/
void            PrintMoveList(MoveType * list, Unsigned1 nrMoves)
{
    Signed2         i;
    char            s[MaxCommandLength];

    for (i = 0; i < nrMoves; i++) {
        SPrintMove(s, list[i]);
        printf("%s ", s);
    }
/*
   printf( "\n\nSorted:\n" );
   HeapSort( list, nrMoves );
   for (i=0; i<nrMoves; i++) {
   SPrintMove( s, list[ i ] );
   printf( "%s ", s );
   }
 */
    printf("\n");
}                               /* PrintMoveList */


/*----------------------------------------------------------------------
 | PrintAllocVariables						940425
 |
 | Prints all allocate variables.
 +----------------------------------------------------------------------*/
void            PrintAllocVariables(void)
{
    printf("Allocated move lists: %d\n", nrAllocMoveLists);
    printf("Allocated path moves: %d\n", nrAllocPathMoves);
}                               /* PrintAllocVariables */


void            PrintGame(Signed2 from, Signed2 to)
{
    Signed2         i;

    for (i = from; i <= to; i++) {
        if (i % 2 == 0) {
            printf("%3d.", i / 2 + 1);
        }
        printf(" %s", gameString[i]);
        if (i % 8 == 7) {
            printf("\n");
        }
    }
    printf("\n");
}                               /* PrintGame */


/*----------------------------------------------------------------------
 | PrintPath							940506
 |
 | Prints a move path.
 +----------------------------------------------------------------------*/
void            PrintPath(PathType * path)
{
    PathType       *ptr;
    Signed2         i,
                    j;

    if (path == NULL) {
        return;
    }
    for (i = 0, ptr = path; ptr != NULL; ptr = ptr->next, i++) {
        if (i && !(i % 6)) {
            printf("\n                     ");
        }
        printf("%-8s", ptr->moveString);
    }
    for (j = 0; j < (6 - i % 6) % 6; j++) {
        printf("        ");
    }
    printf("%d", i);
}                               /* PrintPath */


void            PrintHistoryTable(void)
{
    BoardIndexType  i,
                    j;
    char            s[4];
    Unsigned2       nrHistoryMoves;
    History         table[500];

    printf("White:\n");
    nrHistoryMoves = 0;
    for (i = A1; i <= H8; i++) {
        for (j = A1; j <= H8; j++) {
            if (historyTable[White][i][j] != 0) {
                table[nrHistoryMoves].from = i;
                table[nrHistoryMoves].to = j;
                table[nrHistoryMoves++].nr = historyTable[White][i][j];
            }
        }
    }
    qsort(table, nrHistoryMoves, sizeof(History), CompareHistory);
    for (i = 0; i < (BoardIndexType) nrHistoryMoves; i++) {
        SPrintSquare(s, table[i].from);
        printf("%s", s);
        SPrintSquare(s, table[i].to);
        printf("%s%5d,", s, table[i].nr);
    }

    printf("\n\nBlack:\n");
    nrHistoryMoves = 0;
    for (i = A1; i <= H8; i++) {
        for (j = A1; j <= H8; j++) {
            if (historyTable[Black][i][j] != 0) {
                table[nrHistoryMoves].from = i;
                table[nrHistoryMoves].to = j;
                table[nrHistoryMoves++].nr = historyTable[Black][i][j];
            }
        }
    }
    qsort(table, nrHistoryMoves, sizeof(History), CompareHistory);
    for (i = 0; i < (BoardIndexType) nrHistoryMoves; i++) {
        SPrintSquare(s, table[i].from);
        printf("%s", s);
        SPrintSquare(s, table[i].to);
        printf("%s%5d,", s, table[i].nr);
    }
}                               /* PrintHistoryTable */


static int      CDECL
                CompareHistory(const void *his1, const void *his2)
{
    History        *h1,
                   *h2;

    h1 = (History *) his1;
    h2 = (History *) his2;
    if (h1->nr < h2->nr) {
        return (1);
    }
    if (h1->nr > h2->nr) {
        return (-1);
    }
    return (0);
}                               /* CompareHistory */


void            PrintHashes(void)
{
    Signed2         i;

    for (i = nrGamePlies; i >= startHashIndex[nrGamePlies]; i--) {
        printf("%3d: %x, %x\n", i, hashValue[i][0], hashValue[i][1]);
    }
}                               /* PrintHashes */


void            PrintSettings(void)
{
    printf("\nSettings\n");
    printf("--------\n");
    printf("Refutation table   : %s\n", logicString[useRefTable]);
    printf("Transposition table: %s\n", logicString[useTransTable]);
    if (useTransTable) {
        printf("\nClearing entries with age %d ply\n", keepPly + 1);
        printf("Keepmethod   : %s\n", methodString[keepMethod]);
        printf("TwoLevelTable: %s\n", logicString[useTwoLevelTable]);
        printf("UseTtValue   : %s\n", logicString[useTtValue]);
        printf("UseTtMove    : %s\n", logicString[useTtMove]);
        printf("useFlag      : %s\n", logicString[useFlag]);
        printf("timeStamp    : %s\n", logicString[timeStamp]);
    }
}                               /* PrintSettings */


void            PrintTestSettings(Signed2 testDepth, Signed2 testColor,
                                                  Signed4 testNrNodes)
{
    printf("\nTest settings\n");
    printf("-------------\n");
    printf("search with depth            : %d\n", testDepth);
    printf("search with color            : %s\n", moveColorString[testColor]);
    printf("search with max. number nodes: %d\n", testNrNodes);
    printf("----------------------------------------------------------------\n");
}
