package chess2;


import java.util.ArrayList;
public class MoveNode{
    int key = -5;
   ChessBoard board;
   int owner_key = -6;
   Side side;
   final int checkmate = 1000000; //One million
   ArrayList<MoveNode> consequences = new ArrayList();
   public MoveNode(int KEY, int OWNER_KEY, ChessBoard BOARD, Side SIDE)
   {
       key = KEY;
       side = SIDE;
       owner_key = OWNER_KEY;
       board = new ChessBoard(BOARD);
   }
   public MoveNode(ChessBoard BOARD, Side SIDE)
   {
       side = SIDE;
       board = new ChessBoard(BOARD);
   }
   public MoveNode(ChessBoard BOARD, ArrayList<MoveNode> CONSEQUENCES, Side SIDE)
   {

        side = SIDE;
        board = new ChessBoard(BOARD);
        for(int i=0;i<CONSEQUENCES.size();i++)
        {

        }
   }
   private Side opponentSide(Side orgSide)
   {
       if (orgSide==Side.WHITE)
       {
           return Side.BLACK;
       }
       else
       {
           return Side.WHITE;
       }
   }
   private int pieceEval(Side SIDE)
   {
       int advantage = 0;
       Side opponentSide = opponentSide(SIDE);
       int pieceEval = 0;

           for (int i=0;i<board.pawns.size();i++)
           {
               if (board.pawns.get(i).inBarrel())
               {

               }
               else
               {
                   if (board.pawns.get(i).side==opponentSide)
                   {
                        pieceEval -=50;
                    
                   }
                   else
                   {
                       pieceEval +=50;
                    
                   }
               }
           }
       for (int i=0;i<board.bishops.size();i++)
           {
               if (board.bishops.get(i).inBarrel())
               {

               }
               else
               {
                   if (board.bishops.get(i).side==opponentSide)
                   {
                        pieceEval -=200;
                    
                   }
                   else
                   {
                       pieceEval +=200;
                    
                   }
               }
           }
       for (int i=0;i<board.knights.size();i++)
           {
               if (board.knights.get(i).inBarrel())
               {

               }
               else
               {
                   if (board.knights.get(i).side==opponentSide)
                   {
                        pieceEval -=400;
                    
                   }
                   else
                   {
                       pieceEval +=400;
                   
                   }
               }
           }
       for (int i=0;i<board.rooks.size();i++)
           {
               if (board.rooks.get(i).inBarrel())
               {

               }
               else
               {
                   if (board.rooks.get(i).side==opponentSide)
                   {
                       if (board.game==ChessGame.ADULTERY)
                       {
                           pieceEval -= 1000;
                       }
                       else
                       {
                            pieceEval -=500;
                       }
                    //    pieceEval -= proxEval(opponentSide, board.rooks.get(i).xPos, board.rooks.get(i).yPos);
                   }
                   else
                   {
                       if (board.game==ChessGame.ADULTERY)
                       {
                           pieceEval += 1000;
                       }
                       else
                       {
                            pieceEval +=500;
                       }
                   //    pieceEval += proxEval(opponentSide, board.rooks.get(i).xPos, board.rooks.get(i).yPos);
                   }
               }
           }
       for (int i=0;i<board.queens.size();i++)
           {
               if (board.queens.get(i).inBarrel())
               {

               }
               else
               {

                   if (board.queens.get(i).side==opponentSide)
                   {
                        if (board.game==ChessGame.ADULTERY)
                        {
                            pieceEval -= (800-distance(board.queens.get(i).xPos, board.queens.get(i).yPos, board.yourKing(opponentSide).xPos, board.yourKing(opponentSide).yPos))*2;
                        }
                        else
                        {
                            pieceEval -=900;
                        }
                      //  pieceEval -= proxEval(opponentSide, board.queens.get(i).xPos, board.queens.get(i).yPos);
                   }
                   else
                   {
                       if (board.game==ChessGame.ADULTERY)
                       {
                           pieceEval += (800-distance(board.queens.get(i).xPos, board.queens.get(i).yPos, board.yourKing(side).xPos, board.yourKing(side).yPos))*15;
                       }
                       else
                       {
                            pieceEval +=900;
                       }
                    //   pieceEval += proxEval(opponentSide, board.queens.get(i).xPos, board.queens.get(i).yPos);
                   }
               }
           }
       for (int i=0;i<board.mysteryPieces.size();i++)
           {
               if (board.mysteryPieces.get(i).inBarrel())
               {

               }
               else
               {
                   if (board.mysteryPieces.get(i).side==opponentSide)
                   {
                        pieceEval -=50;
                      //  pieceEval -= proxEval(opponentSide, board.mysteryPieces.get(i).xPos, board.mysteryPieces.get(i).yPos);
                   }
                   else
                   {
                       pieceEval +=50;
                     
                   }
               }
           }
       if (board.yourKing(SIDE).inBarrel())
       {
           pieceEval -= 1200;
       }
       if (board.yourKing(SIDE).isSuffocated())
       {
           pieceEval -= 50000;
       }
       advantage += pieceEval;
       advantage += optionsEval(SIDE);
       return advantage;
   }
   private int optionsEval(Side SIDE)
   {
       int yourOptions = Reply.replies(board, SIDE).size();
       int opponentOptions = Reply.replies(board, opponentSide(SIDE)).size();
       if (yourOptions==0)
       {
           if (board.yourKing(SIDE).inCheckMate())
           {
               return -checkmate;
           }
           else
           {
               //half a negative checkmate is a draw; draws should be second only to losing
               return -(checkmate/2);
           }
       }
           else if (opponentOptions==0)
           {
               if (board.yourKing(opponentSide(SIDE)).inCheckMate())
               {
                   return checkmate;
               }
               else
               {
                   return -(checkmate/2);
               }
           }
        else
        {
           int advantage = (yourOptions)-(opponentOptions);
          if (board.game==ChessGame.CLAUSTROPHOBIC)
           {
               advantage *= 10;
           } 
            return advantage;
        }
   }
 /*  private int proxEval(Side SIDE, int XPOS, int YPOS)
   {
       int advantage = 0;
       King OpponentKing = board.yourKing(opponentSide(SIDE));
       int distance = distance(OpponentKing.xPos, OpponentKing.yPos, XPOS, YPOS);
       advantage = distance*25;
       return advantage;
   }
  * */
   private int distance(int XPOS1, int YPOS1, int XPOS2, int YPOS2)
   {
       return (int) Math.sqrt((XPOS2-XPOS1)*(XPOS2-XPOS1))+((YPOS2-YPOS1)*(YPOS2-YPOS1));
   } 
   private int evaluateBoard(Side SIDE)
   {
       
       int yourMoves = Reply.replies(board, SIDE).size();
       int opponentMoves = Reply.replies(board, opponentSide(SIDE)).size();
       if (yourMoves>0&&opponentMoves==0)
       {
           return checkmate;
       }
       else if (yourMoves==0&&opponentMoves>0)
       {
           return -checkmate;
       }
       else
       {
           int advantage = pieceEval(SIDE);
           return advantage;
       }

   }
   public int value(Side SIDE)
   {
       
       
       if (consequences.size()==0)
       {
            return evaluateBoard(SIDE);
       }
      // System.out.println("Is in fact recursing");
       int boardval = evaluateBoard(SIDE);
       if (boardval==checkmate||boardval==-checkmate)
       {
           return boardval;
       }
       int leastValue = consequences.get(0).value(SIDE);
       for (int i=1;i<consequences.size();i++)
       {
           int value = consequences.get(i).value(SIDE);
           if (value<leastValue)
           {
               leastValue = value;
           }
       }

       return leastValue;
   }
   public void addConsequence(MoveNode CONSEQUENCE)
   {
       consequences.add(CONSEQUENCE);
   }

}