/***************************************************************************
                          Direction.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.                                   *
 *                                                                         *
 ***************************************************************************/
// -*-c++-*-
# ifndef Direction_h
# define Direction_h
# include <list>
# include <Square.h>
namespace Alice
{
class Square;
class Board;
class Direction
{
public:
  virtual ~Direction();
  virtual Square appliedTo(const Square& sq) const = 0;
  virtual bool isUp() const;
  virtual bool isDown() const;
  virtual bool isRight() const;
  virtual bool isLeft() const;
  virtual bool isUpLeft() const;
  virtual bool isUpRight() const;
  virtual bool isDownLeft() const;
  virtual bool isDownRight() const;
  virtual bool isOrthogonal() const;
  virtual bool isDiagonal() const;
  virtual bool isKnightDirection() const;
  virtual bool isNull() const {return false;}
  virtual Square blockedSquareFrom(const Square& sq, 
				   const Board& board) const;
  static const std::list<Direction*>& allInstances()
  {
    if (allDirections.empty())
      initializeInstances();
    return allDirections;
  };
  static void printInfo();
  static const Direction& up();
  static const Direction& down();
  static const Direction& left();
  static const Direction& right();
  static const Direction& upLeft();
  static const Direction& upRight();
  static const Direction& upUpRight();
  static const Direction& upUpLeft();
  static const Direction& upLeftLeft();
  static const Direction& upRightRight();

  static const Direction& downLeft();
  static const Direction& downRight();
  static const Direction& downDownRight();
  static const Direction& downDownLeft();
  static const Direction& downLeftLeft();
  static const Direction& downRightRight();
  static const Direction& null();
protected:
  Direction(signed char diff = 0);
  static std::list<Direction*> allDirections;
private:
  signed char difference;
  static void initializeInstances();
  static int created;
  static int deleted;
  // instances
  static Direction* mUp;
  static Direction* mDown;
  static Direction* mLeft;
  static Direction* mRight;
  static Direction* mUpLeft;
  static Direction* mUpRight;
  static Direction* mDownLeft;
  static Direction* mDownRight;
  static Direction* mUpLeftLeft;
  static Direction* mUpRightRight;
  static Direction* mUpUpLeft;
  static Direction* mUpUpRight;
  static Direction* mDownDownLeft;
  static Direction* mDownDownRight;
  static Direction* mDownLeftLeft;
  static Direction* mDownRightRight;
  static Direction* mNull;
};
inline 
Square
Direction::appliedTo(const Square& sq) const
{
  return sq.number() + difference;
};
}; // namespace Alice
# endif // Direction_h
