/**
   * 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();
      }
    }
  }
  /**
   * Called when one of the sliding window size or step values has changed. This attempts to be
   * 'smart' and instead of recalculating everything from scratch,
   */
  private void newWindowSizeAction() {
    if (sgSeriesMap == null) return;

    XYSeries data;
    int windowSize = (Integer) windowSizeSpinner.getValue();
    int windowStep = (Integer) windowStepSpinner.getValue();
    int tot = 0;

    for (AbstractSeries series : chart.getAllSeries()) {
      if (series instanceof BaseCounterSeries) {
        BaseCounterSeries bcSer = (BaseCounterSeries) series;
        BaseCounter bc = bcSer.getCalculator();
        int partitionIndex = bcSer.getPartitionIndex();
        // System.out.println("Replacing series for calc with name : " + bcSer.getName() + " and
        // partition : " + bcSer.getPartitionIndex());
        if (partitionIndex > -1) {
          bcSer.replaceSeries(bc.getWindowPointSeries(windowSize, windowStep, partitionIndex));
        } else bcSer.replaceSeries(bc.getWindowPointSeries(windowSize, windowStep));
      } else {
        // System.err.println("Hmm, one of the series (" + series.getName() + ") is not a
        // basecounter, cannot recalculate it for the new window size.");/
      }
    }

    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();
  }