/**
 * @file Node.java
 *
 * @author
 *    Anastasia Foti AEM:8959
 *    <anastaskf@ece.auth.gr>
 *
 * @author
 *    Christos Choutouridis AEM:8997
 *    <cchoutou@ece.auth.gr>
 */

package host.labyrinth;

import java.util.ArrayList;

/**
 * Node object for minimax tree.
 */
class Node {

   /** @name Constructors */
   /** @{ */
   /** Null initialize constructor */
   Node () { }
   /** The main constructor for the Node */
   Node (Node parent, int nodeDepth, int [] nodeMove, Board nodeBoard, double nodeEvaluation) {
      this.parent          = parent;
      this.children        = null;
      this.nodeDepth       = nodeDepth;
      this.nodeMove        = nodeMove;
      this.nodeBoard       = nodeBoard;
      this.nodeEvaluation  = nodeEvaluation;
      this.path            = null;
   }
   /** A special constructor for creating a root Node */
   Node (Board nodeBoard) {
      this.parent          = null;
      this.children        = null;
      this.nodeDepth       = 0;
      this.nodeMove        = new int [4];
      this.nodeBoard       = nodeBoard;
      this.nodeEvaluation  = 0;
      this.path            = null;
   }
   /**@} */
   
   /** @name Get/Set interface */
   /** @{ */
   /** Get parent */
   Node getParent()           { return parent; }
   /** get children */
   ArrayList<Node>
      getChildren()           { return children; }
   /** get nodeDepth */
   int getNodeDepth()         { return nodeDepth; }
   /** get nodeMove */
   int[] getNodeMove()        { return nodeMove; }
   /** get nodeBoard */
   Board getNodeBoard()       { return nodeBoard; }
   /** get nodeEvluation */
   double getNodeEvaluation (){ return nodeEvaluation; }
   /** get path */
   Node getPath()             { return path; }

   /** set parent */
   void setParent(Node parent) { this.parent = parent; }
   /** set children */
   void setChildren(ArrayList<Node> children) {
      this.children = children;
   }
   /** set nodeDepth */
   void setNodeDepth(int nodeDepth) {
      this.nodeDepth = nodeDepth;
   }
   /** set nodeMove */
   void setNodeMove(int[] nodeMove) {
      this.nodeMove = nodeMove;
   }
   /** set nodeBoard */
   void setNodeBoard(Board nodeBoard) {
      this.nodeBoard = nodeBoard;
   }
   /** set nodeEvaluation */
   void setNodeEvaluation(double nodeEvaluation) {
      this.nodeEvaluation = nodeEvaluation;
   }
   /** set path */
   void setPath (Node path) {
      this.path = path;
   }

   /**@}*/

   /** @name Public API */
   /** @{ */
   /**
    * Add a child to the tree
    * @param   child   The child to add
    * @return  the status of the operation
    */
   boolean addChild (Node child) {
      if (children == null)
         children = new ArrayList<>();
      return children.add(child);
   }
   /**@}*/

   /** @name Data members */
   /** @{ */
   private Node            parent;     /**< Back reference to parent Node */
   private ArrayList<Node> children;   /**< Fwd reference to leaf Nodes */
   private int             nodeDepth;  /**< The Node's depth */
   private int[]           nodeMove;   /**< The Node's move data [tile, initTile, points, roll]*/
   private Board           nodeBoard;  /**< Reference to Board's copy of the current node*/
   private double          nodeEvaluation; /**< The Node's evaluation result */
   private Node            path;       /**< The minimax evaluation path */
   /**@}*/
}
