/* GNU Chess 5.0 - main.c - entry point
   Copyright (c) 1999-2002 Free Software Foundation, Inc.

   GNU Chess is based on the two research programs 
   Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.

   GNU Chess 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.

   GNU Chess 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 GNU Chess; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Contact Info: 
   bug-gnu-chess@gnu.org
   cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
*/

#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>                                                              
#include <unistd.h>

#include "util.h"
#include "eval.h"
#include "book.h"
#include "movelist.h"
#include "option.h"
#include "log.h"
#include "ttable.h"
#include "ptable.h"
#include "square.h"
#include "protocol.h"
#include "init.h"
#include "cmd.h"
#include "mainloop.h"
#include "version.h"
#include "config.h"
#include "ini.h"
#include "uci.h"
#include "input.h"


int main (int argc, char *argv[]){

    /*
     * Parse command line arguments conforming with getopt_long syntax
     * This used to be handled by getopt but this is a nuissance for mingw.
     */
 
    char *cmd;

    int opt_help = 0, 
	opt_version = 0, 
	opt_post = 0, 
	opt_xboard = 0, 
	opt_easy = 0, 
	opt_manual = 0;

    unsigned long opt_hash = 0; 

    
    char *opt_config = NULL;

    char *endptr;


    int i;
    char* arg=NULL;
    char* opt=NULL;

    for(i=1;i<argc;i++){
	arg=argv[i];
	if(!strcmp(arg,"--hashsize") || !strcmp(arg,"-s")){
	    opt=argv[++i];
	    if(!opt){
		opt_help=1;
	    }else{
		errno = 0; 
		opt_hash = strtol (opt, &endptr, 10);
		if ( errno != 0 || *endptr != '\0' || opt_hash>=67108864 ){
		    printf("%s\n","Hashsize out of Range or Invalid\n");
		    return(1);
		}
	    }
	}else if(!strcmp(arg,"--config") || !strcmp(arg,"-c")){
	    opt=argv[++i];
	    if(!opt){
		opt_help=1;
	    }else{
		opt_config = strdup (opt);
	    }
	    
	}else if(!strcmp(arg,"--version") || !strcmp(arg,"-v")){
	    opt_version=1;
	}else if(!strcmp(arg,"--help") || !strcmp(arg,"-h")){
	    opt_help=1;
	}else if(!strcmp(arg,"xboard") || 
		 !strcmp(arg,"--xboard") || 
		 !strcmp(arg,"-x")){
	    opt_xboard=1;
	}else if(!strcmp(arg,"post") ||
		 !strcmp(arg,"--post") ||
		 !strcmp(arg,"-p")){
	    opt_post=1;
	}else if(!strcmp(arg,"--easy") || !strcmp(arg,"-e")){
	    opt_easy=1;
	}else if(!strcmp(arg,"--manual") || !strcmp(arg,"-m")){
	    opt_manual=1;
	}else{
	    opt_help=1;
	}
    }

    /* If a usage statement is required output it here */
    if (opt_help == 1){
	// Sadly due to locking "Output" does not work before initialize.... 
	// So we stupidly copy paste cmd_usage().
	// TODO: fix this.
	printf (
     "\n"
     " Usage: %s [OPTION]\n"
     "\n"
     " -h, --help                 display this help and exit\n"
     " -v, --version              display version information and exit\n" 
     "\n"
     " -x, --xboard               start up in xboard mode\n"
     " -p, --post                 show thinking\n"
     " -e, --easy                 disable thinking in opponents time\n"
     " -m, --manual               enable manual mode\n"
     " -s size, --hashsize=size   specify hashtable size in slots\n"
     " -c file, --config=file     load settings from file\n"
     "\n"
     " Options xboard and post are accepted without leading dashes\n"
     " for backward compatibility\n"
     "\n"
     "Report bugs to <bug-gnu-chess@gnu.org>.\n"
     "\n", argv[0]);
	
	return (1); /* Maybe an error if due to bad arguments. */
    
    }




    /* If the version option was specified we can exit here */
    if (opt_version == 1){
	printf("%s %s\n", PROGRAM, VERSION);
	return(0);
    }


    /* Ok let's go */
    Initialize (opt_xboard?0:1);
    
    Protocol->progname = argv[0]; /* Save in global for cmd_usage */


    
    if (opt_post == 1){
	SET (Protocol->state_flags, POST);	
    }
    if (opt_manual ==1){
	SET (Protocol->state_flags, MANUAL);
    }
    if(Protocol->console){
	cmd_version();
    }

    if (opt_config){
	ini_entry_t *ini_entry;
	option_t *opt;
	ini_t ini[1];
	gnuchess_set_option("SaveSettingsFile",opt_config);
	IniInit(ini);
	if(IniParse(ini,opt_config)){
	    OutputConsole("Loading settings from \"%s\"\n",opt_config);
	    IniStartIter(ini);
	    while((ini_entry=IniNext(ini))){
		opt=OptionFind(Option,ini_entry->name);
		if(opt && !IS_BUTTON(opt->type)){
		    gnuchess_set_option(ini_entry->name,ini_entry->value);
		}
		
	    }
	}else{
	    OutputConsole("Unable to parse settings file \"%s\"\n",opt_config);
	}
    }
    
    
    if ( opt_hash != 0){
	TTableSetSize(TTable,opt_hash);
    }

    if ( opt_easy == 0){
	SET (Protocol->state_flags, HARD);
    }
    
    InputWait();
    cmd=InputLook();

    if(cmd && !strcmp(cmd,"uci")){
	UciMainLoop();
    }else{
	MainLoop();
    }

    return (0);
}
