/* ht2sgf, very minimal converter from HandTalk format to SGF format.
 * usage: ht2sgf [-v] file.ght file.sgf
 * The -v option adds some extra comments.

 * Copyright 1997-1998 Jean-loup Gailly <jloup@gzip.org>
 *   This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the author be held liable for any damages
 * arising from the use of this software.
 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely.
 *
 * Modification history:
 * 98/06/24 support non handicap games (Dan Stromberg & Jean-loup Gailly)
 * 98/06/11 output HA[num_handicap_stones] (Dan Stromberg)
 */
#include <stdio.h>

#define HEADER_SIZE    56L

#define HANDICAP_STONE 0x28
#define WHITE_MOVE     0x10
#define BLACK_MOVE     0x20
#define CAPTURE        0x90
#define CAPTURE2       0xa0

int main(int argc, char **argv)
{
  int  code;          /* HandTalk code for the move (black, white, etc...) */
  int  move;          /* HandTalk move (01 = aa, etc...) */
  char line;          /* SGF line code (a to s) */
  char column;        /* SGF column code (a to s) */
  int  verbose = 0;   /* true with -v argument to add more comments */
  int  my_column = 0;
  FILE *infile, *outfile;
  int  num_handicap_stones = 0;

  if (argc < 3) {
    fprintf(stderr, "usage: ht2sgf file.ght file.sgf\n");
    exit(1);
  }
  verbose = !strcmp(argv[1], "-v");

  infile = fopen(argv[argc-2], "rb");
  if (infile == NULL) {
    perror(argv[argc-2]);
    exit(1);
  }
  outfile = fopen(argv[argc-1], "w");
  if (infile == NULL) {
    perror(argv[argc-1]);
    exit(1);
  }
  if (fseek(infile, HEADER_SIZE, SEEK_SET) < 0) {
    perror(argv[argc-2]);
    exit(1);
  }
  fprintf(outfile, "(;GM[1]FF[1]SZ[19]\n"); /* standard SGF header */

  for (;;) {
    move = getc(infile);
    code = getc(infile);
    if (code == EOF) break;

    if (code & 1) {  /* move numbers above 256 use bottom bit of the code */
      move += 256;
      code &= ~1;
    }
    column = 'a' + move / 20;
    line = 'a' - 1 + move % 20;
    if (move == 0) {
      line = column = 't'; /* pass */
    }
    switch (code) {
    case HANDICAP_STONE:
      fprintf(outfile, "AB[%c%c]", line, column);
      my_column += 6;
      num_handicap_stones++;
      break;
    case BLACK_MOVE:
      fprintf(outfile, "B[%c%c];", line, column);
      my_column += 6;
      break;
    case WHITE_MOVE:
      fprintf(outfile, "W[%c%c];", line, column);
      my_column += 6;
      break;
    case CAPTURE:
      if (verbose) {
	fprintf(outfile, "\nC[capture at %c%c]", line, column);
	my_column = 16;
      }
      break;
    case CAPTURE2:
      if (verbose) {
	fprintf(outfile, "\nC[capture2 at %c%c]", line, column);
	my_column = 17;
      }
      break;
    default:
      fprintf(outfile, "\nC[unknown code %d 0x%02x, pos %c%c]",
	      code, code, line, column);
      my_column = 31;
    }
    if (my_column > 72) {
      fprintf(outfile, "\n");
      my_column = 0;
    }
  }
  if (num_handicap_stones > 0) {
    fprintf(outfile,"HA[%d]", num_handicap_stones);
  }
  fprintf(outfile, ")\n");
  fclose(infile);
  return 0;
}
