// -*-c++-*-
/***************************************************************************
                          SanNotation.h  -  description
                             -------------------
    begin                : Sat Sep 1 2001
    copyright            : (C) 2001 by Sven Reichard
    email                : reichard@math.udel.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef SANNOTATION_H
#define SANNOTATION_H


# include <iostream>
# include <string>
# include <SmartPointer.h>
# include <Moves/Move.h>
//! ALiCE: A Little Chess Engine
namespace Alice
{
  class Move;
  class Game;
  /**I represent the short algebraic notation of a move, the de-facto
     standard in Computer Chess. Each move is described by the
     initial letter of the moving piece (N for kNight) and its
     destination square. E.g., Nf3, Bb5, Qc8. The initial is
     omitted for pawns.
     
     If the move is a capture, an 'x' is put between the piece
     and square, e.g., Nxd5. Pawn captures are indicated by
     the source file, e.g., exd5.
     
     Special moves: Promotions are indicated by '=' followed
     by the initial of the resulting piece: e8=N. Castling is
     denoted by 'O-O' (short) and 'O-O-O' (long). En passant
     captures are written like usual pawn captures, i.e., 
     e4 dxe3.
     
     If the above does not result in a unique pseudolegal move,
     the following things are tried:
     If fixing the source file makes the move unique, it is added
     after the piece letter, like in Ndxe5. Otherwise the same
     is tried with the rank, R8e6. If all else fails, the complete
     source square is given, Qd8xf6 (you would have to have 
     three queens of one color on the board for this to happen.
     
     In addition to this information to determine the move, a 
     checking move gets a '+'  appended, and a mating move, 
     a '#'. Thus, a move can be as short as "e4", or as long as
     "exd8=R+".
     
     
     *@author Sven Reichard
     */
  class SanNotation {
  public: 
    SanNotation(SmartPointer<Move> m, Game& g);
    SanNotation(std::string str, Game& g);
    ~SanNotation();
    void printOn(std::ostream& out);
    void setPromotion(char c);
    void setCastling(bool isLong);
    std::string getString() ;
    SmartPointer<Move> getMove() const;
    void setFile();
    void setRank();
    bool hasSourceFile() const
    {
      return _hasSourceFile;
    };
    bool hasSourceRank() const
    {
      return _hasSourceRank;
    };
    int getSourceFile() const;
    int getSourceRank() const;
    bool fitsDescription(const Move& move) const;
    bool isValid() const;
  private:
    void calculateFlags();
    void findMove();
    SmartPointer<Move> _move;
    std::string _string;
    Game& game;
    bool _hasSourceFile;
    bool _hasSourceRank;
    bool promotion;
    char promotionChar;
    bool isCastling;
    bool isLongCastling;
    bool _isValid;
    bool flagsCalculated;
    bool isCheck;
    bool isMate;
    std::string displayLetter;
  };
  
  inline
  std::ostream& operator<< (std::ostream& out, SanNotation& san)
  {
    san.printOn(out);
    return out;
  };
};// namespace Alice

#endif
