#include "CommandLine.h"

#include <stdlib.h>
#include <stdio.h>
/*
#include <Windows.h>
*/

#include "protocol.h"

#include "YBWCManager.h"

CommandLine* CommandLine_Construct(CommandLine* pThis, int* pargc, char*** pargv)
{
  int i;

  pThis->pargc          = pargc;
  pThis->pargv          = pargv;

  pThis->nPosition      = arg_intn("p",  "position", NULL, 0,    8,  "takes a test position (range 1..33)   (defaults to 1)");
  pThis->nDepth         = arg_intn("d",  "depth",    NULL, 0,    8,  "takes an optional depth value         (defaults to 8)");
  pThis->nMoveTime      = arg_intn("m",  "movetime", NULL, 0,    8,  "takes an optional movetime value [ms] (no default)");
  pThis->help           = arg_lit0(NULL, "help",                     "print this help and exit");
  pThis->version        = arg_lit0(NULL, "version",                  "print version information and exit");
  pThis->end            = arg_end(20);

//pThis->argtable       = {pos, d, help, version, end};

// kh 28.07.06 defensive
  for(i = 0; i < ARGTABLE_SIZE; i++)
  {
    pThis->argtable[i] = NULL;
  }

  i                     = 0;
  pThis->argtable[i++]  = pThis->nPosition;
  pThis->argtable[i++]  = pThis->nDepth;
  pThis->argtable[i++]  = pThis->nMoveTime;
  pThis->argtable[i++]  = pThis->help;
  pThis->argtable[i++]  = pThis->version;
  pThis->argtable[i++]  = pThis->end;

  pThis->progname       = PROGRAM_NAME;

  pThis->nExitCode      = 0;

  pThis->bExitRequest   = FALSE;

  return pThis;
}

void CommandLine_Destruct(CommandLine* pThis)
{
  if(pThis)
  {

/* deallocate each non-null entry in argtable[] */
    arg_freetable(pThis->argtable, sizeof(pThis->argtable) / sizeof(pThis->argtable[0]));

    free(pThis);
  }
}

BOOL CommandLine_Parse(CommandLine* pThis)
{
  BOOL  bResult = FALSE;

  int   nErrors;
  int   i;

  /* verify the argtable[] entries were allocated sucessfully */
  if(arg_nullcheck(pThis->argtable) != 0)
  {
    /* NULL entries were detected, some allocations must have failed */
    YBWCManager_Printf(YBWCManager_Instance(), "ERROR %s: insufficient memory\n", pThis->progname);
    pThis->nExitCode = 1;
  }
  else
  {

  /* set foo default values to 1 */
    for(i = 0; i < pThis->nPosition->hdr.maxcount; i++)
    {
      pThis->nPosition->ival[i] = 1;
    }
  }

  /* allow depth to have optional values */
  /* and set depth default values to 8 */
  pThis->nDepth->hdr.flag |= ARG_HASOPTVALUE;
  for(i = 0; i < pThis->nDepth->hdr.maxcount; i++)
  {
    pThis->nDepth->ival[i] = 8;
  }

  /* allow movetime to have optional values */
  /* but set movetime default values to -1 */
  pThis->nMoveTime->hdr.flag |= ARG_HASOPTVALUE;
  for(i = 0; i < pThis->nMoveTime->hdr.maxcount; i++)
  {
    pThis->nMoveTime->ival[i] = -1; // kh 12.12.06 no default, used only when specified in the command line
  }

  /* Parse the command line as defined by argtable[] */
  nErrors = arg_parse(*pThis->pargc, *pThis->pargv, pThis->argtable);

  /* special case: '--help' takes precedence over error reporting */
  if(pThis->help->count > 0)
  {
    printf("Usage: %s", pThis->progname);
    arg_print_syntax(stdout, pThis->argtable, "\n");

    arg_print_glossary(stdout, pThis->argtable,"  %-25s %s\n");

// kh 21.09.06
    fflush(stdout);

    pThis->bExitRequest = TRUE; 
    pThis->nExitCode    = 0;
  }
  else if(pThis->version->count > 0)
  /* special case: '--version' takes precedence error reporting */
  {
    printf("'%s' " PROGRAM_VERSION " " PROGRAM_DETAILS ".\n", pThis->progname);
    printf("March 2008\n");

// kh 21.09.06
    fflush(stdout);

    pThis->bExitRequest = TRUE; 
    pThis->nExitCode    = 0;
  }
  else if(nErrors > 0)
  {

  /* If the parser returned any errors then display them and exit */
  /* Display the error details contained in the arg_end struct.*/

    arg_print_errors(stdout, pThis->end, pThis->progname);
    printf("Try '%s --help' for more information.\n", pThis->progname);

// kh 21.09.06
    fflush(stdout);

    pThis->bExitRequest = TRUE; 
    pThis->nExitCode    = 1;
  }
  else if((*pThis->pargc == 1) && FALSE) // kh 28.07.06 "no arguments" is allowed
  {

  /* special case: uname with no command line options induces brief help */
    printf("Try '%s --help' for more information.\n", pThis->progname);

// kh 21.09.06
    fflush(stdout);

    pThis->bExitRequest = TRUE; 
    pThis->nExitCode    = 0;
  }
  else
  {

  }

  bResult = (pThis->nExitCode == 0);

  return bResult;
}

void CommandLine_Dump(CommandLine* pThis)
{
  int i;

  YBWCManager_Printf(YBWCManager_Instance(), "Command line arguments:\n");

  /* command line arguments are successfully parsed at this point. */
  /* print what we have parsed */
  YBWCManager_Printf(YBWCManager_Instance(), "%d instances of --position detected on command line\n", pThis->nPosition->count);
  for(i = 0; i < pThis->nPosition->hdr.maxcount; i++)
  {
    YBWCManager_Printf(YBWCManager_Instance(), "position[%d] = %d\n", i, pThis->nPosition->ival[i]);         
  }

  YBWCManager_Printf(YBWCManager_Instance(), "%d instances of --depth detected on command line\n", pThis->nDepth->count);
  for(i = 0; i < pThis->nDepth->hdr.maxcount; i++)
  {
      YBWCManager_Printf(YBWCManager_Instance(), "depth[%d] = %d\n", i, pThis->nDepth->ival[i]);         
  }

  YBWCManager_Printf(YBWCManager_Instance(), "%d instances of --movetime detected on command line\n", pThis->nMoveTime->count);
  for(i = 0; i < pThis->nMoveTime->hdr.maxcount; i++)
  {
      YBWCManager_Printf(YBWCManager_Instance(), "movetime[%d] = %d\n", i, pThis->nMoveTime->ival[i]);         
  }

  YBWCManager_Printf(YBWCManager_Instance(), " \n");
}
