/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */

package bank;

import java.util.Arrays;
import java.util.Comparator;

import ilog.views.chart.accessibility.IlvAccessibleDataPoint;
import ilog.views.chart.accessibility.IlvChartAreaAccessible;
import ilog.views.chart.servlet.IlvAbstractChartNavigationInfoGenerator;
import ilog.views.chart.servlet.IlvChartHitmap;
import ilog.views.util.hitmap.IlvNavigationInfo;

/**
 * The IlvDefaultChartNavigationInfoGenerator allows the user to navigate
 * through a chain of data points, that consists of first the data points of the
 * first data set, then the data points of the second data set, and so on. In
 * this sample, however, the first data set contains the credit card operations,
 * the second data set the transfers, the third data set the withdrawals, and so
 * on. A user does not want to see the operations ordered in this way. Rather,
 * the desired order is by x value, that is, by the time of the operation.
 *
 * This class implements this custom ordering.
 */
public class MyNavigationInfoGenerator extends IlvAbstractChartNavigationInfoGenerator {

  private Integer[] permutation;
  private int[] inversePermutation;

  public MyNavigationInfoGenerator(final IlvChartHitmap hitmap) {
    super(hitmap);

    int count = hitmap.getRegionsCount();
    permutation = new Integer[count];
    for (int region = 1; region <= count; region++)
      permutation[region - 1] = Integer.valueOf(region);
    Arrays.sort(permutation, new Comparator<Integer>() {
      Override
      public int compare(Integer region1, Integer region2) {
        IlvChartAreaAccessible element1 = hitmap.getElementOfRegion(region1.intValue());
        IlvChartAreaAccessible element2 = hitmap.getElementOfRegion(region2.intValue());
        if (element1 instanceof IlvAccessibleDataPoint) {
          if (element2 instanceof IlvAccessibleDataPoint) {
            IlvAccessibleDataPoint pt1 = (IlvAccessibleDataPoint) element1;
            IlvAccessibleDataPoint pt2 = (IlvAccessibleDataPoint) element2;
            // First, compare the x values.
            double x1 = pt1.getDataPoint().getXData();
            double x2 = pt2.getDataPoint().getXData();
            int cmp = Double.compare(x1, x2);
            if (cmp != 0)
              return cmp;
            // Second, compare the data sets.
            if (pt1.getDataSet() == pt2.getDataSet())
              return 0;
            int dataSetIndex1 = pt1.getRenderer().getDataSetIndex(pt1.getDataSet());
            int dataSetIndex2 = pt2.getRenderer().getDataSetIndex(pt2.getDataSet());
            return dataSetIndex1 - dataSetIndex2;
          } else {
            return 1;
          }
        } else {
          if (element2 instanceof IlvAccessibleDataPoint) {
            return -1;
          } else {
            return region1.compareTo(region2);
          }
        }
      }
    });
    inversePermutation = new int[count];
    for (int i = 0; i < count; i++)
      inversePermutation[permutation[i].intValue() - 1] = i;
  }

  Override
  public IlvNavigationInfo getNavigationInfo(int region, IlvChartAreaAccessible element) {
    int count = permutation.length;
    int i = inversePermutation[region - 1];
    int prev_i = (i == 0 ? count - 1 : i - 1);
    int next_i = (i == count - 1 ? 0 : i + 1);
    int prev_region = permutation[prev_i].intValue();
    int next_region = permutation[next_i].intValue();
    return new IlvNavigationInfo(prev_region, next_region);
  }
}