package graphics.graph;

import java.awt.*;

class Node {
  private double x;
  private double y;

  private double dx;
  private double dy;

  private boolean fixed;

  private String lbl;

  private Class nodeClass = null;

  public Node(String _lbl, Class c) {
    lbl = _lbl;
    nodeClass = c;
  }

  public String toString() {
    return lbl + ":nodeClass:" + nodeClass;
  }

  public Class getNodeClass() {
    return nodeClass;
  }

  public void setNodeClass(Class c) {
    nodeClass = c;
  }


  public double getX() {
    return x;
  }


  /**
   * moveNode nuges the node if it is not fixed
   * it also checks the extremes and
   * reduces the dimensions
   */
  public void nugeNode(Dimension d) {
    if (!isFixed())
      nuge();
    ceilingNode(d);
    oneHalfDxDy();
  }

  public static void nIsNotFixed(Node n) {
    //what does this code do?
    //int temp = 0;
    //int halfTemp = temp/2;
    //n.setX(n.getX() + (temp * Math.random() - halfTemp));
    //n.setY(n.getY() + (temp * Math.random() - halfTemp));
  }

  public void incrementDxDy(double _dx, double _dy) {
    dx = dx + _dx;
    dy = dy + _dy;
  }

  /**
   * push node by small amount on screen
   */
  public void nuge() {
    double nodeX = getX();
    int minDistance = 15;
    setX(nodeX
         + Math.max(-minDistance,
                    Math.min(
                        minDistance,
                        getDx())));
    double nodeY = getY();
    setY(nodeY
         + Math.max(-minDistance,
                    Math.min(minDistance, getDy())));
  }

  /**
   * ceilingNode makes sure that node
   * does not exceed a given dimension
   */
  public void ceilingNode(Dimension d) {
    if (getX() > d.width)
      setX(d.width);
    if (getY() > d.height)
      setY(d.height);
  }

  /**
   * cut dx and dy by one half
   * @author D. Lyon
   */
  public void oneHalfDxDy() {
    setDx(getDx() / 2);
    setDy(getDy() / 2);
  }

  public void setX(double _x) {
    x = _x;
    if (x < 0) x = 0;
  }

  public double getY() {
    return y;
  }

  public void setY(double _y) {
    y = _y;
    if (y < 0) y = 0;
  }

  public double getDx() {
    return dx;
  }

  public void setDx(double dx) {
    this.dx = dx;
  }

  public double getDy() {
    return dy;
  }

  public void setDy(double dy) {
    this.dy = dy;
  }

  public Dimension getSize(FontMetrics fm) {
    int w = fm.stringWidth(getLbl()) + 10;
    int h = fm.getHeight() + 4;
    return new Dimension(w, h);
  }

  public void draw(Graphics g) {
    FontMetrics fm = g.getFontMetrics();
    Dimension d = getSize(fm);
    int w = d.width;
    int h = d.height;
    int ix = (int) x;
    int iy = (int) y;
    g.fillRect(ix - w / 2, iy - h / 2, w, h);
    g.setColor(Color.black);
    g.drawRect(ix - w / 2, iy - h / 2, w - 1, h - 1);
    g.drawString(getLbl(), (ix - (w - 10) / 2),
                 (iy - (h - 4) / 2) + fm.getAscent());
  }

  public boolean isFixed() {
    return fixed;
  }

  public void setFixed(boolean fixed) {
    this.fixed = fixed;
  }


  public String getLbl() {
    return lbl;
  }

  public void setLbl(String _lbl) {
    lbl = _lbl;
  }
}