/* Pepito v1.59  -- file: command.c --
   Copyright (c) 2000-01 Carlos del Cacho

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Contact the author: guggenjaimito@yahoo.com
*/

#ifndef UNIQUE_SOURCE_FILE
#  include "datos.h"
#endif

#include "command.h"
#include "xboard.h"
#include "uci.h"
#include "book.h"

#define DEF_CMND_CNT  20

command_t default_table[] = {

        { "analyze",  WB_Analyze  },
        { "xboard",   WB_Xboard   },
        { "uci",      UCI_Uci     },
        { "quit",     WB_Quit     },
        { "undo",     WB_Undo     },
        { "setboard", WB_SetBoard },
        { "tab",      Def_Tab  },
        { "egtbload", Def_EGTBLoad},
        { "quies",    Def_Quies   },
        { "debugpv",  Def_DebugPV },
        { "badmin",   BK_Badmin   },
        { "perf",     Def_Perf    },
        { "perft",    Def_Perft   },
        { "epd",      Def_EPD     },
        { "eval",     Def_Eval    },
        { "loadfen",  Def_LoadFen },
        { "help",     Def_Help    },
        { "san",      Def_San     },
        { "hash",     Def_Hash    },
        { "dprune",   Def_DPrune  }
};

command_group_t default_commands = {

    DEF_CMND_CNT,
    default_table
};


command_group_t *command_table = &default_commands;

//---------------------------------------------------------------------------------*/
int  ParseCommandLine(char *line)
{
    int argc = CountIArgs();
    int i;

    for (i=0; i < command_table->ncommands; i++)
        if (!strcmp(command_table->cmnd[i].str, line))
        {
            command_table->cmnd[i].exec(argc);
            return 1;
        }

    return 0;
}
//---------------------------------------------------------------------------------*/
int NoOperation(int argc)
{
    GetRestofInput(entrada);
    return 0;
}
//---------------------------------------------------------------------------------*/
int Def_Hash(int argc)
{
    printf("%I64X\n",HashGlob);
	return 1;
}
//---------------------------------------------------------------------------------*/
int Def_LoadFen(int argc)
{
    FILE           *fp;
    int             i;
    char            arg[256];

    if (argc != 3) {
         Print("Numero incorrecto de argumentos\n");
         return 1;
    }

    ReadString(arg);
    if (!(fp = fopen(arg, "r"))) {
       fprintf(stderr, "No pude abrir fichero\n");
       return 1;
    }
    ReadString(arg);
    i = atoi(arg);

    while (i) {
        LeeLinea(&fp, arg, 256);
        i--;
    }
    fclose(fp);
    LeeEPD(arg, NULL);
    xb_info.force = 1;
    xb_info.my_clock = xb_info.opp_clock = xb_info.base;

    for (i = 0; i < 4096; i++)
    {
       tab.history[i][0] = 0;
       tab.history[i][1] = 0;
    }

    memset(tab.trans_tab_p, 0, PAWN_HASH_SIZE * sizeof(entrada_hash_p));
    memset(tab.trans_tab, 0, HASH_SIZE * sizeof(entrada_hash));
    memset(tab.eval_cache, 0, CACHE_SIZE * sizeof(ecache));
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Tab(int argc)    
{
    PintaTablero();
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_EGTBLoad(int argc)    
{
    InitTB();
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Quies(int argc)    
{
   char arg[256];

   if (argc != 3)
      Print("Need a search window\n");
   else
   {
      int alpha, beta, i;

      tab.book_retry = 0;
      ClearTables(0);
      GeneraValidas(0);

      MaxPos[0] = Max(PEON_VAL, MaxPos[0]>>1);
      MaxPos[1] = Max(PEON_VAL, MaxPos[1]>>1);
      pv_long[0] = 0;

      PreProcesa();
      tab.jaque[1] = Jaque(Turno);
      ReadString(arg);
      alpha = atoi(arg);
      ReadString(arg);
      beta = atoi(arg);
      Print("Resultado Quiesce(%d,%d) = %d\nPV: ",alpha,beta,Quiesce(alpha,beta, UNIT_PROF,1));
      for (i=1;i<pv_long[1];i++)
         PintaJugada(&pv[1][i], Print);
      Print("\n");
   }

   return 1;
}
//---------------------------------------------------------------------------------*/
int Def_DebugPV(int argc)    
{
    int             i;
    entero32        jug;
    char            arg[256];

    for (i = 0; i < (argc - 1); i++) {
       ReadString(arg);
       if (!LeeJugada(arg, &jug)) {
           Print("Invalid PV! Move %s not recongnized as legal.\n", arg);
           while (i) {
               CambiaTurno();
               DesMueve();
               i--;
           }
           return 1;
       }
       pvdebug[i].jug = jug;
       pvdebug[i].pieza_mov = Tablero[jug & 0x3f];
       Mueve(jug);
       CambiaTurno();
       debughash[i] = HashGlob;
    }

    while (i) {
        CambiaTurno();
        DesMueve();
        i--;
    }
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Perf(int argc)
{
   Perf();
   return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Perft(int argc)
{
   int ply;
   char arg[256];

   ReadString(arg);
   ply = atoi(arg);
   RunTestGen(ply,0);
   return 1;
}
//---------------------------------------------------------------------------------*/
int Def_EPD(int argc)
{
    FILE           *pachi;
    char            arg[256];

    Print("Introduzca fichero a cargar: \n> ");
    ReadString(arg);
    pachi = fopen(arg, "r");
    if (pachi == NULL)
        Print("No se encontro archivo %s\n", arg);
    else
        TestEPD(&pachi);
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Eval(int argc)
{
    GeneraValidas(1);
    EvalTest(0);
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_DPrune(int argc)
{
   int beta;
   char arg[256];

   ReadString(arg);
   beta = atoi(arg);
   RTurno = 1;
   PreProcesa();
   ClearTables(0);
   printf("beta: %d\n",beta);
   tab.max_stack[0] = JugStack;
   DealPrune(beta,1);
   return 1;
}
//---------------------------------------------------------------------------------*/
int Def_Help(int argc)
{
    Print("\nanalyze\t\t\tSearches with infinite time current position\n");
    Print("badmin\t\t\tSwitches to book administration mode\n");
    Print("egtbload\t\tLoads the endgame tablebases\n");
    Print("epd\t\t\tRun EPD Testsuite in batch\n");
    Print("eval\t\t\tPrint static evaluation for current position\n");
    Print("loadfen\t\t\tLoads FEN position from file\n");
    Print("perf\t\t\tRun move generator performance test\n");
    Print("perft\t\t\tCalculates legal moves up to a certain depth\n");
    Print("quies\t\t\tReturns the result and PV from a call to Quiesce\n");
    Print("quit\t\t\tQuits the program\n");
    Print("setboard\t\tLoads a FEN string\n");
    Print("tab\t\t\tDisplays board\n");
    Print("uci\t\t\tInitializes uci protocol mode\n");
    Print("undo\t\t\tTakes back one half move\n");
    Print("xboard\t\t\tInitializes xboard protocol mode\n\n");
    return 1;
}
//---------------------------------------------------------------------------------*/
int Def_San(int argc)
{
    char            arg[256];
    int jug;

    ReadString(arg);
    if (LeeJugada(arg, &jug))
    {
       Print("Tu jugada en notacion algebraica: ");
       ImprimeJugada(jug,arg);
       Print("%s\n",arg);
    }
    return 1;
}
