package bagaturchess.bitboard.bughouse.eval;

import bagaturchess.bitboard.bughouse.BughouseConstants;
import bagaturchess.bitboard.common.Fen;
import bagaturchess.bitboard.common.Utils;
import bagaturchess.bitboard.impl.Constants;

/*
 EVERYTHING IS CENTI-PAWN EVALUATED
*/
public class BughouseAttackWeightEval implements IBughouseEval {

    /* NOT IN USE */

    private Fen fen;
    private int sideToMove;

    private int kingPositionW;
    private int kingPositionB;
    private int kingDiagonalW;
    private int kingDiagonalB;
    private int kingFileW;
    private int kingFileB;
    private int kingRankW;
    private int kingRankB;

    static final int[] FILES =

        {

           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8,
           1,2,3,4,5,6,7,8

        };

    static final int[] RANKS =
    {

           1,1,1,1,1,1,1,1,
           2,2,2,2,2,2,2,2,
           3,3,3,3,3,3,3,3,
           4,4,4,4,4,4,4,4,
           5,5,5,5,5,5,5,5,
           6,6,6,6,6,6,6,6,
           7,7,7,7,7,7,7,7,
           8,8,8,8,8,8,8,8

    };

    final double[] BISHOP_SCALING_WHITE = Utils.reverseSpecial(new double[]{1, 1, 1.02, 1.05, 1.1, 1.12, 1.15, 1.2});
    final double[] ROOK_SCALING = Utils.reverseSpecial(new double[]{1, 1, 1, 1.03, 1.05, 1.07, 1.09, 1.10});
    final double[] QUEEN_SCALING = {};


    public BughouseAttackWeightEval(String fenPosition) {
        this.fen = new Fen(fenPosition);
        this.sideToMove = fen.getColourToMove();
        this.kingPositionW = getKingPositionFromFEN(0);
        this.kingPositionB = getKingPositionFromFEN(1);

        updateAllPositions();
    }


    private void updateAllPositions() {
        updateKingsFile();
        updateKingRank();
        updateKingDiagonal();
    }


    private int getKingPositionFromFEN(int kingColor) {
        for (int i = 0; i < fen.getBoardArray().length; i++) {
            if (fen.getBoardArray()[i] == Constants.PID_W_KING && kingColor == Constants.COLOUR_WHITE) {
                return i;
            } else if (fen.getBoardArray()[i] == Constants.PID_B_KING && kingColor == Constants.COLOUR_BLACK) {
                return i;
            }
        }
        throw new UnsupportedOperationException("FEN position is not correct, could not find king");
    }

    /*
    Checks if king and bishop are on the same diagonal and if so, returns max scaling.
    If not, returns scaling based on the diagonal difference between the two if said difference is in range.
    Otherwise returns scaling of lower then 1, subject to change in BughouseConstants;
    */
    @Override
    public int getBughouseWeightedEvalBishop(int tileNumber) {
        int bishopDiagonal = getDiagonal(tileNumber);
        int diagonalDifference = Math.abs(bishopDiagonal - kingDiagonalW);

        if (isGreekSacrifice(kingDiagonalW, bishopDiagonal)) {
            return BughouseConstants.BISHOP_GREEK_SACRIFICE_SCALING;
        }
        return getBishopBonusCP(diagonalDifference);
    }

    private boolean isGreekSacrifice(int kingDiagonal, int bishopDiagonal) {
        if (fen.getColourToMove() == Constants.COLOUR_WHITE) {
            return kingDiagonal == BughouseConstants.KING_DIAGPOSITION_FOR_GREEK_SACRIFICE_BONUS_
                    && bishopDiagonal == BughouseConstants.BISHOP_DIAGPOSITION_FOR_GREEK_SACRIFICE_BONUS_;
        } else {
            return kingDiagonal == BughouseConstants.KING_DIAGPOSITION_FOR_GREEK_SACRIFICE_BONUS_BLACK
                    && bishopDiagonal == BughouseConstants.BISHOP_DIAGPOSITION_FOR_GREEK_SACRIFICE_BONUS_BLACK;
        }
    }


    public int getBughouseWeightedEvalKnight(int tileNumber) {
        return 100;
    }


    public int getBughouseWeightedEvalRook(int tileNumber) {
        int rookFile = FILES[tileNumber];
        return (int) ROOK_SCALING[Math.abs(rookFile - kingFileW)] * 100;
    }


    public int getBughouseWeightedEvalQueen(int tileNumber) {
        //TODO
        return 100;
    }


    /*
    UPDATES REGARDING PIECE FILE/RANK/DIAGONAL
    */
    private void updateKingsFile() {
        this.kingFileW = FILES[kingPositionW];
        this.kingFileB = FILES[kingPositionB];
    }


    private void updateKingDiagonal() {
        this.kingDiagonalW = 7 + kingRankW - kingFileW;
        this.kingDiagonalB = 7 ;
    }


    private void updateKingRank() {
        this.kingRankW = RANKS[kingPositionW];
        this.kingRankB = RANKS[kingPositionB];
    }


    private int getDiagonal(int tileNumber) {
        return 7 + RANKS[tileNumber] - FILES[tileNumber];
    }

    /*
    GETTER METHODS
    */
    private int getBishopBonusCP(int diagonalDifference) {
        if (diagonalDifference == kingDiagonalW) {
            return (int) BISHOP_SCALING_WHITE[7]*100;
        }
        if (diagonalDifference >= 0 && diagonalDifference <= 7) {
            return (int) BISHOP_SCALING_WHITE[diagonalDifference]*100;
        } else {
            return BughouseConstants.BISHOP_OUT_OF_POSITION_SCALING;
        }
    }


}
