#include <iostream>
#include <GL/glut.h>

#include "CMove.h"
#include "Pieces.h"
#include "CBoard.h"




/////////////
//         //
//  QUEEN  //
//         //
/////////////

char CQueen::GetChar() const
{
  return ((GetColor() == WHITE) ? 'Q' : 'q');
}

CBasePiece* CQueen::GetCopy(CBoard* par) const
{
  return new CQueen(par, GetX(), GetY(), GetColor());
}

type_piece CQueen::GetType() const
{
  return QUEEN;
}


bool CQueen::IsCheck(type_color Col) const
{
  if ((Col == EMPTY) || (Col == GetColor()))
    return false;

  char King = ((Col == WHITE) ? 'K' : 'k');

  char x, y;

  // Horizontal check to the right

  x = GetX() + 1;
  y = GetY();

  while (x <= 7)
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x++;
    }


  // Horizontal check to the left

  x = GetX() - 1;
  y = GetY();

  while (x >= 0)
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x--;
    }


  // Vertical check above

  x = GetX();
  y = GetY() + 1;

  while (y <= 7)
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      y++;
    }


  // Vertical check below

  x = GetX();
  y = GetY() - 1;

  while (y >= 0)
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      y--;
    }


  // North-East check
  x = GetX() + 1;
  y = GetY() + 1;

  while ( (x <= 7) && (y <= 7) )
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x++;
      y++;
    }


  // South-East check

  x = GetX() + 1;
  y = GetY() - 1;

  while ( (x <= 7) && (y >= 0) )
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x++;
      y--;
    }


  // South-West check

  x = GetX() - 1;
  y = GetY() - 1;

  while ( (x >= 0) && (y >= 0) )
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x--;
      y--;
    }


  // North-West check

  x = GetX() - 1;
  y = GetY() + 1;

  while ( (x >= 0) && (y <= 7) )
    {
      if ((*GetParent())(x, y)->GetColor() != EMPTY)
        {
          if ((*GetParent())(x, y)->GetChar() == King)
            return true;
          else
            break;
        }

      x--;
      y++;
    }

  return false;
}

bool CQueen::IsMoveValid(const CMove& move) const
{
  if ( (move.GetSourceX() != GetX()) || (move.GetSourceY() != GetY()) )
    return false;

  char DirX = move.GetDestinationX() - move.GetSourceX();
  char DirY = move.GetDestinationY() - move.GetSourceY();

  if (!((abs(DirX) == abs(DirY)) || ( (DirX == 0) ^ (DirY == 0) )))
    return false;

  if (DirX)
    DirX /= abs(DirX);
  if (DirY)
    DirY /= abs(DirY);

  char CurX = GetX()+DirX;
  char CurY = GetY()+DirY;

  while ( (CurX != move.GetDestinationX()) ||
          (CurY != move.GetDestinationY()) )
    {
      if ((*GetParent())(CurX, CurY)->GetColor() != EMPTY)
        return false;
      else
        {
          CurX += DirX;
          CurY += DirY;
        }
    }

  if ((*GetParent())(CurX, CurY)->GetColor() == GetColor())
    return false;

  CBoard copy = *GetParent();
  copy.Move(move);

  if (copy.IsCheck(GetColor()))
    return false;

  return true;
}

void CQueen::MoveAlert(const CMove& move)
{
  return;
}
