/* Establish the currentRange of bases covered by the
    currentFeature of this renderer
 */
 public double[] establishRange(SeqFeatureI sf, int pos, int tier, boolean use_set) {
   double range[];
   if (sf == null || (!use_set && (sf.canHaveChildren()))) {
     range = baseEditor.getRangeAtPosition(tier, pos);
   } else {
     range = new double[2];
     range[0] = (double) baseEditor.basePairToPos(sf.getLow());
     range[1] = (double) baseEditor.basePairToPos(sf.getHigh());
   }
   return range;
 }
  /**
   * Get component to be rendered, if pos outside of current range getFeatureAtPosition and reset
   * currentRange, if feature is non null and not an instance of FeatureSetI then its an exon, and
   * set isExon flag
   */
  public Component getBaseRendererComponent(char base, int pos, int tier, SequenceI seq) {
    init(base, pos, tier, seq);

    hatchColor = null;
    if (((BaseEditorPanel) baseEditor).getShowHitZones()) {
      Vector hitZones = ((BaseEditorPanel) baseEditor).hitZones;

      for (int hitIndex = 0; hitIndex < hitZones.size(); hitIndex++) {
        int[] hitZone = (int[]) hitZones.elementAt(hitIndex);

        if (pos >= hitZone[0] && pos < hitZone[1]) {
          hatchColor = Color.yellow;
          break;
        }
      }
    }

    currentFeature = baseEditor.getFeatureAtPosition(pos, tier);
    double[] range = establishRange(currentFeature, pos, tier, false);

    if (range[1] != currentRange[1] || range[0] != currentRange[0]) {
      currentRange[0] = range[0];
      currentRange[1] = range[1];

      currentFeatureSet = baseEditor.getFeatureSetAtPosition(pos, tier);
      range = establishRange(currentFeatureSet, pos, tier, true);
      transcriptRange[0] = range[0];
      transcriptRange[1] = range[1];

      if (currentFeature != null) {
        // This decides the index into the color array, transcripts
        // can have different colors for their features
        transcriptColorIndex =
            (baseEditor.getRangeIndex(tier, (int) currentRange[0], (int) currentRange[1]))
                % transcriptColorList.length;
        exonColorIndex =
            (baseEditor.getExonRangeIndex(tier, (int) currentRange[0], (int) currentRange[1]))
                % transcriptColorList[transcriptColorIndex].length;
      }
      if (currentFeature == null) {
        isExon = false;
        isIntron = false;
        // } else if (currentFeature.canHaveChildren()) {
      } else if (currentFeature.hasKids()) { // 1 level annots can but dont
        isExon = false;
        isIntron = true;
      } else {
        isExon = true;
        isIntron = false;
      }
    }
    return this;
  }
 /**
  * Checks if selected or selected refs feature is the feature set at current pos, so an exon as
  * well as a transcript will have an outline color
  */
 public Color getOutlineColor() {
   SeqFeatureI selected = null;
   if (baseEditor instanceof BaseEditorPanel) {
     selected = ((BaseEditorPanel) baseEditor).getSelectedFeature();
   }
   FeatureSetI featureSet = baseEditor.getFeatureSetAtPosition(pos, tier);
   if (featSetContainsFeat(featureSet, selected)) return Color.magenta;
   else return null;
 }
  public Color getBackgroundBoxColor() {
    if (pos == targetNucleotide && tier == targetTier) return targetColor;
    int lowSeqSelect;
    int highSeqSelect;
    if (baseEditor instanceof BaseEditorPanel) {
      lowSeqSelect = ((BaseEditorPanel) baseEditor).selectLowPos();
      highSeqSelect = ((BaseEditorPanel) baseEditor).selectHighPos();
    } else {
      lowSeqSelect = -1;
      highSeqSelect = -1;
    }

    if (lowSeqSelect != -1 && highSeqSelect != -1 && pos >= lowSeqSelect && pos <= highSeqSelect) {
      return seqSelectColor;
    }

    int basePos = baseEditor.posToBasePair(pos);

    if (((BaseEditorPanel) baseEditor).isSequencingErrorPosition(basePos)) return shiftColor;

    if (isExon) {
      ExonI exon = null;
      if (currentFeature instanceof ExonI) exon = (ExonI) currentFeature;
      else if (currentFeature instanceof DrawableSeqFeature)
        exon = (ExonI) ((DrawableSeqFeature) currentFeature).getFeature();
      if (exon != null && exon.getTranscript() != null) {
        Transcript transcript = exon.getTranscript();
        int tss = (int) exon.getTranscript().getTranslationStart();
        if (basePos == tss
            || basePos == (tss + exon.getStrand())
            || basePos == (tss + (2 * exon.getStrand())))
          return DrawableUtil.getStartCodonColor(transcript);
        else {
          int tes = (int) transcript.getTranslationEnd();
          if (basePos == tes
              || basePos == (tes + exon.getStrand())
              || basePos == (tes + (2 * exon.getStrand()))) return Color.red;
          else {
            int shift_pos = (int) transcript.plus1FrameShiftPosition();
            if (basePos == shift_pos) return shiftColor;
            else {
              shift_pos = (int) transcript.minus1FrameShiftPosition();
              if (basePos == shift_pos) return shiftColor;
              else {
                int stop_pos = (int) transcript.readThroughStopPosition();
                if (basePos == stop_pos
                    || basePos == (stop_pos + exon.getStrand())
                    || basePos == (stop_pos + (2 * exon.getStrand()))) return Color.pink;
              }
            }
          }
        }
      }
      return transcriptColorList[transcriptColorIndex][exonColorIndex];
    }
    return null;
  }