package chess2;
import java.util.ArrayList;
public class Queen extends ChessPiece {
    public Queen(Side SIDE, int XPOS, int YPOS, ChessBoard YOURBOARD, ChessGame GAME){
        super(SIDE, XPOS, YPOS, YOURBOARD, GAME);

    }
    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.getQueen(xPos, yPos).canMoveToMinusTank(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    @Override
    public ArrayList<Decision> possibleDecisions(){
        ArrayList<Decision> possibleDecisions = new ArrayList();

         for (int i=xPos-100;inRangeOfBoard(i, yPos);i-=100){
             if (canMoveLeftTo(i, yPos)&&(!kingWouldBeInCheck(i, yPos))){
                 if (yourBoard.level(i, yPos)<yourBoard.level(i+100, yPos)-1){
                    possibleDecisions.add(new Decision(i, yPos, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(i, yPos));
                }
             }
             if (game==ChessGame.ADULTERY){
                 break;
             }
         }
         for (int i=xPos;inRangeOfBoard(i, yPos);i-=100){
             if (canAttackLeftTo(i, yPos)&&(!kingWouldBeInCheck(i, yPos))){
                 possibleDecisions.add(new Decision(i, yPos, DeciType.ATTACKS));
             }
              if (game==ChessGame.ADULTERY&&i!=xPos){
                 break;
             }
         }
        for (int i=xPos+100;inRangeOfBoard(i, yPos);i+=100){
             if (canMoveRightTo(i, yPos)&&(!kingWouldBeInCheck(i, yPos))){
                 if (yourBoard.level(i, yPos)<yourBoard.level(i-100, yPos)-1){
                    possibleDecisions.add(new Decision(i, yPos, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(i, yPos));
                }
             }
             if (game==ChessGame.ADULTERY){
                 break;
             }
         }
         for (int i=xPos;inRangeOfBoard(i, yPos);i+=100){
             if (canAttackRightTo(i, yPos)&&(!kingWouldBeInCheck(i, yPos))){
                 possibleDecisions.add(new Decision(i, yPos, DeciType.ATTACKS));
             }
             if (game==ChessGame.ADULTERY&&i!=xPos){
                 break;
             }
         }
        for (int i=yPos-100;inRangeOfBoard(xPos, i);i-=100){
             if (canMoveUpTo(xPos, i)&&(!kingWouldBeInCheck(xPos, i))){
                 if (yourBoard.level(xPos, i)<yourBoard.level(xPos, i+100)-1){
                    possibleDecisions.add(new Decision(xPos, i, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(xPos, i));
                }
             }
             if (game==ChessGame.ADULTERY){
                 break;
             }
         }
        for (int i=yPos;inRangeOfBoard(xPos, i);i-=100){
             if (canAttackUpTo(xPos, i)&&(!kingWouldBeInCheck(xPos, i))){
                 possibleDecisions.add(new Decision(xPos, i, DeciType.ATTACKS));
             }
              if (game==ChessGame.ADULTERY&&i!=yPos){
                 break;
             }
         }
        for (int i=yPos+100;inRangeOfBoard(xPos, i);i+=100){
             if (canMoveDownTo(xPos, i)&&(!kingWouldBeInCheck(xPos, i))){
                 if (yourBoard.level(xPos, i)<yourBoard.level(xPos, i-100)-1){
                    possibleDecisions.add(new Decision(xPos, i, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(xPos, i));
                }
             }
             if (game==ChessGame.ADULTERY){
                 break;
             }
         }
         for (int i=yPos;inRangeOfBoard(xPos, i);i+=100){
             if (canAttackDownTo(xPos, i)&&(!kingWouldBeInCheck(xPos, i))){
                 possibleDecisions.add(new Decision(xPos, i, DeciType.ATTACKS));
             }
             if (game==ChessGame.ADULTERY&&i!=yPos){
                 break;
             }
         }
        int XPOS = xPos+100;
        int YPOS = yPos+100;
        while(inRangeOfBoard(XPOS, YPOS)){
            if (canMoveDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                if (yourBoard.level(XPOS, YPOS)<yourBoard.level(XPOS-100, YPOS-100)-1){
                    possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(XPOS, YPOS));
                }
            }
            else if (canAttackDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.ATTACKS));
                break;
            }

            XPOS+=100;
            YPOS+=100;
            if (game==ChessGame.ADULTERY){
                 break;
             }
        }
        XPOS = xPos+100;
        YPOS = yPos-100;
        while(inRangeOfBoard(XPOS, YPOS)){
            if (canMoveDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                if (yourBoard.level(XPOS, YPOS)<yourBoard.level(XPOS-100, YPOS+100)-1){
                    possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(XPOS, YPOS));
                }
            }
            else if (canAttackDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.ATTACKS));
                break;
            }

            XPOS+=100;
            YPOS-=100;
            if (game==ChessGame.ADULTERY){
                 break;
             }
        }
        XPOS = xPos-100;
        YPOS = yPos+100;
        while(inRangeOfBoard(XPOS, YPOS)){
            if (canMoveDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                possibleDecisions.add(new Decision(XPOS, YPOS));
            }
            else if (canAttackDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.ATTACKS));
                break;
            }

            XPOS-=100;
            YPOS+=100;
            if (game==ChessGame.ADULTERY){
                 break;
             }
        }
        XPOS = xPos-100;
        YPOS = yPos-100;
        while(inRangeOfBoard(XPOS, YPOS)){
            if (canMoveDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                if (yourBoard.level(XPOS, YPOS)<yourBoard.level(XPOS+100, YPOS+100)-1){
                    possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.SUICIDE));
                }
                else{
                    possibleDecisions.add(new Decision(XPOS, YPOS));
                }
            }
            else if (canAttackDiagonallyTo(XPOS, YPOS)&&(!kingWouldBeInCheck(XPOS, YPOS))){
                possibleDecisions.add(new Decision(XPOS, YPOS, DeciType.ATTACKS));
                break;
            }

            XPOS-=100;
            YPOS-=100;
            if (game==ChessGame.ADULTERY){
                 break;
             }
        }
        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;
    }
    @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 canMoveToMinusChecking(int XPOS, int YPOS){
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (canMoveUpTo(XPOS, YPOS)){
            return true;
        }
        if (canAttackUpTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveDownTo(XPOS, YPOS)){
            return true;
        }
        if (canAttackDownTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveLeftTo(XPOS, YPOS)){
            return true;
        }
        if (canAttackLeftTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveRightTo(XPOS, YPOS)){
            return true;
        }
        if (canAttackRightTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveDiagonallyTo(XPOS, YPOS)){
            return true;
        }
        if (canAttackDiagonallyTo(XPOS, YPOS)){
            return true;
        }
        if (canEnterTankAt(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    public boolean canMoveToMinusTank(int XPOS, int YPOS){
        if (!inRangeOfBoard(XPOS, YPOS)){
            return false;
        }
        if (kingWouldBeInCheck(XPOS, YPOS)){
            return false;
        }
        if (canMoveUpTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveDownTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveLeftTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveRightTo(XPOS, YPOS)){
            return true;
        }
        if (canMoveDiagonallyTo(XPOS, YPOS)){
            return true;
        }
        return false;
    }
    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.queens.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 (canAttackUpTo(XPOS, YPOS)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackDownTo(XPOS, YPOS)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackLeftTo(XPOS, YPOS)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackRightTo(XPOS, YPOS)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackDiagonallyTo(XPOS, YPOS)){
                yourBoard.kill(this, XPOS, YPOS);
            }
            if (canAttackInLineTo(XPOS, YPOS, 2)){
                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.queens.size();i++){
                    if (yourBoard.queens.get(i).xPos==xPos&&yourBoard.queens.get(i).yPos==yPos){
                        yourBoard.queens.remove(i);
                        break;
                    }
                }
            }
            else{
                if (inDisco(XPOS, YPOS)&&!inDisco(xPos, yPos)){yourBoard.wildCards.add(new WildCard(side, XPOS, YPOS, yourBoard, game, Piece.QUEEN));yourBoard.queens.remove(this);}
                else{
                    if (!killedTank){
                        xPos=XPOS;
                        yPos=YPOS;

                    }
                }
            }
        }
}