// 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.

part of layout;

/**
 * Base class for simple recursive descent parsers.
 * Handles the lower level stuff, i.e. what a scanner/tokenizer would do.
 */
class _Parser {
  static const WHITESPACE = ' \r\n\t';

  // TODO(jmesserly): shouldn't need this optimization, but dart_json parser
  // found that they needed this.
  static const A_BIG = 65;  // 'A'.codeUnitAt(0)
  static const Z_BIG = 90;  // 'Z'.codeUnitAt(0)
  static const A_SMALL = 97;  // 'a'.codeUnitAt(0)
  static const Z_SMALL = 122;  // 'z'.codeUnitAt(0)
  static const TAB = 9;  // '\t'.codeUnitAt(0)
  static const NEW_LINE = 10;  // '\n'.codeUnitAt(0)
  static const LINE_FEED = 13;  // '\r'.codeUnitAt(0)
  static const SPACE = 32;  // ' '.codeUnitAt(0)
  static const ZERO = 48;  // '0'.codeUnitAt(0)
  static const NINE = 57;  // '9'.codeUnitAt(0)
  static const DOT = 46;  // '.'.codeUnitAt(0)
  static const R_PAREN = 41;  // ')'.codeUnitAt(0)

  final String _src;
  int _offset;

  // TODO(jmesserly): should be this._offset = 0, see bug 5332175.
  _Parser(this._src) : _offset = 0;

  // TODO(jmesserly): these should exist in the standard lib.
  // I took this from dart_json.dart
  static bool _isWhitespace(int c) {
    switch (c) {
      case SPACE:
      case TAB:
      case NEW_LINE:
      case LINE_FEED:
        return true;
    }
    return false;
  }

  static bool _isDigit(int c) {
    return (ZERO <= c) && (c <= NINE);
  }

  static bool _isLetter(int c) {
    return (A_SMALL <= c) && (c <= Z_SMALL) || (A_BIG <= c) && (c <= Z_BIG);
  }

  void _error(String msg) {
    throw new SyntaxErrorException(msg, _src, _offset);
  }

  int get length => _src.length;

  int get remaining => _src.length - _offset;

  int _peekChar() => _src.codeUnitAt(_offset);

  bool get endOfInput => _offset >= _src.length;

  bool _maybeEatWhitespace() {
    int start = _offset;
    while (_offset < length && _isWhitespace(_peekChar())) {
      _offset++;
    }
    return _offset != start;
  }

  bool _maybeEatMultiLineComment() {
    if (_maybeEat('/*', /*eatWhitespace:*/false)) {
      while (!_maybeEat('*/', /*eatWhitespace:*/false)) {
        if (_offset >= length) {
          _error('expected */');
        }
        _offset++;
      }
      return true;
    }
    return false;
  }

  void _maybeEatWhitespaceOrComments() {
    while (_maybeEatWhitespace() || _maybeEatMultiLineComment()) {}
  }

  void _eatEnd() {
    _maybeEatWhitespaceOrComments();
    if (!endOfInput) {
      _error('expected end of input');
    }
  }

  bool _maybeEat(String value, [bool eatWhitespace = true]) {
    if (eatWhitespace) {
      _maybeEatWhitespaceOrComments();
    }
    if (remaining < value.length) {
      return false;
    }
    for (int i = 0; i < value.length; i++) {
      if (_src[_offset + i] != value[i]) {
        return false;
      }
    }

    // If we're eating something that's like a word, make sure
    // it's not followed by more characters.
    // This is ugly. Proper tokenization would make this cleaner.
    if (_isLetter(value.codeUnitAt(value.length - 1))) {
      int i = _offset + value.length;
      if (i < _src.length && _isLetter(_src.codeUnitAt(i))) {
        return false;
      }
    }

    _offset += value.length;
    return true;
  }

  void _eat(String value, [bool eatWhitespace = true]) {
    if (!_maybeEat(value)) {
      _error('expected "$value"');
    }
  }

  String _maybeEatString() {
    // TODO(jmesserly): make this match CSS string parsing
    String quote = "'";
    if (!_maybeEat(quote)) {
      quote = '"';
      if (!_maybeEat(quote)) {
        return null;
      }
    }

    bool hasEscape = false;
    int start = _offset;
    while (!_maybeEat(quote)) {
      if (endOfInput) {
        _error('expected "$quote"');
      }
      if (_maybeEat('\\')) {
        hasEscape = true;
      }
      _offset++;
    }
    String result = _src.substring(start, _offset - 1);
    if (hasEscape) {
      // TODO(jmesserly): more escape sequences
      result = result.replaceFirst('\\', '');
    }
    return result;
  }

