// -*-c++-*-
/***************************************************************************
                          Square.h  -  description
                             -------------------
    begin                : Tue May 22 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 Square_h
# define Square_h
# include <iostream>
# include <vector>
# include <BasicBoard.h>
namespace Alice
{
  class Direction;
  /** This class represents a square on the chess board. It is used
   *  for addressing purposes.
   */
  class Square
  {
    static const char rankMask = 0x07;
  public:
    static const char fileShift = 3;
    static const int maximalNumber = 64;
    Square(){};
    Square(char number);
  private:
    static Square at(signed char rank, signed char file){ return Square(rank, file);};
  public:
    static Square invalid() { return at(8,8);}
    signed char rank() const{ return mNumber & rankMask;}
    signed char file() const {return mNumber>>fileShift;}
    char number() const {return mNumber;}
    char flippedNumber() const;
    char getDownDiagonalNumber() const;
    char getUpDiagonalNumber() const;
    char getNumberRotated45() const;
    char getNumberRotated135() const;
    Square left() const;
    Square right() const;
    Square up() const;
    Square down() const;
    const Direction& directionTo(const Square& sq) const;
    bool isValid() const;
    void printOn(std::ostream& out) const;
    bool operator ==(const Square& sq) const {return mNumber == sq.mNumber;}
    bool operator !=(const Square& sq) const
    {
      return mNumber != sq.mNumber;
    };
    Square(signed char file, signed char rank);
    static const std::vector<Square>& allInstances();
    
    typedef std::vector<Square>::const_iterator SquareIterator;
    static void initializeAllInstances();
  private:
    //    Square(signed char file, signed char rank, bool valid);
    //signed char  mFile, mRank;
    char mNumber;
    bool mIsValid;
    static BasicBoard<BasicBoard<const Direction*> > directionCache;
    const Direction& calculateDirectionTo(const Square& sq) const;
    static std::vector<Square> _allInstances;
    struct ClassInitializer
    {
      ClassInitializer() {Square::initializeAllInstances();};
    };
    static ClassInitializer _classInit;
  };
  
  inline
  const std::vector<Square>& 
  Square::allInstances()
  {
    return _allInstances;
  };
  
  inline
  Square::Square( char number )
    : mNumber (number),
      mIsValid( true )
  {
    
  };
  inline
  std::ostream&
  operator<<( std::ostream& out, const Square& sq )
  {
    sq.printOn( out );
    return out;
  }
}; // namespace Alice
# endif // Square_h
