// Copyright 1994 by Jon Dart.  All Rights Reserved.

#include "stdafx.h"
#include "emove.h"
#include "util.h"
extern "C"
{
#include <string.h>
};

ExtendedMove::ExtendedMove() 
{
}

void ExtendedMove::set_special(const Board &ABoard)
{
    // set special field
    my_special = Normal;
    switch (my_piecemoved.Type())
    {
    case Piece::Pawn:
       if (my_dest.Rank(ABoard.Side()) == 8)
       {
          my_special = Promotion;
	  //my_promotion = Piece(Piece::Queen,ABoard.Side()); // for now
       }
       else if (ABoard[my_dest].IsEmpty())
       {
          if (my_dest.File() != my_start.File())
	  {
	     my_special = (byte)EnPassant;
	     my_capture = Piece(Piece::Pawn,ABoard.OppositeSide());
	  }
       }
       break;
    case Piece::King:
       if (Util::Abs((int)my_start - (int)my_dest) == 2)
       {
          if (my_start > my_dest)
	     my_special = QCastle;
          else
	     my_special = KCastle;
       }
       break;
    default:
       break;
    }
}

ExtendedMove::ExtendedMove( const Board &ABoard, const Square start, 
  const Square dest, const Piece::PieceType promotion )
: Move(start,dest,promotion)
{
     if (start == Square::InvalidSquare)
	my_piecemoved = Piece::InvalidPiece();
     else
	my_piecemoved = ABoard[start];
     if (dest == Square::InvalidSquare)
	my_capture = Piece::InvalidPiece();
     else
	my_capture = ABoard[dest];
     set_special(ABoard);
}

ExtendedMove::ExtendedMove( const Board &ABoard, const Move &move )
: Move(move.StartSquare(), move.DestSquare(), move.PromoteTo())
{
     if (move.StartSquare() == Square::InvalidSquare)
	my_piecemoved = Piece::InvalidPiece();
     else
	my_piecemoved = ABoard[move.StartSquare()];
     if (move.DestSquare() == Square::InvalidSquare)
	my_capture = Piece::InvalidPiece();
     else
	my_capture = ABoard[move.DestSquare()];
     set_special(ABoard);
}

const int ExtendedMove::operator == (const ExtendedMove &m) const
{
   return (Move::operator == (m)) &&
          (my_special == m.my_special) &&
	  (my_piecemoved == m.my_piecemoved) &&
	  (my_capture == m.my_capture);
}
		
const ExtendedMove::SpecialType ExtendedMove::Special() const
{
    return (SpecialType)my_special;
}

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

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

const char * ExtendedMove::Image() const
{
    static char image[10];
    static char null_image[] = "(null)";
    if (IsNull())
       return null_image; //Move::Image();
    if (Special() == KCastle)
    {
          strcpy(image,"o-o");
	  return image;
    }
    else if (Special() == QCastle)
    {
	  strcpy(image,"o-o-o");
	  return image;
    }
    image[0] = FileImage(StartSquare());
    image[1] = RankImage(StartSquare());
    if (Capture().IsEmpty())
       image[2] = '-';
    else
       image[2] = 'x';
    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;
}

