package chess2;
import java.util.ArrayList;

public class King extends ChessPiece {
    boolean hasMoved = false;
    boolean hasCastled = false;
    int air=0;
    Path path;
    boolean didBreathInPlace = false;
    public King(Side SIDE, int XPOS, int YPOS, ChessBoard YOURBOARD, ChessGame GAME){
        super(SIDE, XPOS, YPOS, YOURBOARD, GAME);
    }
    public King(Side SIDE, int XPOS, int YPOS, int AIR, ChessBoard YOURBOARD, ChessGame GAME){
            super(SIDE, XPOS, YPOS, YOURBOARD, GAME);
            air = AIR;
    }
    public King(Side SIDE, int XPOS, int YPOS, boolean HASMOVED, ChessBoard YOURBOARD, ChessGame GAME){
        super(SIDE, XPOS, YPOS, YOURBOARD, GAME);
        hasMoved = HASMOVED;
    }
     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.yourKing(side)!=null&&simulaBoard.yourKing(side).canMoveToMinusTank(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    public boolean canCanibalize(int XPOS, int YPOS){
        switch(game){
            case NORMAL: return false;
            case INSECURE: return false;
            case ADULTERY: return false;
        }
        if (inBarrel(xPos, yPos)&&!inBarrel(XPOS, YPOS))
        {
            return false;
        }
        if (!(Math.abs(xPos-XPOS)==100||Math.abs(yPos-YPOS)==100)){
            return false;
        }
        if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==side&&yourBoard.pieceOccupyingSquare(XPOS, YPOS)!=Piece.TANK){
            return true;
        }
        return false;
    }
    @Override
    public ArrayList<Decision> possibleDecisions(){
        ArrayList<Decision> possibleDecisions = new ArrayList();
        if (canBreathInPlace()){
            possibleDecisions.add(new Decision(xPos, yPos));
        }
        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 (canMoveInLineTo(xPosits2[n], yPosits2[n])&&!kingWouldBeInCheck(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n]));
           }
           else if (canCanibalize(xPosits2[n], yPosits2[n])&&!kingWouldBeInCheck(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n], DeciType.CANNIBALIZES));
           }
           else if (canAttackInLineTo(xPosits2[n], yPosits2[n])&&!kingWouldBeInCheck(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n], DeciType.ATTACKS));
           }
        /*   if (canMarry(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n], DeciType.WEDS));
           }
           if (canEnterTankAt(xPosits2[n], yPosits2[n])){
               possibleDecisions.add(new Decision(xPosits2[n], yPosits2[n], DeciType.ENTERS));
           } */
       }
      /*  ArrayList<Decision> corpseJumps = corpseJumps();
        for (int i=0;i<corpseJumps.size();i++){
            possibleDecisions.add(corpseJumps.get(i));
        } */
        return possibleDecisions;
    }
    @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 canBreathInPlace(){
        if (!inCheck()&&isSuffocated()){
            return true;
        }
        return false;
    }
    public boolean canMoveToMinusChecking(int XPOS, int YPOS){

        if (canBreathInPlace()){
            return true;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (canMoveUpTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackUpTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveDownTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackDownTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveRightTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackRightTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveLeftTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackLeftTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveDiagonallyTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canCanibalize(XPOS, YPOS)){
            return true;
        }
        ArrayList<Decision> corpseJumps = corpseJumps();
        for (int i=0;i<corpseJumps.size();i++){
            if (corpseJumps.get(i).xPos==XPOS&&corpseJumps.get(i).yPos==YPOS){return true;}
        }
        if (canEnterTankAt(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    public boolean canMoveToMinusTank(int XPOS, int YPOS){
        if (kingWouldBeInCheck(XPOS, YPOS)){
            return false;
        }
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (canMoveUpTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackUpTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveDownTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackDownTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveRightTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackRightTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveLeftTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackLeftTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canMoveDiagonallyTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
            return true;
        }
        if (canCanibalize(XPOS, YPOS)){
            return true;
        }
        ArrayList<Decision> corpseJumps = corpseJumps();
        for (int i=0;i<corpseJumps.size();i++){
            if (corpseJumps.get(i).xPos==XPOS&&corpseJumps.get(i).yPos==YPOS){return true;}
        }
        return false;
    }
    public int corpseNum(int XPOS, int YPOS){
        int corpsenum = 0;
        ArrayList<Decision> corpseJumps = corpseJumps();

        for (int i=0;i<yourBoard.corpses.size();i++){
            Decision landingSquare = landingSquare(yourBoard.corpses.get(i).xPos, yourBoard.corpses.get(i).yPos);
            if (landingSquare!=null&&landingSquare.xPos==XPOS&&landingSquare.yPos==YPOS){
                corpsenum++;
                yourBoard.corpses.remove(i);
                i--;
            }

        }
        return corpsenum;
    }
    public void move(int XPOS, int YPOS){
        didBreathInPlace = false;
            if (XPOS==xPos&&YPOS==yPos&&canBreathInPlace()){
               hasMoved=!hasMoved;
               air--;
               didBreathInPlace = true;
                return;
            }

            boolean killedTank = false;
            if (yourBoard.sideOccupyingSquare(XPOS, YPOS)==opponentSide&&yourBoard.pieceOccupyingSquare(XPOS, YPOS)==Piece.TANK){
                killedTank = true;
            }
            if (side==ChessApplet.yourSide){
                if (ChessApplet.wed&&canMarry(XPOS, YPOS)){
                    yourBoard.marry(XPOS, YPOS, side);
                     return;
                }
            }
            else{
                if (canMarry(XPOS, YPOS)){
                    yourBoard.marry(XPOS, YPOS, side);
                     return;
                }
            }
           int corpsenum = corpseNum(XPOS, YPOS);
           yourBoard.corpses.clear();
           if (corpsenum>0){
               if (corpsenum==1){

               }
               else if(corpsenum==2){

               }
               else if (corpsenum==3){

               }
               xPos = XPOS;
               yPos = YPOS;
               hasMoved = true;
               return;
           }
           if (canCanibalize(XPOS, YPOS)){
                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);
                    }
                }
                for (int i=0;i<yourBoard.bishops.size();i++){
                    if (yourBoard.bishops.get(i).xPos==XPOS&&yourBoard.bishops.get(i).yPos==YPOS){
                        yourBoard.bishops.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.knights.size();i++){
                    if (yourBoard.knights.get(i).xPos==XPOS&&yourBoard.knights.get(i).yPos==YPOS){
                        yourBoard.knights.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.queens.size();i++){
                    if (yourBoard.queens.get(i).xPos==XPOS&&yourBoard.queens.get(i).yPos==YPOS){
                        yourBoard.queens.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.rooks.size();i++){
                    if (yourBoard.rooks.get(i).xPos==XPOS&&yourBoard.rooks.get(i).yPos==YPOS){
                        yourBoard.rooks.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.mysteryPieces.size();i++){
                    if (yourBoard.mysteryPieces.get(i).xPos==XPOS&&yourBoard.mysteryPieces.get(i).yPos==YPOS){
                        yourBoard.mysteryPieces.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.tanks.size();i++){
                    if (yourBoard.tanks.get(i).xPos==XPOS&&yourBoard.tanks.get(i).yPos==YPOS){
                        yourBoard.tanks.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.monkeys.size();i++){
                    if (yourBoard.monkeys.get(i).xPos==XPOS&&yourBoard.monkeys.get(i).yPos==YPOS){
                        yourBoard.monkeys.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.tacoFiends.size();i++){
                    if (yourBoard.tacoFiends.get(i).xPos==XPOS&&yourBoard.tacoFiends.get(i).yPos==YPOS){
                        yourBoard.tanks.remove(i);
                    }
                }
                for (int i=0;i<yourBoard.wildCards.size();i++){
                    if (yourBoard.wildCards.get(i).xPos==XPOS&&yourBoard.wildCards.get(i).yPos==YPOS){
                        yourBoard.tanks.remove(i);
                    }
                }
                air++;
            }
            if (canAttackUpTo(XPOS, YPOS, 1)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackDownTo(XPOS, YPOS, 1)){
                yourBoard.kill(this, XPOS, YPOS);

            }
            if (canAttackLeftTo(XPOS, YPOS, 1)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackRightTo(XPOS, YPOS, 1)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackDiagonallyTo(XPOS, YPOS, 1)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            yourBoard.addWall(xPos, yPos);
            if (inDisco(XPOS, YPOS)&&!inDisco(xPos, yPos)){
                yourBoard.wildCards.add(new WildCard(side, XPOS, YPOS, yourBoard, game, Piece.KING));yourBoard.getWildCard(XPOS, YPOS).air = air;
                if (side==Side.WHITE){yourBoard.whiteKing=null;}
                else{yourBoard.blackKing=null;}
            }
                else{
                    if (!killedTank){
                        xPos=XPOS;
                        yPos=YPOS;
                    }

                    hasMoved = true;

                }
    }

}