// Copyright 1994 by Jon Dart.  All Rights Reserved

#include "stdafx.h"
#include "move.h"
#include <iostream.h>
#include <iomanip.h>
extern "C"
{
#include <ctype.h>
#include <string.h>
};

static char FileImage( const Square sq )
{
    return 'a' + sq.File() - 1;
}

static char RankImage( const Square sq )
{
    return '1' + sq.Rank(White) - 1;
}

#ifdef _TRACE
const char * Move::Image() const
{
    static char image[8];
    if (IsNull())
    {
       strcpy(image,"(null)");
       return image;
    }
    image[0] = FileImage(StartSquare());
    image[1] = RankImage(StartSquare());
    image[2] = '-';
    image[3] = FileImage(DestSquare());
    image[4] = RankImage(DestSquare());
    int i = 5;
    if (my_promotion != Piece::Empty && my_promotion != Piece::Invalid)
    {
       image[i++] = '=';
       image[i++] = Piece::Image((Piece::PieceType)my_promotion);
    }
    image[i] = '\0';
    return image;
}
#endif

Move &Move::NullMove()
{
    static Move m;
    return m;
}

Move Move::Value( char *str, const ColorType color )
{
    char *p = str;
    Square source, dest;

    if (strcmp(str,"O-O")==0)
    {
       if (color == White)
          return Move(60,62);
       else
          return Move(4,6);
    }
    else if (strcmp(str,"O-O-O")==0)
    {
       if (color == White)
          return Move(60,58);
       else
          return Move(4,2);
    }

    while (isspace(*p)) p++;
    source = Square::Value(p);
    p += 2;
    if (*p == '-' || *p == 'x') p++;
    dest = Square::Value(p);
    if ((source == -1) || (dest == -1))
       return NullMove();
    else
    {
       p += 2;
       Piece::PieceType promotion = Piece::Invalid;
       if (*p == '=')
       {
          // promotion
	  p++;
	  promotion = Piece::CharValue(*p);
	  // check for promotion to valid piece:
	  switch (promotion)
	  {
	    case Piece::Empty:
	    case Piece::Pawn:
	       return Move::NullMove();
	    case Piece::Knight:
	    case Piece::Bishop:
	    case Piece::Rook:
	    case Piece::Queen:
	       break;
	    case Piece::King:
	    case Piece::Invalid:
	       return Move::NullMove();
	  }
       }
       Move m(source,dest,promotion);
       return m;
    }
}

#ifdef _TRACE
ostream & operator << (ostream &o, Move &move)
{
	o << move.Image();
	return o;
}
#endif
