package chess2;
import java.util.ArrayList;
public class Pawn extends ChessPiece{
    boolean hasMoved;
    boolean canBeEnPassanted = false;
    public Pawn(Side SIDE, int XPOS, int YPOS, ChessBoard YOURBOARD, ChessGame GAME){
        super(SIDE, XPOS, YPOS, YOURBOARD, GAME);
        hasMoved = false;
        if (game==ChessGame.ADULTERY)
        {hasMoved=true;}
    }
    public Pawn(Side SIDE, int XPOS, int YPOS,  boolean HASMOVED, ChessBoard YOURBOARD, ChessGame GAME){
        super(SIDE, XPOS, YPOS, YOURBOARD, GAME);
        hasMoved = HASMOVED;
    }

    @Override
    public ArrayList<Decision> possibleDecisions(){
        ArrayList<Decision> possibleDecisions = new ArrayList();

        for (int i=0;i<yourBoard.pawns.size();i++){
            if (yourBoard.pawns.get(i).side==opponentSide){
                if (opponentSide==Side.WHITE){
                    if (canEnPassantTo(yourBoard.pawns.get(i).xPos, yourBoard.pawns.get(i).yPos+100)){
                        possibleDecisions.add(new Decision(yourBoard.pawns.get(i).xPos, yourBoard.pawns.get(i).yPos+100, DeciType.ATTACKS));
                    }
                }
                else{
                    if (canEnPassantTo(yourBoard.pawns.get(i).xPos, yourBoard.pawns.get(i).yPos-100)){
                        possibleDecisions.add(new Decision(yourBoard.pawns.get(i).xPos, yourBoard.pawns.get(i).yPos-100, DeciType.ATTACKS));
                    }
                }
            }
        }
        if (side==Side.WHITE||game==ChessGame.ADULTERY){
            if (canMoveUpTo(xPos, yPos-100)&&(!kingWouldBeInCheck(xPos, yPos-100))){
                if (yourBoard.level(xPos, yPos-100)<yourBoard.level(xPos, yPos)-1){
                    possibleDecisions.add(new Decision(xPos, yPos-100, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(xPos, yPos-100));
                }
            }
            if (!hasMoved&&side==Side.WHITE&&canMoveUpTo(xPos, yPos-200)&&(!kingWouldBeInCheck(xPos, yPos-200))){
                 if (yourBoard.level(xPos, yPos-200)<yourBoard.level(xPos, yPos)-1){
                    possibleDecisions.add(new Decision(xPos, yPos-200, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(xPos, yPos-200));
                }
            }
            if (canAttackDiagonallyTo(xPos+100, yPos-100)&&(!kingWouldBeInCheck(xPos+100, yPos-100))){
                possibleDecisions.add(new Decision(xPos+100, yPos-100, DeciType.ATTACKS));
            }
            if (canAttackDiagonallyTo(xPos-100, yPos-100)&&(!kingWouldBeInCheck(xPos-100, yPos-100))){
                possibleDecisions.add(new Decision(xPos-100, yPos-100, DeciType.ATTACKS));
            }
        }
        if (side==Side.BLACK||game==ChessGame.ADULTERY){
            if (canMoveDownTo(xPos, yPos+100)&&(!kingWouldBeInCheck(xPos, yPos+100))){
                 if (yourBoard.level(xPos, yPos+100)<yourBoard.level(xPos, yPos)-1){
                    possibleDecisions.add(new Decision(xPos, yPos+100, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(xPos, yPos+100));
                }
            }
            if (!hasMoved&&canMoveDownTo(xPos, yPos+200)&&(!kingWouldBeInCheck(xPos, yPos+200))){
                 if (yourBoard.level(xPos, yPos+200)<yourBoard.level(xPos, yPos)-1){
                possibleDecisions.add(new Decision(xPos, yPos+200, DeciType.SUICIDE));
            }
            else{
                possibleDecisions.add(new Decision(xPos, yPos+200));
            }
            }
            if (canAttackDiagonallyTo(xPos+100, yPos+100)&&(!kingWouldBeInCheck(xPos+100, yPos+100))){
                possibleDecisions.add(new Decision(xPos+100, yPos+100, DeciType.ATTACKS));
            }
            if (canAttackDiagonallyTo(xPos-100, yPos+100)&&(!kingWouldBeInCheck(xPos-100, yPos+100))){
                possibleDecisions.add(new Decision(xPos-100, yPos+100, DeciType.ATTACKS));
            }
        }
        if (canExplode(xPos, yPos)&&!kingWouldBeInCheck(xPos, yPos)){
            possibleDecisions.add(new Decision(xPos, yPos, DeciType.EXPLODES));
        }
        int [] xPosits2 = {xPos, xPos, xPos+100, xPos-100, xPos+100, xPos+100, xPos-100, xPos-100};
        int [] yPosits2 = {yPos+100, yPos-100, yPos, yPos, yPos+100, yPos-100, yPos+100, yPos-100};

       for (int n=0;n<8;n++){
           if (canMarry(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n], DeciType.WEDS));
           }
       }
        return possibleDecisions;
    }
    public boolean canEnterTankAt(int XPOS, int YPOS){
        if (side==ChessApplet.yourSide&&!ChessApplet.entertank){
            return false;
        }
        if (yourBoard.getTank(XPOS, YPOS)==null){
            return false;
        }
        if (yourBoard.pieceOccupyingSquare(XPOS, YPOS)!=Piece.TANK){
            return false;
        }
        ChessBoard simulaBoard = new ChessBoard (yourBoard);
        Tank targetTank = simulaBoard.getTank(XPOS, YPOS);
        simulaBoard.clearTank(targetTank);
        simulaBoard.tanks.remove(targetTank);
        if (simulaBoard.getPawn(xPos, yPos).canMoveToMinusTank(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    @Override
    public boolean canMoveTo(int XPOS, int YPOS){
        ArrayList<Decision> possibleDecisions = possibleDecisions();
        if (possibleDecisions.size()==0){
            return false;
        }
        for (int i=0;i<possibleDecisions.size();i++){
            if (possibleDecisions.get(i).xPos==XPOS&&possibleDecisions.get(i).yPos==YPOS){
                break;
            }
            if (i==possibleDecisions.size()-1){
                return false;
            }
        }
        if (kingWouldBeInCheck(XPOS, YPOS)){
            return false;
        }

        return canMoveToMinusChecking(XPOS, YPOS);
    }
     public boolean canAttackToMinusChecking(int XPOS, int YPOS){


        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (canEnPassantTo(XPOS, YPOS)){
           return true;
       }
        if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
            if (side==Side.BLACK&&(yPos<YPOS||game==ChessGame.ADULTERY)){
                return true;
            }
            if (side==Side.WHITE&&(yPos>YPOS||game==ChessGame.ADULTERY)){
                return true;
            }
        }
        return false;
    }
   public boolean canMoveToMinusChecking(int XPOS, int YPOS){

       
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (canEnPassantTo(XPOS, YPOS)){
           return true;
       } 
       if (!hasMoved&&(side==Side.WHITE&&canMoveUpTo(XPOS, YPOS, 2)||game==ChessGame.ADULTERY)){
            return true;
        }
         if (!hasMoved&&(side==Side.BLACK&&canMoveDownTo(XPOS, YPOS, 2)||game==ChessGame.ADULTERY)){
           return true;
        }
        if (side==Side.WHITE&&(canMoveUpTo(XPOS, YPOS, 1)||game==ChessGame.ADULTERY)){
            return true;
        } 
        if (side==Side.BLACK&&(canMoveDownTo(XPOS, YPOS, 1)||game==ChessGame.ADULTERY)){
           return true;
        }
        if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
            if (side==Side.BLACK&&(yPos<YPOS||game==ChessGame.ADULTERY)){
                return true;
            }
            if (side==Side.WHITE&&(yPos>YPOS||game==ChessGame.ADULTERY)){
                return true;
            }
        } 
        return false;
    }
   @Override
   public boolean canEnPassantTo(int XPOS, int YPOS){
          if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
          if (!canMoveDiagonallyTo(XPOS, YPOS, 1)){
              return false;
          }
          if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS)){
            return false;
          }
          for (int i=0;i<yourBoard.pawns.size();i++){
              if (yourBoard.pawns.get(i).canBeEnPassanted&&yourBoard.pawns.get(i).side==opponentSide){
                  if (yourBoard.pawns.get(i).side==Side.WHITE){
                      if (yourBoard.pawns.get(i).xPos==XPOS&&yourBoard.pawns.get(i).yPos==YPOS-100){
                          return true;
                      }
                  }
                  else{
                      if (yourBoard.pawns.get(i).xPos==XPOS&&yourBoard.pawns.get(i).yPos==YPOS+100){
                          return true;
                      }
                  }
              }
          }

          return false;
      }
   public boolean canMoveToMinusTank(int XPOS, int YPOS){
       if (kingWouldBeInCheck(XPOS, YPOS)){
            return false;
        }
       if (!hasMoved&&side==Side.WHITE&&canMoveUpTo(XPOS, YPOS, 2)){
            return true;
        }
         if (!hasMoved&&side==Side.BLACK&&canMoveDownTo(XPOS, YPOS, 2)){
            return true;
        }
        if (side==Side.WHITE&&canMoveUpTo(XPOS, YPOS, 1)){
            return true;
        }
        if (side==Side.BLACK&&canMoveDownTo(XPOS, YPOS, 1)){
            return true;
        }
       return false;
   }
    public void changeCheck(){
        if (side==Side.WHITE&&yPos==_8){
                yourBoard.promotePawn(side, xPos, yPos);
            }
            if (side==Side.BLACK&&yPos==_1){
                yourBoard.promotePawn(side, xPos, yPos);
            }
            if (game==ChessGame.MONKEY||game==ChessGame.PEASANT){
                if (yourBoard.yourKing(opponentSide)!=null&&Math.abs(xPos-yourBoard.yourKing(opponentSide).xPos)<=200&&Math.abs(yPos-yourBoard.yourKing(opponentSide).yPos)<=200){
                    yourBoard.monkeys.add(new Monkey(side, xPos, yPos, yourBoard, game));
                    for (int i=0;i<yourBoard.pawns.size();i++){
                        if (yourBoard.pawns.get(i).xPos==xPos&&yourBoard.pawns.get(i).yPos==yPos){yourBoard.pawns.remove(i);}
                    }
                }
            }
    }
    public void controlMind(){
        if (numberOfChecks()>=3){
            if (side==Side.WHITE){
                side=Side.BLACK;
                opponentSide = Side.WHITE;
            }
            else{
                side = side.WHITE;
                opponentSide = Side.BLACK;
            }
        }
        if (numberOfChecks()>=3){
            yourBoard.pawns.remove(this);
        }
    }
    public void move(int XPOS, int YPOS){
            boolean killedTank = false;
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==opponentSide&&yourBoard.pieceOccupyingSquare(XPOS, YPOS)==Piece.TANK){
                killedTank = true;
            }
            if (ChessApplet.wed&&canMarry(XPOS, YPOS)){
                 yourBoard.marry(XPOS, YPOS, side);
                 return;
             }
            if (side==Side.WHITE&&yPos==_8){
                yourBoard.promotePawn(side, xPos, yPos);
                yourBoard.getPiece(xPos, yPos).inTank = inTank;
            }
            if (side==Side.BLACK&&yPos==_1){
                yourBoard.promotePawn(side, xPos, yPos);
                yourBoard.getPiece(xPos, yPos).inTank = inTank;
            }
              if (!canMoveToMinusChecking(XPOS, YPOS)){
                  return;
              }
            if (game==ChessGame.MONKEY||game==ChessGame.PEASANT){
                if (yourBoard.yourKing(opponentSide)!=null&&Math.abs(xPos-yourBoard.yourKing(opponentSide).xPos)<=200&&Math.abs(yPos-yourBoard.yourKing(opponentSide).yPos)<=200){
                    yourBoard.monkeys.add(new Monkey(side, xPos, yPos, yourBoard, game));
                    yourBoard.getMonkey(xPos, yPos).inTank = inTank;
                    for (int i=0;i<yourBoard.pawns.size();i++){
                        if (yourBoard.pawns.get(i).xPos==xPos&&yourBoard.pawns.get(i).yPos==yPos){yourBoard.pawns.remove(i);}
                    }
                }
            }
              if (canExplode(xPos, yPos)){
                if (inBarrel()){
                    yourBoard.explode(D, _4);
                    yourBoard.explode(D, _5);
                    yourBoard.explode(E, _4);
                    yourBoard.explode(E, _5);
                    yourBoard.wellExploded = true;
                }
                else {
                    yourBoard.explode(xPos, yPos);
                }
                return;
            }
            if (canEnPassantTo(XPOS, YPOS)){
                if (side==Side.WHITE){
                    yourBoard.kill(this, XPOS, YPOS+100);
                }
                else{
                    yourBoard.kill(this, XPOS, YPOS-100);
                }
            }
            if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
                if (side==Side.BLACK&&(yPos<YPOS||game==ChessGame.ADULTERY)){
                    yourBoard.kill(this, XPOS, YPOS);
                }
                if (side==Side.WHITE&&(yPos>YPOS||game==ChessGame.ADULTERY)){
                    yourBoard.kill(this, XPOS, YPOS);
                }

            }
            yourBoard.addWall(xPos, yPos);
            if (yourBoard.level(XPOS, YPOS)<yourBoard.level(xPos, yPos)-1){
                for (int i=0;i<yourBoard.pawns.size();i++){
                    if (yourBoard.pawns.get(i).xPos==xPos&&yourBoard.pawns.get(i).yPos==yPos){
                        yourBoard.pawns.remove(i);
                        break;
                    }
                }
            }
            else{
                if (Math.abs(YPOS-yPos)==200){
                    canBeEnPassanted = true;
                }
                else{
                    canBeEnPassanted = false;
                }
                if (inDisco(XPOS, YPOS)&&!inDisco(xPos, yPos)){yourBoard.wildCards.add(new WildCard(side, XPOS, YPOS, yourBoard, game, Piece.PAWN));yourBoard.pawns.remove(this);}
                else{
                    if (!killedTank){
                        xPos=XPOS;
                        yPos=YPOS;
                        if (game==ChessGame.ADULTERY){
                            if (yourBoard.blackKing!=null&&xPos==yourBoard.blackKing.xPos&&yPos==yourBoard.blackKing.yPos){
                                yourBoard.pawns.remove(this);
                            }
                            if (yourBoard.whiteKing!=null&&xPos==yourBoard.whiteKing.xPos&&yPos==yourBoard.whiteKing.yPos){
                                yourBoard.pawns.remove(this);
                            }
                            for (int i=0;i<yourBoard.queens.size();i++){
                                if (xPos==yourBoard.queens.get(i).xPos&&yPos==yourBoard.queens.get(i).yPos){
                                    yourBoard.pawns.remove(this);
                                }
                            }
                        }
                    }

                    hasMoved = true;
                }

            }
    }

}