#include "xbugchess.h"
#include "table.h"

check_for_legal_move(tab,p,x,y,nx,ny, mycolor,whoseturn,special)
Special *special;
char mycolor,whoseturn;
Table *tab;
Piece *p;
int x,y,nx,ny;
{
  int retval;
  int t;

  t = PieceType(p);

  if((x == nx) && (y == ny) && PieceWhere(p) == ONBOARD) return MYPIECE;

  switch( t ) {
  case PAWN:
    retval = pawnmove(tab,p,x,y,nx,ny,mycolor,whoseturn, special);
    if( (retval != ILLEGAL) && (( ny == 0) || (ny == 7))) {
      SpecialType(special) = PROMOTION;
    }
    break;

  case ROOK:
    retval = rookmove(tab, p, x,y,nx,ny,whoseturn);
    break;

  case KNIGHT:
    retval = knightmove(tab,p,x,y,nx,ny,whoseturn);
    break;
    
  case BISHOP:
    retval = bishopmove(tab, p,x,y,nx,ny,whoseturn);
    break;

  case QUEEN:
  case QMUTANT:
    retval = queenmove(tab,p,x,y,nx,ny,whoseturn);
    break;
    
  case KING:
    retval = kingmove(tab,p,x,y,nx,ny,whoseturn,special);
    break;
  }
  return retval;
}


pawnmove(t,p,x,y,nx,ny,mycolor,whoseturn, special)
Special *special;
char mycolor, whoseturn;
Piece *p;
Table *t;
int x,y,nx,ny;
{
  Piece junk;
  int retval;
  if (PieceWhere(p) != ONBOARD)  {
    if (ny == 0 || ny == 7) return ILLEGAL;
    retval = check_for_clear_space(t,nx,ny,whoseturn);
    if (retval == OPPIECE) return ILLEGAL;
    return retval;
  }

  if(x == nx ) {
    if((PieceMoveStatus(p) == 0 ) && (((y == 1) && (ny == 3))  ||
				      ((y == 6) && (ny == 4)))) {
      if (check_row_clear (t,x,y,nx,ny,whoseturn, &junk) == EMPTY) {
	return EMPTY;
      } else {
	return ILLEGAL;
      }
    }
    
    if(PieceColor(p) == mycolor) {
      if (y == ny + 1)  {
	if (check_for_clear_space (t, nx,ny,whoseturn) == EMPTY) {
	  return EMPTY;
	} else  {
	  return ILLEGAL;
	}
      } else return ILLEGAL;
    } else {
      if (y == ny - 1) {
	if (check_for_clear_space (t,nx,ny,whoseturn) == EMPTY) {
	  return EMPTY;
	} else  {
	  return ILLEGAL;
	}
      } else return ILLEGAL;
    }
  } else {
    if( ( x == nx + 1 ) || ( x == nx - 1)) { 
      if(PieceColor(p) == mycolor) {
	if ( y == ny + 1) {
	  if (check_for_clear_space (t, nx,ny,whoseturn) == OPPIECE) {
	    return OPPIECE;
	  } else  {
	    return ILLEGAL;
	  } 
	} else return ILLEGAL;
      } else {
	if ( y == ny - 1) {
	  if (check_for_clear_space (t, nx,ny,whoseturn) == OPPIECE) {
	    return OPPIECE;
	  } else {
	    return ILLEGAL;
	  }
	} else return ILLEGAL;
      }
    } else return ILLEGAL;
  }
}

rookmove(t,p,x,y,nx,ny,whoseturn)
Piece *p;
Table *t;
int x,y,nx,ny;
char whoseturn;
{
  int retval;
  Piece retpiece;
  if (PieceWhere(p) != ONBOARD)  {
    retval = check_for_clear_space(t,nx,ny,whoseturn);
    if (retval == OPPIECE) return ILLEGAL;
    return retval;
  }
  if( ( x == nx ) || (y == ny)) {
    return check_row_clear(t,x,y,nx,ny,whoseturn, &retpiece);
  } else return ILLEGAL;
}

knightmove(t,p,x,y,nx,ny,whoseturn)
char whoseturn;
Piece *p;
Table *t;
int x,y,nx,ny;
{
  int retval;
  if (PieceWhere(p) != ONBOARD)  {
    retval = check_for_clear_space(t,nx,ny,whoseturn);
    if (retval == OPPIECE) return ILLEGAL;
    return retval;
  }
  if((( abs(x - nx) == 1) && (abs(y - ny) == 2)) ||
     (( abs(y - ny) == 1) && (abs(x - nx) == 2)))
    return check_for_clear_space(t,nx,ny,whoseturn);
  else return ILLEGAL;
}

bishopmove(t,p,x,y,nx,ny,whoseturn)
char whoseturn;
Piece *p;
Table *t;
int x,y,nx,ny;
{
  int retval;
  Piece retpiece;

  if (PieceWhere(p) != ONBOARD)  {
    retval = check_for_clear_space(t,nx,ny,whoseturn);
    if (retval == OPPIECE) return ILLEGAL;
    return retval;
  }
  if (PieceWhere(p) != ONBOARD) 
    return check_for_clear_space(t,nx,ny,whoseturn);
  if ( abs(x - nx) == abs(y - ny)) {
    return check_di_clear(t,x,y,nx,ny,whoseturn, &retpiece);
  } else return ILLEGAL;
}