  /** Eats something like a keyword. */
  String _eatWord() {
    int start = _offset;
    while (_offset < length && _isLetter(_peekChar())) {
      _offset++;
    }
    return _src.substring(start, _offset);
  }

  /** Eats an integer. */
  int _maybeEatInt() {
    int start = _offset;
    bool dot = false;
    while (_offset < length && _isDigit(_peekChar())) {
      _offset++;
    }

    if (start == _offset) {
      return null;
    }

    return int.parse(_src.substring(start, _offset));
  }

  /** Eats an integer. */
  int _eatInt() {
    int result = _maybeEatInt();
    if (result == null) {
      _error('expected positive integer');
    }
    return result;
  }

  /** Eats something like a positive decimal: 12.345. */
  num _eatDouble() {
    int start = _offset;
    bool dot = false;
    while (_offset < length) {
      int c = _peekChar();
      if (!_isDigit(c)) {
        if (c == DOT && !dot) {
          dot = true;
        } else {
          // Not a digit or decimal seperator
          break;
        }
      }
      _offset++;
    }

    if (start == _offset) {
      _error('expected positive decimal number');
    }

    return double.parse(_src.substring(start, _offset));
  }
}

/** Parses a grid template. */
class _GridTemplateParser extends _Parser {
  _GridTemplateParser._internal(String src) : super(src);

  /** Parses the grid-rows and grid-columns CSS properties into object form. */
  static GridTemplate parse(String str) {
    if (str == null) return null;
    final p = new _GridTemplateParser._internal(str);
    final result = p._parseTemplate();
    p._eatEnd();
    return result;
  }

  /** Parses a grid-cell value. */
  static String parseCell(String str) {
    if (str == null) return null;
    final p = new _GridTemplateParser._internal(str);
    final result = p._maybeEatString();
    p._eatEnd();
    return result;
  }

  // => <string>+ | 'none'
  GridTemplate _parseTemplate() {
    if (_maybeEat('none')) {
      return null;
    }
    final rows = new List<String>();
    String row;
    while ((row = _maybeEatString()) != null) {
      rows.add(row);
    }
    if (rows.length == 0) {
      _error('expected at least one cell, or "none"');
    }
    return new GridTemplate(rows);
  }
}

/** Parses a grid-row or grid-column */
class _GridItemParser extends _Parser {
  _GridItemParser._internal(String src) : super(src);

  /** Parses the grid-rows and grid-columns CSS properties into object form. */
  static _GridLocation parse(String cell, GridTrackList list) {
    if (cell == null) return null;
    final p = new _GridItemParser._internal(cell);
    final result = p._parseTrack(list);
    p._eatEnd();
    return result;
  }

  // [ [ <integer> | <string> | 'start' | 'end' ]
  //   [ <integer> | <string> | 'start' | 'end' ]? ]
  // | 'auto'
  _GridLocation _parseTrack(GridTrackList list) {
    if (_maybeEat('auto')) {
      return null;
    }
    int start = _maybeParseLine(list);
    if (start == null) {
      _error('expected row/column number or name');
    }
    int end = _maybeParseLine(list);
    int span = null;
    if (end != null) {
      span = end - start;
      if (span <= 0) {
        _error('expected row/column span to be a positive integer');
      }
    }
    return new _GridLocation(start, span);
  }

  // [ <integer> | <string> | 'start' | 'end' ]
  int _maybeParseLine(GridTrackList list) {
    if (_maybeEat('start')) {
      return 1;
    } else if (_maybeEat('end')) {
      // The end is exclusive and 1-based, so return one past the size of the
      // track list.
      // TODO(jmesserly): this won't interact properly with implicit
      // rows/columns. Instead it will snap to the number of tracks at the point
      // where it is evaluated.
      return list.tracks.length + 1;
    }

    String name = _maybeEatString();
    if (name == null) {
      return _maybeEatInt();
    } else {
      int edge = list.lineNames[name];
      if (edge == null) {
        _error('row/column name "$name" not found in the parent\'s '
            ' grid-row/grid-columns properties');
      }
      return edge;
    }
  }
}

/**
 * Parses grid-rows and grid-column properties, see:
 * [http://dev.w3.org/csswg/css3-grid-align/#grid-columns-and-rows-properties]
 * This is kept as a recursive descent parser for simplicity.
 */
// TODO(jmesserly): implement missing features from the spec. Mainly around
// CSS units, support for all escape sequences, etc.
class _GridTrackParser extends _Parser {
  final List<GridTrack> _tracks;
  final Map<String, int> _lineNames;

