/**
   * Called when either the state of the partitions has changed, or when the user has clicked on the
   * 'Use Partitions..' box. Either way, we recalculate the series data here to reflect the change
   */
  public void partitionStateChanged(Partitionable source, PartitionChangeType type) {
    if (type == PartitionChangeType.NEW_PARTITION) {
      usePartitionsBox.setEnabled(true);
      if (usePartitionsBox.isSelected()) repaintAllSeries();
    }
    if (type == PartitionChangeType.PARTITIONS_CLEARED) {
      // Do all sg's have no partitions? If so, set the box to disabled
      int max = 0;
      for (SequenceGroup sg : sgSeriesMap.keySet()) {
        if (max < sg.getPartitionCount()) max = sg.getPartitionCount();
      }
      if (max < 2) usePartitionsBox.setEnabled(false);

      repaintAllSeries();
    }
  }
  /**
   * Uses the calculator with name calcName to construct & display a series for the sg. This should
   * be the only way new series' are added to the chart, since we need to keep track of all the
   * current series in the sgSeriesMap
   *
   * @param calcName
   * @param sg
   */
  protected void addSeriesForSG(String calcName, SequenceGroup sg) {
    BaseCounter calc = null;
    try {
      calc = sgReg.getBaseCounterInstance(calcName, sg);
    } catch (IllegalArgumentException ex) {
      System.err.println("Could not find base counter of type : " + calcName);
      return;
    }

    List<AbstractSeries> seriesList = sgSeriesMap.get(sg);

    if (seriesList == null) {
      System.out.println(
          "Uh-oh, this sequence group doesn't have an associated list in the sgSeriesMap...");
    }

    // Make a new series from the calculator
    int windowsize = ((Integer) windowSizeSpinner.getValue()).intValue();
    int windowStep = ((Integer) windowStepSpinner.getValue()).intValue();

    if (usePartitionsBox.isSelected()) {
      for (int i = 0; i < sg.getPartitionCount(); i++) {
        BaseCounterSeries ser = calc.getWindowSeries(windowsize, windowStep, i);
        ser.setPartitionIndex(i);
        seriesList.add(ser);
        ser.setName(calc.getName() + " - " + sg.getPartitionKeyForIndex(i));
        if (ser != null && ser.size() > 0) {
          chart.addDataSeries(ser);
          chart.repaint();
        }
      }

    } else {
      BaseCounterSeries ser = calc.getWindowSeries(windowsize, windowStep);
      seriesList.add(ser);
      if (sgSeriesMap.size() > 1) {
        String name = sg.getName();
        if (name == null) {
          ser.setName(calc.getName());
        } else {
          ser.setName(calc.getName() + " - " + sg.getName());
        }
      }
      if (ser != null && ser.size() > 0) {
        chart.addDataSeries(ser);
        chart.repaint();
      }
    }
  }
  public void analyze(String name, Object data) {
    if (data.getClass() != SequenceGroup.class) {
      ErrorWindow.showErrorWindow(
          new IllegalArgumentException(
              "Got a incompatible data type for SequenceLineChart: " + data.getClass()));
      return;
    }

    SequenceGroup currentSG = (SequenceGroup) data;
    originalSG = currentSG;
    originalSG.addPartitionListener(this);
    originalSG.addSGChangeListener(this);
    sgSeriesMap.put((SequenceGroup) data, new ArrayList<AbstractSeries>());
    currentName = name;
    if (topLabel != null) topLabel.setText(currentName);
    else topLabel = new JLabel(currentName);

    topLabel.setFont(defaultFont);

    int maxLength = currentSG.getMaxSeqLength();

    // Guess some decent initial values for size of window and step
    int windowSize = Math.min(100, maxLength);
    int windowStep = maxLength > 50 ? 10 : 1;
    if (maxLength > 9999) {
      windowSize = 1000;
      windowStep = 100;
    }

    SpinnerModel sizeModel = new SpinnerNumberModel(windowSize, 1, maxLength, 1);
    SpinnerModel stepModel = new SpinnerNumberModel(windowStep, 1, maxLength / 2, 1);

    windowSizeSpinner.setModel(sizeModel);
    windowStepSpinner.setModel(stepModel);

    if (currentSG.getPartitionCount() < 2) {
      usePartitionsBox.setSelected(false);
      usePartitionsBox.setEnabled(false);
    } else {
      usePartitionsBox.setEnabled(true);
      usePartitionsBox.setSelected(true);
    }

    toggleCalculator(SGStatisticsRegistry.NUC_DIVERSITY);
    chart.repaint();
  }