// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// @dart = 2.9

part of view;

// TODO(jacobr): handle splitting lines on symbols such as '-' that aren't
// whitespace but are valid word breaking points.
/// Utility class to efficiently word break and measure text without requiring
/// access to the DOM.
class MeasureText {
  static CanvasRenderingContext2D _context;

  final String font;
  num _spaceLength;
  num _typicalCharLength;

  static const String ELLIPSIS = '...';

  MeasureText(this.font) {
    if (_context == null) {
      CanvasElement canvas = Element.tag('canvas');
      _context = canvas.getContext('2d');
    }
    if (_spaceLength == null) {
      _context.font = font;
      _spaceLength = _context.measureText(' ').width;
      _typicalCharLength = _context.measureText('k').width;
    }
  }

  // TODO(jacobr): we are DOA for i18N...
  // the right solution is for the server to send us text perparsed into words
  // perhaps even with hints on the guess for the correct breaks so on the
  // client all we have to do is verify and fix errors rather than perform the
  // full calculation.
  static bool isWhitespace(String character) {
    return character == ' ' || character == '\t' || character == '\n';
  }

  num get typicalCharLength {
    return _typicalCharLength;
  }

  String quickTruncate(String text, num lineWidth, int maxLines) {
    int targetLength = lineWidth * maxLines ~/ _typicalCharLength;
    // Advance to next word break point.
    while (targetLength < text.length && !isWhitespace(text[targetLength])) {
      targetLength++;
    }

    if (targetLength < text.length) {
      return '${text.substring(0, targetLength)}$ELLIPSIS';
    } else {
      return text;
    }
  }

  /// Add line broken text as html separated by <br> elements.
  /// Returns the number of lines in the output.
  /// This function is safe to call with [:sb == null:] in which case just the
  /// line count is returned.
  int addLineBrokenText(
      StringBuffer sb, String text, num lineWidth, int maxLines) {
    // Strip surrounding whitespace. This ensures we create zero lines if there
    // is no visible text.
    text = text.trim();

    // We can often avoid performing a full line break calculation when only
    // the number of lines and not the actual linebreaks is required.
    if (sb == null) {
      _context.font = font;
      int textWidth = _context.measureText(text).width.toInt();
      // By the pigeon hole principle, the resulting text will require at least
      // maxLines if the raw text is longer than the amount of text that will
      // fit on maxLines - 1.  We add the length of a whitespace
      // character to the lineWidth as each line is separated by a whitespace
      // character. We assume all whitespace characters have the same length.
      if (textWidth >= (lineWidth + _spaceLength) * (maxLines - 1)) {
        return maxLines;
      } else if (textWidth == 0) {
        return 0;
      } else if (textWidth < lineWidth) {
        return 1;
      }
      // Fall through to the regular line breaking calculation as the number
      // of lines required is unclear.
    }
    int lines = 0;
    lineBreak(text, lineWidth, maxLines, (int start, int end, num width) {
      lines++;
      if (lines == maxLines) {
        // Overflow case... there may be more lines of text than we can handle.
        // Add a few characters to the last line so that the browser will
        // render ellipses correctly.
        // TODO(jacobr): make this optional and only add characters until
        // the first whitespace character encountered.
        end = Math.min(end + 50, text.length);
      }
      if (sb != null) {
        if (lines > 1) {
          sb.write('<br>');
        }
        // TODO(jacobr): HTML escape this text.
        sb.write(text.substring(start, end));
      }
    });
    return lines;
  }

  void lineBreak(String text, num lineWidth, int maxLines, Function callback) {
    _context.font = font;
    int lines = 0;
    num currentLength = 0;
    int startIndex = 0;
    int wordStartIndex;
    int lastWordEndIndex;
    bool lastWhitespace = true;
    // TODO(jacobr): optimize this further.
    // To simplify the logic, we simulate injecting a whitespace character
    // at the end of the string.
    for (int i = 0, len = text.length; i <= len; i++) {
      // Treat the char after the end of the string as whitespace.
      bool whitespace = i == len || isWhitespace(text[i]);
      if (whitespace && !lastWhitespace) {
        num wordLength =
            _context.measureText(text.substring(wordStartIndex, i)).width;
        // TODO(jimhug): Replace the line above with this one to workaround
        //               dartium bug - error: unimplemented code
        // num wordLength = (i - wordStartIndex) * 17;
        currentLength += wordLength;
        if (currentLength > lineWidth) {
          // Edge case:
          // It could be the very first word we ran into was too long for a
          // line in which case  we let it have its own line.
          if (lastWordEndIndex != null) {
            lines++;
            callback(startIndex, lastWordEndIndex, currentLength - wordLength);
          }
          if (lines == maxLines) {
            return;
          }
          startIndex = wordStartIndex;
          currentLength = wordLength;
        }
        lastWordEndIndex = i;
        currentLength += _spaceLength;
        wordStartIndex = null;
      } else if (wordStartIndex == null && !whitespace) {
        wordStartIndex = i;
      }
      lastWhitespace = whitespace;
    }
    if (currentLength > 0) {
      callback(startIndex, text.length, currentLength);
    }
  }
}
