package com.github.pedrovgs.nox.path;

/**
 * Circular Path implementation used to place NoxItem objects in a circle inside NoxView starting
 * from the center of the view. NoxItem instances in this path will have the same size and the
 * number of NoxItem elements per circle level will follow a linear distribution where "n = 6 *
 * iteration" and one element in the middle of the view.
 *
 * @author Pedro Vicente Gomez Sanchez.
 */
class CircularPath extends Path {

  private static final double RAD = Math.PI / 180;
  private static final int BASE = 6;

  CircularPath(PathConfig pathConfig) {
    super(pathConfig);
  }

  @Override public void calculate() {
    PathConfig pc = getPathConfig();
    int numberOfItems = pc.getNumberOfElements();
    final float centerX =
        pc.getViewWidth() / 2 - pc.getFirstItemSize() / 2 - pc.getFirstItemMargin() / 2;
    final float centerY =
        pc.getViewHeight() / 2 - pc.getFirstItemSize() / 2 - pc.getFirstItemMargin() / 2;
    float radius = pc.getFirstItemSize() + pc.getFirstItemMargin();
    int item = 0;
    int iteration = 0;
    while (item < numberOfItems) {
      int numberOfElementsPerIteration = Math.max(BASE * iteration, 1);
      calculatePositionsForIteration(item, numberOfElementsPerIteration, radius, iteration, centerX,
          centerY);
      item += numberOfElementsPerIteration;
      iteration++;
    }
  }

  private void calculatePositionsForIteration(int item, int numberOfElementsPerIteration,
      float radius, float iteration, float centerX, float centerY) {
    if (numberOfElementsPerIteration == 1) {
      setNoxItemLeftPosition(item, centerX);
      setNoxItemTopPosition(item, centerY);
      return;
    }

    float distance = radius * iteration;
    int numberOfElements = getPathConfig().getNumberOfElements();
    numberOfElementsPerIteration = Math.min(numberOfElementsPerIteration, numberOfElements - item);
    for (int i = 0; i < numberOfElementsPerIteration; i++) {
      double angle = RAD * 360 / numberOfElementsPerIteration * i;
      double sin = Math.sin(angle);
      double cos = Math.cos(angle);
      float x = (float) (centerX + (sin * distance));
      float y = (float) (centerY + (cos * distance));
      setNoxItemLeftPosition(item, x);
      setNoxItemTopPosition(item, y);
      item++;
    }
  }
}

@@ -1165,40 +1165,13 @@
 on =
- Math.max(BASE * iteration, 1);%0A
+%0A    
     
@@ -1212,38 +1212,8 @@
 tem,
- numberOfElementsPerIteration,
  rad
@@ -1236,26 +1236,16 @@
 centerX,
-%0A         
  centerY
@@ -1331,20 +1331,19 @@
 private 
-void
+int
  calcula
@@ -1379,48 +1379,8 @@
 tem,
- int numberOfElementsPerIteration,%0A     
  flo
@@ -1390,20 +1390,18 @@
 radius, 
-floa
+in
 t iterat
@@ -1419,16 +1419,22 @@
 centerX,
+%0A     
  float c
@@ -1439,24 +1439,113 @@
  centerY) %7B%0A
+    int numberOfElementsPerIteration = getNumberOfElementsPerIteration(item, iteration);%0A
     if (numb
@@ -1678,16 +1678,18 @@
   return
+ 1
 ;%0A    %7D%0A
@@ -1734,174 +1734,8 @@
 on;%0A
-    int numberOfElements = getPathConfig().getNumberOfElements();%0A    numberOfElementsPerIteration = Math.min(numberOfElementsPerIteration, numberOfElements - item);%0A
     
@@ -2131,18 +2131,416 @@
 em++;%0A    %7D%0A
+    return numberOfElementsPerIteration;%0A  %7D%0A%0A  protected int getNumberOfElementsPerIteration(int item, int iteration) %7B%0A    int numberOfElements = getPathConfig().getNumberOfElements();%0A    int numberOfElementsPerIteration = Math.max(BASE * iteration, 1);%0A    numberOfElementsPerIteration = Math.min(numberOfElementsPerIteration, numberOfElements - item);%0A    return numberOfElementsPerIteration;%0A
   %7D%0A%7D%0A

Refactor CircularPath to calculate the number of elements per iteration in one method we can override to build the next path