/*
 *    MAIN.C
 *
 *      sachovy program pro unix - ver. 0.1b
 *      ========================
 *
 *      Martin Macok
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "data.h"

#ifdef UNIX
#include <signal.h>
#endif				/*  */

void undo(THra *);		/* vezme zpet posledni tah */

int IQ = DEPTH, SIQ = SDEPTH;
TTah historie[MAXPOCTAH];	/* 1.tah = [1] */

int main(int argc, char **argv)
{
	THra Hra;
	char c[10], fn[30], tah[5], nextchar;
	TMG mg;
	int i, XB = 1, comp = CERNYH, doba, IB, pt, vt;
    int tseconds2;
	TBook book;
	time_t seeed;

	setbuf(stdin, NULL);	/* bacha na to! muze to zpusobit problemy */
	/* udajne tam stejne bude jedno-char-ovej buffer, protoze
	   scanf nekdy potrebuje vracet jeden znak zpet na stdin */
	/* toz radsi budem jeste flushovat */
	setbuf(stdout, NULL);	/* kvuli XBOARD -> unbuffered stdout */
	printf("\n *** Sachy (simple chess program) *** (v%s)\n\n", VERSION);
#ifdef UNIX
	signal(SIGINT, SIG_IGN);
#endif
	time(&seeed);
	srand((unsigned int) seeed);
	HraInic(&Hra);
	//ReadCFG();
	if (openbook(&book))
		IB = 1;
	/* printbook(&book); */
	else
		IB = 0;
	do {
		/*      fflush(stdin); fflush(stdout); */
		if (JePat(&Hra)) {
			if (XB) printf("\007 Draw !!!\n");
			/*              KonecHry();
			   return 0; */
		} else if (JeMat(&Hra)) {
			if (XB) printf("\007 Checkmated !!!\n");
			/*              KonecHry();
			   return 0; */
		} else if (JeVSachu(Hra.natahu, &Hra))
			if (XB) printf(" check!\n");
		if (XB) printf("(%d)", (Hra.PHT) / 2 + 1);
		if (Hra.natahu == BILYH) {
            if (XB) printf(" white> ");
        } else
			if (XB) printf(" black> ");
		if (Hra.natahu == comp) {
			if (XB) printf(" ... thinking ...");
			if (IB) {
				pt = book.p[book.aktual].poctah;
				if (pt > 0) {
					vt = rand() % pt;
					strcpy(tah, book.p[book.aktual].tahy[vt]);
					book.aktual = book.p[book.aktual].kam[vt];
					doba = 0;
				} else
					IB = 0;
			}
			if (IB == 0)
				doba = NejlepsiTah(&Hra, tah, XB);
			if (doba >= 0) {
                Hra.tleft -= doba;
                if (((Hra.PHT+3)/2) == Hra.tmoves)
                    Hra.tleft += Hra.tseconds;
				ZpracujTah(tah, &Hra);
				if (XB) {
					TiskSach(Hra);
				    printf("time left: %d seconds\n", Hra.tleft);
                }
				printf("move %s\n", tah);
			} else
				comp = -1;
			continue;
		}
		scanf("%9s", &c);
		if (strcmp(c, "new") == 0) {
			HraInic(&Hra);
			comp = CERNYH;
			IB = 1;
			book.aktual = 0;
		} else if (strcmp(c, "random") == 0 ||
			   strcmp(c, "?") == 0)
			continue;
		else if (strcmp(c, "book") == 0)
			printbook(&book);
		else if (strcmp(c, "xboard") == 0) {
			XB = 0;
			printf("\n");
		} else if (strcmp(c, "draw") == 0)
            { if (XB) printf("Go on!\n"); }
		else if (strcmp(c, "white") == 0) {
			comp = CERNYH;
			Hra.natahu = BILYH;
		} else if (strcmp(c, "black") == 0) {
			comp = BILYH;
			Hra.natahu = CERNYH;
		} else if (strcmp(c, "force") == 0)
			comp = -1;
		else if (strcmp(c, "undo") == 0) {
			undo(&Hra);
			IB = 0;
		} else if (strcmp(c, "remove") == 0) {
			undo(&Hra);
			undo(&Hra);
			IB = 0;
		} else if (strcmp(c, "tisk") == 0)
			TiskSach(Hra);
		else if (strcmp(c, "test") == 0)
			printf("Benchmark: %d positions per second\n", benchmark(&Hra));
		else if (strcmp(c, "poz") == 0)
			TiskFig(Hra);
		else if (strcmp(c, "hod") == 0)
			printf("%d\n", Ohodnot(&Hra));
		else if (strcmp(c, "hist") == 0)
			TiskHist(Hra);
		else if (strcmp(c, "slist") == 0) {
			i = SMoveGen(&Hra, mg);
			TiskTahu(mg, i);
		} else if (strcmp(c, "list") == 0) {
			i = MoveGen(&Hra, mg, 0);
			TiskTahu(mg, i);
		} else if (strcmp(c, "hint") == 0) {
			doba = NejlepsiTah(&Hra, tah, XB);
			if (doba > 0)
				printf("Hint: %s\n", tah);
		} else if (strcmp(c, "go") == 0)
			comp = Hra.natahu;
		else if (strcmp(c, "ply") == 0) {
			scanf("%d", &i);
			if (i > 0)
				IQ = i;
		} else if (strcmp(c, "sply") == 0) {
			scanf("%d", &i);
			if (i <= 0)
				SIQ = i;
		} else if (strcmp(c, "open") == 0) {
			scanf("%29s", &fn);
			OpenFile(&Hra, fn);
			IB = 0;
		} else if (strcmp(c, "save") == 0) {
			scanf("%29s", &fn);
			SaveFile(&Hra, fn);
		} else if (strcmp(c, "quit") == 0) {
			KonecHry();
			break;
        } else if (strcmp(c, "level") == 0) {
            scanf("%d %d", &Hra.tmoves, &Hra.tseconds);
            Hra.tseconds *= 60;
            scanf("%c", &nextchar);
            if (nextchar == ':') {
                scanf("%d %d", &tseconds2, &Hra.tclockmode);
                Hra.tseconds += tseconds2;
            } else if (nextchar == ' ') {
                scanf("%d", &Hra.tclockmode);
            } else
                printf("Error parsing level command.");
            if (Hra.tclockmode != 0) {
                printf("Error: only conventional clock mode is supported\n");
            }
            Hra.tleft = Hra.tseconds;
		} else if (a1b1(c)) {
			if (PreJTT(c, &Hra) && JeToTah(c, &Hra, 1)) {
				ZpracujTah(c, &Hra);
				if (IB) {
					pt = book.p[book.aktual].poctah;
					i = 0;
					while (i < pt &&
					       strcmp(c, book.p[book.aktual].tahy[i]) != 0)
						i++;
					if (i < pt)
						book.aktual = book.p[book.aktual].kam[i];
					else
						IB = 0;
				}
				if (XB)
					TiskSach(Hra);
			} else
				printf("%s\n", c);
		} else
			printf("Error (unknown command): %s \n", c);
	}
	while (1);
	return 0;
}

void undo(THra * H)
{
	int i, pht;
	char t[5];

	pht = H->PHT;
	HraInic(H);
	for (i = 1; i < pht; i++) {
		Num2Not(historie[i].odkud, &(t[0]));
		Num2Not(historie[i].kam, &(t[2]));
		ZpracujTah(t, H);
	}
}