queenmove(t,p,x,y,nx,ny,whoseturn)
char whoseturn;
Piece *p;
Table *t;
int x,y,nx,ny;
{
  int retval;
  if (PieceWhere(p) != ONBOARD)  {
    retval = check_for_clear_space(t,nx,ny,whoseturn);
    if (retval == OPPIECE) return ILLEGAL;
    return retval;
  }
  if ((retval = bishopmove(t,p,x,y,nx,ny,whoseturn)) != ILLEGAL) {
    return retval;
  }
  if ((retval = rookmove(t,p,x,y,nx,ny,whoseturn)) != ILLEGAL) {
    return retval;
  }
  return ILLEGAL;
}

kingmove(t,p,x,y,nx,ny,whoseturn,special)
Special *special;
char whoseturn;
Piece *p;
Table *t;
int x,y,nx,ny;
{
  int endx,counter, newx;
  Piece *whichrook, junkpiece;

  if(abs(y-ny) > 1) return ILLEGAL;
  if(abs(x-nx) < 2)
    return check_for_clear_space(t, nx,ny,whoseturn);
  
  if((y != ny) || (abs(x-nx) != 2) || (PieceMoveStatus(p))) return ILLEGAL;
  if(nx < x) endx = 0;
  else endx = 7;
  if( (whichrook = XY2Piece(t, endx, y, ONBOARD)) == 0) return ILLEGAL;
  if(PieceMoveStatus(whichrook))  return ILLEGAL;

  newx = (nx + x) / 2;
  if (check_row_clear(t,x,y, (endx) ? 6:1, y,whoseturn, &junkpiece) != EMPTY ) return ILLEGAL;
  if(getgametype() != BUGCHESS)
    for(counter = 0 ; counter <= abs(endx-x) ; counter++) {
      if( underattack(&TableBoard(t),x,y,whoseturn) )  {
	printf("%d, %d, under attach \n", x,y);
	return ILLEGAL;
      }
      if(endx > x) x++; else x--;
    } 
  /* Set up Special to be Castle */

  /* NOTE THAT ROOK ISN"T PUSHED IN BOARDXYPIECE */
  SpecialType(special) = CASTLE;
  SpecialOldPiecePtr(special)  = whichrook;
  SpecialOldPiece(special)  = *whichrook; 
  SpecialNewPiece(special) = *whichrook;
  PieceBaseX(&(SpecialNewPiece(special))) = newx;
  PieceBaseY(&(SpecialNewPiece(special))) = y;
  PieceWhere(&(SpecialNewPiece(special))) = ONBOARD;
  PieceMoveStatus(&(SpecialNewPiece(special))) = 1;

  PieceWhere(whichrook) = ALTERNATE;
  PieceAltX(whichrook) = newx;
  PieceAltY(whichrook) = y;

  return EMPTY;

}


rattk(b,x,y, endx, endy,whoseturn)
Board *b;
int x,y,endx,endy;
{
  Piece retpiece;
  if(check_row_clear(BoardTable(b),x,y,endx,endy,whoseturn,&retpiece) == OPPIECE) {
    if ((PieceColor(&retpiece) != whoseturn) && 
	((PieceType(&retpiece) == ROOK) ||
	 (PieceType(&retpiece) == QUEEN))) {
      printf("Caught in %d, %d, from %d, %d\n", endx,endy, PieceX(&retpiece),
	     PieceY(&retpiece));
      return 1;
    }
  } 
  return 0;
}

dattk(b,x,y, endx,endy,whoseturn)
Board *b;
int x,y,endx,endy;
{
  Piece retpiece;
  if(check_di_clear(BoardTable(b),x,y,endx,endy, whoseturn,&retpiece) == OPPIECE) {
    if ((PieceColor(&retpiece) != whoseturn) && 
	((PieceType(&retpiece) == BISHOP) ||
	 (PieceType(&retpiece) == QUEEN))) {
      printf("DiCaught in %d, %d, from %d, %d\n", endx,endy, PieceX(&retpiece),
	     PieceY(&retpiece));
      return 1;
    }
  } 
  return 0;
}

underattack(b,x,y,whoseturn)
Board *b;
int x,y;
{
  int real_piece_grabbed, retval = 0, saveboard;

  if (rattk(b,x,y,x,7,whoseturn) ||
      rattk(b,x,y,x,0,whoseturn) ||
      rattk(b,x,y,7,y,whoseturn) || 
      rattk(b,x,y,0,y,whoseturn)) return 1;
  
  if (dattk(b,x,y, x+7, y+7,whoseturn) ||
      dattk(b,x,y, x-7, y+7,whoseturn) ||
      dattk(b,x,y, x+7, y-7,whoseturn) ||
      dattk(b,x,y, x-7, y-7,whoseturn)) {
    return 1;
  }

  if (knightat(b,x+2, y+1)  ||
      knightat(b,x+2, y-1)  ||
      knightat(b,x-2, y+1)  ||
      knightat(b,x-2, y-1)  ||
      knightat(b,x+1, y+2)  ||
      knightat(b,x+1, y-2)  ||
      knightat(b,x-1, y+2)  ||
      knightat(b,x-1, y-2))  return 1; 

  return 0;
}

