/** Scrolls the window to the start/end of the next annotation to the right. */
  public void nextAnnotation() {
    int basepair = getVisibleBase();
    if (getType().equals("AA")) {
      basepair += 3 * getAnnotationPanel().getStrand().toInt();
    }
    int position =
        getAnnotationPanel()
            .tierPositionToPixelPosition(getAnnotationPanel().basePairToTierPosition(basepair));
    SeqFeatureI feature = getAnnotationPanel().getNextFeature(position);

    if (feature != null) {

      if (getAnnotationPanel().getOrientation() == Orientation.FIVE_TO_THREE) {
        scrollToBase(feature.getStart());
      } else {
        scrollToBase(feature.getEnd());
      }

      AnnotatedFeatureI selection = null;
      if (feature instanceof AnnotatedFeatureI) {
        selection = getTransOrOneLevelAnn((AnnotatedFeatureI) feature);
      }

      if (selection != null
          && selection.isTranscript()
          && ((Transcript) selection).haveWholeSequence()) {
        setSelection((AnnotatedFeatureI) feature);
        getCurationState().getSelectionManager().select(feature, this);
      } else if (selection != null && selection != getSelection()) {
        nextAnnotation();
      }
    }
  }
 /**
  * AssemblyFeature is the only GAI at the moment that has no relation to // a transcript. Dont
  * think they can end up in ede (??). // Would be nice to have an interface that was solely for
  * the exon // trans gene heirarchy? Should we actively make sure AssemblyFeatures dont // get
  * into ede? (filter in AnnotationMenu?) returns null if no transcript can be found.
  */
 private AnnotatedFeatureI getTransOrOneLevelAnn(AnnotatedFeatureI af) {
   if (af != null) {
     if (af.isTranscript()) return af;
     if (af.isExon()) return af.getRefFeature().getAnnotatedFeature();
     if (af.isAnnotTop()) {
       if (af.hasKids()) return af.getFeatureAt(0).getAnnotatedFeature(); // transcript
       else // 1 level annot
       return af;
     }
   }
   return null;
 }
  /** Scrolls the window to the start/end of the next annotation to the left */
  public void prevAnnotation() {
    int basepair = getVisibleBase();
    int offset = getType().equals("AA") ? 3 : 1;
    basepair += (getVisibleBaseCount() - offset) * getStrand().toInt();

    int position =
        getAnnotationPanel()
            .tierPositionToPixelPosition(getAnnotationPanel().basePairToTierPosition(basepair));

    SeqFeatureI feature = getAnnotationPanel().getPrevFeature(position);

    if (feature != null) {

      // get highest pixel position
      position = getAnnotationPanel().getHigh(feature);

      position =
          getType().equals("AA")
              ? position - (getVisibleBaseCount() / 3)
              : position - getVisibleBaseCount();
      position = getAnnotationPanel().pixelPositionToTierPosition(position);
      int bp = getAnnotationPanel().tierPositionToBasePair(position);
      scrollToBase(bp);

      AnnotatedFeatureI selection = null;
      if (feature instanceof AnnotatedFeatureI) {
        selection = getTransOrOneLevelAnn((AnnotatedFeatureI) feature);
      }

      if (selection != null
          && selection.isTranscript()
          && ((Transcript) selection).haveWholeSequence()) {

        setSelection((AnnotatedFeatureI) feature);
        getCurationState().getSelectionManager().select(feature, this);
      } else if (selection != null && selection != getSelection()) {
        prevAnnotation();
      }
    }
  }
  /**
   * Display AnnotatedFeatureI feature. Exon, Transcript, and Gene are all GenericAnnotationI. No
   * selection event is fired. (selectAnnot fires and displays)
   */
  private void displayAnnot(AnnotatedFeatureI annot) {
    currentAnnot = annot;
    if (currentAnnot == null) {
      transcriptComboBox.removeAllItems();
      transcriptComboBox.addItem("<no feature selected>");
      lengthLabel.setText("Translation length: <no feature selected>");
      upstream_button.setLabel("");
      downstream_button.setLabel("");
      translationViewer.setTranscript(null, editorPanel.getSelectedTier()); // ??
      return;
    }

    // else {
    setupTranscriptComboBox(currentAnnot);

    SeqFeatureI topAnnot = currentAnnot;
    if (topAnnot.isTranscript()) topAnnot = currentAnnot.getRefFeature();
    if (topAnnot.isProteinCodingGene()) {
      String translation = currentAnnot.translate();
      if (translation == null) {
        lengthLabel.setText("Translation length: <no start selected>");
      } else {
        lengthLabel.setText("Translation length: " + currentAnnot.translate().length());
      }
    } else {
      lengthLabel.setText(topAnnot.getFeatureType() + " annotation");
    }
    FeatureSetI holder = (FeatureSetI) topAnnot.getRefFeature();
    neighbor_up = null;
    neighbor_down = null;
    if (holder != null) {

      int index = holder.getFeatureIndex(topAnnot);
      // get next neighbor up that has whole sequence
      for (int i = index - 1; i >= 0 && neighbor_up == null; i--) {
        FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i);
        if (gene_sib.getFeatureAt(0) instanceof Transcript) {
          Transcript trans = (Transcript) gene_sib.getFeatureAt(0);
          if (trans.haveWholeSequence()) // szap.getCurationSet()))
          neighbor_up = trans;
        }
      }

      // get next neighbor down that has whole sequence
      for (int i = index + 1; i < holder.size() && neighbor_down == null; i++) {
        FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i);
        if (gene_sib.getFeatureAt(0) instanceof Transcript) {
          Transcript trans = (Transcript) gene_sib.getFeatureAt(0);
          if (trans.haveWholeSequence()) // szap.getCurationSet()))
          neighbor_down = trans;
        }
      }
    }
    upstream_button.setLabel(
        neighbor_up == null
            ? ""
            : "Go to next 5' annotation (" + neighbor_up.getParent().getName() + ")");
    upstream_button.setVisible(neighbor_up != null);
    downstream_button.setLabel(
        neighbor_down == null
            ? ""
            : "Go to next 3' annotation (" + neighbor_down.getParent().getName() + ")");
    downstream_button.setVisible(neighbor_down != null);
    // }
    // todo - translationViewer take in 1 level annot
    if (currentAnnot.isTranscript())
      translationViewer.setTranscript((Transcript) currentAnnot, editorPanel.getSelectedTier());
  }