  _GridTrackParser._internal(String src)
    : super(src),
      _tracks = new List<GridTrack>(),
      _lineNames = new Map<String, int>();

  /** Parses the grid-rows and grid-columns CSS properties into object form. */
  static GridTrackList parse(String str) {
    if (str == null) return null;
    final p = new _GridTrackParser._internal(str);
    final result = p._parseTrackList();
    p._eatEnd();
    return result;
  }

  /**
   * Parses the grid-row-sizing and grid-column-sizing CSS properties into
   * object form.
   */
  static TrackSizing parseTrackSizing(String str) {
    if (str == null) str = 'auto';
    final p = new _GridTrackParser._internal(str);
    final result = p._parseTrackMinmax();
    p._eatEnd();
    return result;
  }

  // <track-list> => [ [ <string> ]* <track-group> [ <string> ]* ]+ | 'none'
  GridTrackList _parseTrackList() {
    if (_maybeEat('none')) {
      return null;
    }
    _parseTrackListHelper();
    return new GridTrackList(_tracks, _lineNames);
  }

  /** Code shared by _parseTrackList and _parseTrackGroup */
  void _parseTrackListHelper([List<GridTrack> resultTracks = null]) {
    _maybeEatWhitespace();
    while (!endOfInput) {
      String name;
      while ((name = _maybeEatString()) != null) {
        _lineNames[name] = _tracks.length + 1; // should be 1-based
      }

      _maybeEatWhitespace();
      if (endOfInput) {
        return;
      }

      if (resultTracks != null) {
        if (_peekChar() == _Parser.R_PAREN) {
          return;
        }
        resultTracks.add(new GridTrack(_parseTrackMinmax()));
      } else {
        _parseTrackGroup();
      }

      _maybeEatWhitespace();
    }
  }

  // <track-group> => [ '(' [ [ <string> ]* <track-minmax> [ <string> ]* ]+ ')'
  //                     [ '[' <positive-number> ']' ]? ]
  //                  | <track-minmax>
  void _parseTrackGroup() {
    if (_maybeEat('(')) {
      final tracks = new List<GridTrack>();
      _parseTrackListHelper(tracks);
      _eat(')');
      if (_maybeEat('[')) {
        num expand = _eatInt();
        _eat(']');

        if (expand <= 0) {
          _error('expected positive number');
        }

        // Repeat the track definition (but not the names) the specified number
        // of times. See:
        // http://dev.w3.org/csswg/css3-grid-align/#grid-repeating-columns-and-rows
        for (int i = 0; i < expand; i++) {
          for (GridTrack t in tracks) {
            _tracks.add(t.clone());
          }
        }
      }
    } else {
      _tracks.add(new GridTrack(_parseTrackMinmax()));
    }
  }

  // <track-minmax> => 'minmax(' <track-breadth> ',' <track-breadth> ')'
  //                   | 'auto' | <track-breadth>
  TrackSizing _parseTrackMinmax() {
    if (_maybeEat('auto') || _maybeEat('fit-content')) {
      return const TrackSizing.auto();
    }
    if (_maybeEat('minmax(')) {
      final min = _parseTrackBreadth();
      _eat(',');
      final max = _parseTrackBreadth();
      _eat(')');
      return new TrackSizing(min, max);
    } else {
      final breadth = _parseTrackBreadth();
      return new TrackSizing(breadth, breadth);
    }
  }

  // <track-breadth> => <length> | <percentage> | <fraction>
  //                    | 'min-content' | 'max-content'
  SizingFunction _parseTrackBreadth() {
    if (_maybeEat('min-content')) {
      return const MinContentSizing();
    } else if (_maybeEat('max-content')) {
      return const MaxContentSizing();
    }

    num value = _eatDouble();

    String units;
    if (_maybeEat('%')) {
      units = '%';
    } else {
      units = _eatWord();
    }

    if (units == 'fr') {
      return new FractionSizing(value);
    } else {
      return new FixedSizing(value, units);
    }
  }
}


/**
 * Exception thrown because the grid style properties had incorrect values.
 */
class SyntaxErrorException implements Exception {
  final String _message;
  final int _offset;
  final String _source;

  const SyntaxErrorException(this._message, this._source, this._offset);

  String toString() {
    String location;
    if (_offset < _source.length) {
      location = 'location: ${_source.substring(_offset)}';
    } else {
      location = 'end of input';
    }
    return 'SyntaxErrorException: $_message at $location';
  }
}
