/**
   * Class constructor.
   *
   * @param id current id
   * @param timeStart starting time
   * @param timeEnd ending time
   * @param text text
   * @throws SubtitleObjectException Thrown if timeStart is greater than timeEnd.
   */
  public SubtitleObject(int id, TimeHolder timeStart, TimeHolder timeEnd, String text)
      throws SubtitleObjectException {
    this.id = id;
    this.timeStart = timeStart;
    this.timeEnd = timeEnd;
    this.text = text;
    this.originalText = RemoveEndingCharacter.fix(text, '<', '>', null);
    this.splitMap = new SplitMap();

    if (timeStart != null && timeStart.calcTotalTimeMs() > timeEnd.calcTotalTimeMs()) {
      throw new SubtitleObjectException(
          String.format(
              "[ID: %s] Start time is greater than end time. (%s > %s)", id, timeStart, timeEnd));
    }
  }
  /** Apply fixes to text. */
  public void fix() {
    if (text == null || text.isEmpty()) {
      return;
    }
    text = text.trim();
    text = RemoveEmpty.fix(text, this);
    if (text.isEmpty()) {
      return;
    }

    // TODO: comment this

    text = RemoveEndingCharacter.fix(text, '<', '>', this);
    text = RemoveEndingCharacter.fix(text, '{', '}', this);
    text = RemoveEndingCharacter.fix(text, '[', ']', this);
    if (ManuelFix.MANUEL_FIX.containsKey(text)) {
      text = ManuelFix.MANUEL_FIX.get(text);
      return;
    } else if (DoNotFix.DO_NOT_FIX.contains(text)) {
      return;
    }

    if (text.startsWith("#") && !text.endsWith("#")) {
      text += " #";
    }
    text = RemoveEndingCharacter.fix(text, '(', ')', this);
    text = FixNonTraditionalStrings.fix(text, this);

    // TODO: messy (see "...with the .22?")
    if (text.startsWith("-") && !text.startsWith("- ")) {
      text = "- " + text.substring(1);
      splitMap.clear(); // TODO: clean up
    }
    text = FixEllipses.fix(text, this);
    text = FixSingleDoubleQuotes.fix(text, this);

    String result = "";
    int removedNames = 0;
    String originalText = text;

    text = FixUnbalancedDashes.fix(text);
    boolean fixedUnbalancedDashes = !originalText.equals(text);

    if (!text.startsWith("-")) {
      // text = text.replace("\n", " "); // TODO: explain this
    }

    String temp;
    for (String line : RegexUtil.split(RegexEnum.NEWLINE, text)) { // TODO: if contains punctuation
      line = line.trim();
      splitMap.clear();
      line = PrepareLine.fix(line, this);
      split(RegexEnum.SPACE, line);
      temp = line;
      line = RemoveCharacterName.fix(line, this);
      if (!temp.equals(line)) {
        ++removedNames;
      }
      line = FixSpelling.fix(line, this);
      if (!SrtFixerConfig.isToggleCorrectCapitalization()) {
        line =
            FixToUppercase.fix(
                line, this); // TODO: remove this once all bugs in FixCapitalization is fixed
      }
      line = ChangeLsToIs.fix(line, this);
      line = FixDashes.fix(line, this);
      line = RemoveEmpty.fix(line, this);
      if (SrtFixerConfig.isToggleCorrectCapitalization()) {
        line = FixCapitalization.fix(line, this);
      }
      line = FixAmpersand.fix(line, this);
      line = FixHeight.fix(line, this);
      line = FixWebsites.fix(line, this);
      line = FixTime.fix(line, this);
      line = FixNumbers.fix(line, this);
      line = FixAbbreviations.fix(line, this);
      line = FixContractions.fix(line, this);
      line = FixAcronym.fix(line, this);
      line = FixLetterS.fix(line, this);
      line = FixMisplacedQuotes.fix(line, this);
      line = FixSpacing.fix(line, this);
      line = FixCommonErrors.fix(line, this);
      line = FixEnding.fix(line, this);

      if (!line.isEmpty()) {
        line = FixMultilineDashes.fix(result, line); // TODO: why doesn't this work???
        if (!result.isEmpty()) {
          result = FixMultilineDashes.fix(line, result);
        }
        StringBuilder builder = new StringBuilder();
        if (removedNames == 2) {
          builder.append("- ");
          builder.append(result);
          builder.append("- ");
          builder.append(line);
          result = builder.toString();
          continue;
        }
        builder.append(result);
        builder.append(line);
        builder.append('\n');
        result = builder.toString();
      }
    }

    result = FixEllipses.fix(result, this);
    result = result.trim();

    result = FixMultilineQuotes.fix(result, this);

    result = FixThreeLines.fix(result);
    result = FixTwoLines.fix(result);
    result = FixOneLine.fix(result);

    if (StringUtil.count(originalText, '\n') <= 1
        && SubtitleUtil.isApproximatelyEqual(result, originalText)
        && !fixedUnbalancedDashes) {
      result = originalText;
    }

    text = result;
  }