/* (non-Javadoc)
  * @see gov.nasa.ial.mde.solver.symbolic.AnalyzedItem#dispose()
  */
 public void dispose() {
   xName = null;
   yName = null;
   xData = null;
   yData = null;
   preferredBounds = null;
   features = null;
   xPointValues = null;
   disposeGraphTrails();
   disposePoints();
 }
  /* (non-Javadoc)
   * @see gov.nasa.ial.mde.solver.symbolic.AnalyzedItem#computePoints(double, double, double, double)
   */
  public void computePoints(double left, double right, double top, double bottom) {
    // Calculate the points and graph-trails for the given bounds
    int lastIndex = xData.length - 1;

    int leftIndex = Arrays.binarySearch(xData, left);
    if (leftIndex < 0) {
      leftIndex = -leftIndex - 1;
    }
    if (leftIndex >= xData.length) {
      leftIndex = lastIndex;
    }
    // Use the point to the left of the index found in the binary search,
    // which puts us to the left of the desired left position.
    while ((leftIndex > 0) && (xData[leftIndex] > left)) {
      leftIndex--;
    }

    int rightIndex = Arrays.binarySearch(xData, right);
    if (rightIndex < 0) {
      rightIndex = -rightIndex - 1;
    }
    if (rightIndex >= xData.length) {
      rightIndex = lastIndex;
    }
    // Use the index found in the binary search, which puts us to the right
    // of the desired right position.
    while ((rightIndex < lastIndex) && (xData[rightIndex] < right)) {
      rightIndex++;
    }

    if (leftIndex > rightIndex) {
      throw new IllegalArgumentException("Can not have left bound > right bound");
    }

    // The left and right indexes for all the real data points in the given bounds.
    this.leftIndexBound = leftIndex;
    this.rightIndexBound = rightIndex;

    maxJump = Math.abs(top - bottom);
    int totalPts = (rightIndex - leftIndex) + 1;

    // NOTE: Our current model is to either interpolate or decimate the real data points.
    // TODO: Use a real data model.

    // Dispose of the current points array so we don't have a memory leak.
    disposePoints();

    // Generate the points that will be used for sonifying the model.
    if (totalPts < NUM_POINTS) {
      // Interpolate the data to a length of NUM_POINTS.
      points = PointsUtil.interpolatePoints(leftIndex, rightIndex, NUM_POINTS, xData, yData);
    } else if (totalPts > NUM_POINTS) {
      // Decimate the data to a length of NUM_POINTS.
      points = PointsUtil.decimatePoints(leftIndex, rightIndex, NUM_POINTS, xData, yData);
    } else {
      // Make a copy of the points that is a length of NUM_POINTS.
      points = PointsUtil.copyPoints(leftIndex, rightIndex, xData, yData);
    }

    // Create the array of x-values of the points for quick x-value to index lookup.
    // We assume that the x values from the points array are sorted in ascending order.
    if (points == null) {
      xPointValues = null;
    } else {
      int len = points.length;
      if ((xPointValues == null) || (xPointValues.length != len)) {
        xPointValues = new double[len];
      }
      for (int i = 0; i < len; i++) {
        xPointValues[i] = points[i].x;
      }
    }

    // Dispose of the current graph trails array so we don't have a memory leak.
    disposeGraphTrails();

    // Generate the trails used for graphing the model of the real data.
    graphTrails = TrailUtil.getGraphTrailsFrom(points, maxJump);

    // Update the preferred bounds we keep for this analyzed data.
    preferredBounds.setBounds(left, right, top, bottom);
  }