package graphics.graph;

import cutils.putils.ClassPathUtils;

import java.io.File;
import java.util.Vector;

/**
 *  The responsibility of this class is to maintain
 *  a collection of all of the nodes and be able to
 *  return any particular node or collection of nodes
 *  upon request,
 *  This class has been modified to store the nodes in
 *  the Vector nodeVector rather than the array nodes[].
 */

public class Nodes {


  private Vector nodeVector = new Vector();

  public Node getRandomNode() {
    Node n = getNode(getRandomNodeNumber());
    return n;
  }

  private int getRandomNodeNumber() {
    return (int) (Math.random() * getNumberOfNodes());
  }

  public Node getNode(int i) {
//      return nodes[i];
    return (Node) nodeVector.elementAt(i);
  }

  int addNode(String lbl) {
    Class c = null;
    try {
      c = Class.forName(lbl);
    } catch (ClassNotFoundException cnfe) {
      // so deep in the code, noone will ever
      // find this...shhh
      // Java hack, alert!
      // if a file name is given, we will have to
      // parse the bytecodes to the class file
      // in order to extract the class.
      // Wacky stuff, huh?
      //  - Doug

      return addNodeModified(lbl);
    }
    Node n = new Node(lbl, c);
    n.setX(50 + 380 * Math.random());
    n.setY(50 + 380 * Math.random());
    nodeVector.addElement(n);
    return nodeVector.size() - 1;
  }

  int addNodeModified(String lbl) {
    Class c = null;
    String className = ClassPathUtils.classFileToClassName(new File(lbl));
    try {
      c = Class.forName(className);
    } catch (ClassNotFoundException cnfe) {
      System.out.println(
          "graphics.graph.Nodes.addNodeModified; can't find class:" + lbl);
    }
    Node n = new Node(lbl, c);
    n.setX(50 + 380 * Math.random());
    n.setY(50 + 380 * Math.random());
    nodeVector.addElement(n);
    return nodeVector.size() - 1;
  }

  public int getNumberOfNodes() {
    return nodeVector.size();
  }

  /**
   *
   */
  public void preturbJRelativetoI(int i, Node n1) {
    double dx = 0;
    double dy = 0;
    for (int j = 0; j < getNumberOfNodes(); j++) {
      if (i == j) continue;
      Node n2 = getNode(j);

      double vx = n1.getX() - n2.getX();
      double vy = n1.getY() - n2.getY();
// len = distance**2 between
// the nodes.
      double len = vx * vx + vy * vy;
//if (len == 0) {
//dx += Math.random();
//dy += Math.random();

//} else
      if (len < 100 * 100) {
        dx += vx / len;
        dy += vy / len;
      }
    }

    double dlen = dx * dx + dy * dy;
    int interNodePixelSpread = 10; //pixels
    if (dlen > 0) {
      dlen = Math.sqrt(dlen) / interNodePixelSpread;
      n1.setDx(n1.getDx() + dx / dlen);
      n1.setDy(n1.getDy() + dy / dlen);
    }

  }

  public Node[] getFixedNodes() {
    Vector v = new Vector();
    for (int i = 0; i < getNumberOfNodes(); i++)
      if (getNode(i).isFixed())
        v.addElement(getNode(i));
    Node na[] = new Node[v.size()];
    v.copyInto(na);
    return na;
  }

  int findNode(String lbl) {
    for (int i = 0; i < getNumberOfNodes(); i++) {
      if (getNode(i).getLbl().equals(lbl))
        return i;
    }
    return addNode(lbl);
  }
}