#include <clib/alib_protos.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "common.h"

#define EPDCLOSE 1

short ReadEPDFile(const char *file,short op)
{
static FILE *fp=0;
char line[255];
if(!fp)
	{
	if(!(fp=fopen(file,"r")))
		{
		sprintf(line,"Error opening file %s",file);
		DoMethod(mui_app,MUIM_Chess_ShowThinking,line);
		return false;
		}
	}
if(op==EPDCLOSE)   
	{ 
	fclose(fp);
	fp=0;
	return false;
	}
fgets(line,255,fp);
if(!feof(fp)) 
	{
	ParseEPD(line);
//	if(op!=2) printf("\n%s : Best move=%s\n",id,solution);
	return true;
	}
fclose(fp);
fp=0;
return false;
}

void ParseEPD(char *p)
{
short r,c,sq;
char s[8];
r=56;
c=0;
memset(&board,0,sizeof(board));
while(*p!=' ')
	{
	sq=r+c;
	switch(*p)
		{
		case 'P':
			SETBIT(board.b[white][pawn],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[white]+=ValueP;
			break;	
		case 'N' :
			SETBIT(board.b[white][knight],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[white]+=ValueN;
			break;	
		case 'B':
			SETBIT(board.b[white][bishop],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[white]+=ValueB;
			break;
		case 'R':SETBIT(board.b[white][rook],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[white]+=ValueR;
			break;	
		case 'Q' :
			SETBIT(board.b[white][queen],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[white]+=ValueQ;
			break;	
		case 'K':
			SETBIT(board.b[white][king],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			break;	
		case 'p':
			SETBIT(board.b[black][pawn],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[black]+=ValueP;
			break;	
		case 'n':
			SETBIT(board.b[black][knight],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[black]+=ValueN;
			break;	
		case 'b':
			SETBIT(board.b[black][bishop],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[black]+=ValueB;
			break;	
		case 'r':
			SETBIT(board.b[black][rook],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[black]+=ValueR;
			break;	
		case 'q':
			SETBIT(board.b[black][queen],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			board.material[black]+=ValueQ;
			break;	
		case 'k':
			SETBIT(board.b[black][king],sq);
			SETBIT(board.blockerr90,r90[sq]);
			SETBIT(board.blockerr45,r45[sq]);
			SETBIT(board.blockerr315,r315[sq]);
			break;	
		case '/':
			r-=8;
			c=-1;
		}
	if(isdigit(*p)) c+=(*p-'0');
	else c++;
	p++;
	}
board.pmaterial[white]=board.material[white]-nbits(board.b[white][pawn])*ValueP;
board.pmaterial[black]=board.material[black]-nbits(board.b[black][pawn])*ValueP;
board.king[white]=leadz(board.b[white][king]);
board.king[black]=leadz(board.b[black][king]);
UpdateFriends(); 
UpdateCBoard();
UpdateMvboard();
sscanf(p," %s %[^\n]",s,p);
if(s[0]=='w') board.side=white;
else if(s[0]=='b') board.side=black;
sscanf(p," %s %[^\n]",s,p);
if(strchr(s,'K')) board.flag|=WKINGCASTLE;
if(strchr(s,'Q')) board.flag|=WQUEENCASTLE;
if(strchr(s,'k')) board.flag|=BKINGCASTLE;
if(strchr(s,'q')) board.flag|=BQUEENCASTLE;
sscanf(p," %s %[^\n]",s,p);
if(s[0]!='-') board.ep =(s[0]-'a')+(s[1]-'1')*8;
else board.ep=-1;
if(!strncmp(p,"bm",2)) sscanf(p,"%*s %[^;]; %[^\n]",solution,p); 
if(!strncmp(p,"id",2)) sscanf(p,"%*s %[^;]; %[^\n]",id,p); 
CalcHashKey();
phase=PHASE;
}

void LoadEPD(char *p)
{
char file[32];
short N=1;
sscanf(p,"%s %hd ",file,&N);
if(strcmp(file,"next")==0) ReadEPDFile(file,0);
else
	{ 
	ReadEPDFile(file,1);
	while(--N)
		{
		if(ReadEPDFile(file,2)==false)
			{
			DoMethod(mui_app,MUIM_Chess_ShowThinking,"File position exceeded.");
			return; 
			}
		}
	ReadEPDFile(file,0);
	}
DoMethod(mui_app,MUIM_Chess_ShowBoard);
NewPosition();
}

void SaveEPD(char *file)
{
FILE *fp;
short r,c,sq,k;
char c1;
if(fp=fopen(file,"a"))
	{
	for(r=A8;r>=A1;r-=8)
		{
		k=0;
		for(c=0;c<8;c++)
			{
			sq=r+c;
			if(cboard[sq]==empty) k++;
			else
				{
				if(k) fprintf(fp,"%1d",k);
				k=0;
				c1=notation[cboard[sq]];
				if(BitPosArray[sq] & board.friends[black])
				c1=tolower(c1);
				fprintf(fp,"%c",c1);
				}
			}
		if(k) fprintf(fp,"%1d",k);
		if(r>A1) fprintf(fp,"/");
		}
	fprintf(fp,(board.side==white?" w ":" b "));
	if(board.flag & WKINGCASTLE) fprintf(fp,"K");
	if(board.flag & WQUEENCASTLE) fprintf(fp,"Q");
	if(board.flag & BKINGCASTLE) fprintf(fp,"k");
	if(board.flag & BQUEENCASTLE) fprintf(fp,"q");
	if(!(board.flag&(WCASTLE|BCASTLE))) fprintf(fp,"-");
	fprintf(fp," %s",(board.ep>-1?algbr[board.ep]:"-"));
	fprintf(fp," bm 1; id 1;");
	fprintf(fp,"\n");
	fclose(fp);
	}
else DoMethod(mui_app,MUIM_Chess_ShowThinking,"Can't save file.");
}
