/** @param args */
  public static void main(String[] args) {

    VoronoiCore core = new VoronoiCore();
    OpenList sites = new OpenList();
    Random rand = new Random(100);
    int amount = 200;

    PolygonSimple rootPolygon = new PolygonSimple();
    int width = 500;
    int height = 500;
    rootPolygon.add(0, 0);
    rootPolygon.add(width, 0);
    rootPolygon.add(width, height);
    rootPolygon.add(0, height);
    for (int i = 0; i < amount; i++) {
      Site site = new Site(rand.nextInt(width), rand.nextInt(width));
      site.setPercentage(1);
      sites.add(site);
    }
    sites.get(0).setPercentage(3);

    core.setDebugMode();
    //		core.setOutputMode();
    core.normalizeSites(sites);
    // ArrayList<Site> sites = TestConvergence.getSites(100, rectangle,
    // true);
    // core.setErrorAreaThreshold(0.00);
    // core.setUseExtrapolation(false);
    // normalizeSites(sites);
    core.setSites(sites);
    core.setClipPolygon(rootPolygon);
    long start = System.currentTimeMillis();

    core.setUseNegativeWeights(true);
    core.setCancelOnAreaErrorThreshold(true);
    core.doIterate(5000);

    long end = System.currentTimeMillis();
    double diff = (end - start) / 1000.0D;
    System.out.println("NeededTime: " + diff);
    // }
  }
  public void doIterate(final int iterationAmount) {
    //		solveDuplicates(this.sites);

    // if there is just one side we don't have to do anything
    if (sites.size == 1) {
      PolygonSimple p = (PolygonSimple) clipPolygon.clone();
      Site site = sites.get(0);
      site.setPolygon(p);
      return;
    }
    if (firstIteration) {
      voroDiagram();
      drawCurrentState(false);
    }
    //		long start = System.nanoTime();

    int k = 0;
    for (int i = 0; i < iterationAmount; i++) {
      iterate();

      //			long end = System.nanoTime();
      //			 System.out.println("Time in MilliSeconds,Iter "+i+":" + ((double)(end - start))/10E6);
      //			start=end;

      // for (Site site : polygons.keySet()) {
      // NPoly poly=polygons.get(site);
      // /**
      // * the the resulting polygon
      // */
      // if (site.cellObject != null) {
      // site.cellObject.setVoroPolygon(poly.clone());
      // }
      // }
      drawCurrentState(false);

      if (isCancelOnAreaErrorThreshold() && lastMaxError < errorAreaThreshold) {
        //				 System.out.println("AreaError:" + lastAreaError);
        //				 System.out.println("Iterations:" + i);
        break;
      }
    }
    // System.out.println("AreaError:"+errorArea);

    // now its finish so give the cells a hint
    drawCurrentState(true);

    /** TODO remove cellObject notification */
    Site[] array = sites.array;
    int size = sites.size;
    for (int z = 0; z < size; z++) {
      Site site = array[z];
      PolygonSimple poly = site.getPolygon();
      if (site.cellObject != null) {
        site.cellObject.setVoroPolygon(poly);
        site.cellObject.doFinalWork();
      }
    }
    //		long end = System.currentTimeMillis();
    //		 System.out.println("Time in MilliSeconds:" + (end - start));
    // System.out.println("LastErrorArea:" + lastAreaError);
    // System.out.println("LastErrorArea:" + lastAreaError/sites.size());
  }