package nxm.sys.test.junit.prim;

import java.util.HashSet;
import java.util.LinkedList;

import nxm.sys.lib.Midas;
import nxm.sys.prim.prescaler;
import nxm.sys.test.junit.NMTestCase;

/** Tests for prescaler
 *  @author Jeanette McCall
 *  @since NeXtMidas 3.9.2
 */
public class prescalerTest extends NMTestCase {


    public prescalerTest(String methodName) {
      super(methodName, null);
    }

    /** Creates a new instance of the class.
        @param methodName The name of the method being called.
        @param midas      The midas context testTo use when running the tests.
     */
    public prescalerTest(String methodName, Midas midas) {
      super(methodName, midas);
    }

    /** Tests the operation of "random" that is really a planned scattering of samples */
    public void testGetNScatteredMultiplesOfValue () {
      int maxN = 1024;
      int n = maxN / 10;
      int frameSize = 1024;
      int lastChosen = frameSize * maxN;
      LinkedList<Integer> samples = prescaler.getNScatteredMultiplesOfValue(n,maxN,frameSize);
      int numChosen = samples.size();
      int first = samples.peekFirst();
      int last = samples.peekLast();
      boolean numChosenInRange = (numChosen >= n) && (numChosen < n * 1.1);
      assertTrue("prescaler.getNScatteredMultiplesOfValue number chosen in range",numChosenInRange);
      assertEquals("prescaler.getNScatteredMultiplesOfValue choses first element", 0, first);
      assertEquals("prescaler.getNScatteredMultiplesOfValue choses last element", lastChosen, last);
      double approxInterval = (maxN - 1) * frameSize / (double)n;
      double halfInterval = approxInterval / 2;
      int numValuesOutOfRange = 0;
      for (int sampleIdx = 0; sampleIdx < n; sampleIdx++) {
        int sample = samples.get(sampleIdx);
        double expected = approxInterval * sampleIdx;
        double lowBounds = expected - halfInterval;
        double highBounds = expected + halfInterval;
        if ((sample < lowBounds) || (sample > highBounds)) numValuesOutOfRange++;
      }
      assertEquals("prescaler.getNScatteredMultiplesOfValue number values out of range", 0, numValuesOutOfRange);
    }

    /** Tests the operation of "random" that is preseeded random (except first and last always selected) */
    public void testGetNRandomMultiplesOfValue () {
      int maxN = 1024;
      int n = maxN / 10;
      int frameSize = 1024;
      int lastChosen = frameSize * maxN;
      HashSet<Integer> samples = prescaler.getNRandomMultiplesOfValue(n,maxN,frameSize);
      int numChosen = samples.size();
      boolean first = samples.contains(Integer.valueOf(0));
      boolean last = samples.contains(Integer.valueOf(lastChosen));
      assertEquals("prescaler.getNRandomMultiplesOfValue number chosen is exact", n, numChosen);
      assertTrue("prescaler.getNRandomMultiplesOfValue choses first element", first);
      assertTrue("prescaler.getNRandomMultiplesOfValue choses last element", last);
    }
  }
