/***************************************************************************
                          Direction.cpp  -  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.                                   *
 *                                                                         *
 ***************************************************************************/
# include "Directions/Direction.h"
# include "Square.h"
# include "Board.h"
# include "Pieces/Piece.h"

# include "Directions/DirectionUp.h"
# include "Directions/DirectionDown.h"
# include "Directions/DirectionLeft.h"
# include "Directions/DirectionRight.h"
# include "Directions/DirectionUpLeft.h"
# include "Directions/DirectionUpRight.h"
# include "Directions/DirectionDownLeft.h"
# include "Directions/DirectionDownRight.h"
# include "Directions/DirectionUpUpLeft.h"
# include "Directions/DirectionUpLeftLeft.h"
# include "Directions/DirectionUpUpRight.h"
# include "Directions/DirectionUpRightRight.h"
# include "Directions/DirectionDownDownLeft.h"
# include "Directions/DirectionDownDownRight.h"
# include "Directions/DirectionDownLeftLeft.h"
# include "Directions/DirectionDownRightRight.h"
# include "Directions/NullDirection.h"
// static variables
using namespace Alice;

std::list<Direction*> Direction::allDirections;

Direction* Direction::mUp = 0;
Direction* Direction::mDown = 0;
Direction* Direction::mRight = 0;
Direction* Direction::mLeft = 0;
Direction* Direction::mUpLeft = 0;
Direction* Direction::mUpRight = 0;
Direction* Direction::mDownLeft = 0;
Direction* Direction::mDownRight = 0;
Direction* Direction::mUpUpLeft = 0;
Direction* Direction::mUpUpRight = 0;
Direction* Direction::mUpLeftLeft = 0;
Direction* Direction::mUpRightRight = 0;
Direction* Direction::mDownDownLeft = 0;
Direction* Direction::mDownDownRight = 0;
Direction* Direction::mDownLeftLeft = 0;
Direction* Direction::mDownRightRight = 0;
Direction* Direction::mNull = 0;

Direction::Direction(signed char diff)
  : difference(diff)
{
	created ++;
};
Direction::~Direction()
{
	deleted ++;
};


bool 
Direction::isUp() const
{
  return false;
};

bool 
Direction::isDown() const
{
  return false;
};

bool 
Direction::isLeft() const
{
  return false;
};

bool 
Direction::isRight() const
{
  return false;
};

bool 
Direction::isUpRight() const
{
  return false;
};

bool 
Direction::isUpLeft() const
{
  return false;
};

bool 
Direction::isDownRight() const
{
  return false;
};

bool 
Direction::isDownLeft() const
{
  return false;
};

bool Direction::isOrthogonal() const
{
  return false;
};

bool Direction::isDiagonal() const
{
  return false;
};
bool Direction::isKnightDirection() const
{
  return false;
};
Square 
Direction::blockedSquareFrom(const Square& sq, const Board& board) const
{
  Square destination(appliedTo(sq));
  while(destination.isValid() && board.at(destination)->isNull())
    destination = appliedTo(destination);
  return destination;
};
void
Direction::initializeInstances()
{
  allDirections.push_back(mUp = new DirectionUp);
  allDirections.push_back(mDown = new DirectionDown);
  allDirections.push_back(mLeft = new DirectionLeft);
  allDirections.push_back(mRight = new DirectionRight);
  allDirections.push_back(mUpLeft = new DirectionUpLeft);
  allDirections.push_back(mUpRight = new DirectionUpRight);
  allDirections.push_back(mDownLeft = new DirectionDownLeft);
  allDirections.push_back(mDownRight = new DirectionDownRight);
  allDirections.push_back(mUpUpLeft = new DirectionUpUpLeft);
  allDirections.push_back(mUpUpRight = new DirectionUpUpRight);
  allDirections.push_back(mDownDownLeft = new DirectionDownDownLeft);
  allDirections.push_back(mDownDownRight = new DirectionDownDownRight);
  allDirections.push_back(mUpLeftLeft = new DirectionUpLeftLeft);
  allDirections.push_back(mUpRightRight = new DirectionUpRightRight);
  allDirections.push_back(mDownLeftLeft = new DirectionDownLeftLeft);
  allDirections.push_back(mDownRightRight = new DirectionDownRightRight);
  mNull = new NullDirection;
};

int
Direction::created = 0;

int
Direction::deleted = 0;

void
Direction::printInfo()
{
	std::cout<<"Direction: "<<created<<" instances created"<<std::endl;
	std::cout<<"Direction: "<<deleted<<" instances deleted"<<std::endl;
	std::cout<<"Direction: "<<created-deleted<<" instances left"<<std::endl;
	
};

const Direction&
Direction::up()
{
	return *mUp;
};

const Direction&
Direction::down()
{
	return *mDown;
};

const Direction&
Direction::left()
{
	return *mLeft;
};

const Direction&
Direction::right()
{
	return *mRight;
};
const Direction&
Direction::upLeft()
{
	return *mUpLeft;
};

const Direction&
Direction::downRight()
{
	return *mDownRight;
};

const Direction&
Direction::downLeft()
{
	return *mDownLeft;
};

const Direction&
Direction::upRight()
{
	return *mUpRight;
};

const Direction&
Direction::upUpLeft()
{
	return *mUpUpLeft;
};
const Direction&
Direction::upUpRight()
{
	return *mUpUpRight;
};
const Direction&
Direction::upLeftLeft()
{
	return *mUpLeftLeft;
};
const Direction&
Direction::upRightRight()
{
	return *mUpRightRight;
};
const Direction&
Direction::downDownLeft()
{
	return *mDownDownLeft;
};
const Direction&
Direction::downDownRight()
{
	return *mDownDownRight;
};
const Direction&
Direction::downLeftLeft()
{
	return *mDownLeftLeft;
};
const Direction&
Direction::downRightRight()
{
	return *mDownRightRight;
};
const Direction&
Direction::null()
{
	return *mNull;
};
