// Copyright (c) 2012, 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.

patch class StringBuffer {
  static const int _BUFFER_SIZE = 64;
  static const int _PARTS_TO_COMPACT = 128;
  static const int _PARTS_TO_COMPACT_SIZE_LIMIT = _PARTS_TO_COMPACT * 8;

  /**
   * When strings are written to the string buffer, we add them to a
   * list of string parts.
   */
  List<String> _parts;

  /**
    * Total number of code units in the string parts. Does not include
    * the code units added to the buffer.
    */
  int _partsCodeUnits = 0;

  /**
   * To preserve memory, we sometimes compact the parts. This combines
   * several smaller parts into a single larger part to cut down on the
   * cost that comes from the per-object memory overhead. We keep track
   * of the last index where we ended our compaction and the number of
   * code units added since the last compaction.
   */
  int _partsCompactionIndex = 0;
  int _partsCodeUnitsSinceCompaction = 0;

  /**
   * The buffer is used to build up a string from code units. It is
   * used when writing short strings or individual char codes to the
   * buffer. The buffer is allocated on demand.
   */
  Uint16List _buffer;
  int _bufferPosition = 0;

  /**
   * Collects the approximate maximal magnitude of the code units added
   * to the buffer.
   *
   * The value of each added code unit is or'ed with this variable, so the
   * most significant bit set in any code unit is also set in this value.
   * If below 256, the string in the buffer is a Latin-1 string.
   */
  int _bufferCodeUnitMagnitude = 0;

  /// Creates the string buffer with an initial content.
  /* patch */ StringBuffer([Object content = ""]) {
    write(content);
  }

  /* patch */ int get length => _partsCodeUnits + _bufferPosition;

  /* patch */ void write(Object obj) {
    String str;
    if (obj is String) {
      str = obj;
    } else {
      // TODO(srdjan): The following four lines could be replaced by
      // '$obj', but apparently this is too slow on the Dart VM.
      str = obj.toString();
      if (str is! String) {
        throw new ArgumentError('toString() did not return a string');
      }
    }
    if (str.isEmpty) return;
    _consumeBuffer();
    _addPart(str);
  }

  /* patch */ void writeCharCode(int charCode) {
    if (charCode <= 0xFFFF) {
      if (charCode < 0) {
        throw new RangeError.range(charCode, 0, 0x10FFFF);
      }
      _ensureCapacity(1);
      _buffer[_bufferPosition++] = charCode;
      _bufferCodeUnitMagnitude |= charCode;
    } else {
      if (charCode > 0x10FFFF) {
        throw new RangeError.range(charCode, 0, 0x10FFFF);
      }
      _ensureCapacity(2);
      int bits = charCode - 0x10000;
      _buffer[_bufferPosition++] = 0xD800 | (bits >> 10);
      _buffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
      _bufferCodeUnitMagnitude |= 0xFFFF;
    }
  }

  /** Makes the buffer empty. */
  /* patch */ void clear() {
    _parts = null;
    _partsCodeUnits = _bufferPosition = _bufferCodeUnitMagnitude = 0;
  }

  /** Returns the contents of buffer as a string. */
  /* patch */ String toString() {
    _consumeBuffer();
    return (_partsCodeUnits == 0) ?
        "" :
        _StringBase._concatRange(_parts, 0, _parts.length);
  }

  /** Ensures that the buffer has enough capacity to add n code units. */
  void _ensureCapacity(int n) {
    if (_buffer == null) {
      _buffer = new Uint16List(_BUFFER_SIZE);
    } else if (_bufferPosition + n > _buffer.length) {
      _consumeBuffer();
    }
  }

  /**
   * Consumes the content of the buffer by turning it into a string
   * and adding it as a part. After calling this the buffer position
   * will be reset to zero.
   */
  void _consumeBuffer() {
    if (_bufferPosition == 0) return;
    bool isLatin1 = _bufferCodeUnitMagnitude <= 0xFF;
    String str = _create(_buffer, _bufferPosition, isLatin1);
    _bufferPosition = _bufferCodeUnitMagnitude = 0;
    _addPart(str);
  }

  /**
   * Adds a new part to this string buffer and keeps track of how
   * many code units are contained in the parts.
   */
  void _addPart(String str) {
    int length = str.length;
    _partsCodeUnits += length;
    _partsCodeUnitsSinceCompaction += length;

    if (_parts == null) {
      _parts = [ str ];
    } else {
      _parts.add(str);
      int partsSinceCompaction = _parts.length - _partsCompactionIndex;
      if (partsSinceCompaction == _PARTS_TO_COMPACT) {
        _compact();
      }
    }
  }

  /**
   * Compacts the last N parts if their average size allows us to save a
   * lot of memory by turning them all into a single part.
   */
  void _compact() {
    if (_partsCodeUnitsSinceCompaction < _PARTS_TO_COMPACT_SIZE_LIMIT) {
      String compacted = _StringBase._concatRange(
          _parts,
          _partsCompactionIndex,                     // Start
          _partsCompactionIndex + _PARTS_TO_COMPACT  // End
      );
      _parts.length = _parts.length - _PARTS_TO_COMPACT;
      _parts.add(compacted);
    }
    _partsCodeUnitsSinceCompaction = 0;
    _partsCompactionIndex = _parts.length;
  }

  /**
   * Create a [String] from the UFT-16 code units in buffer.
   */
  static String _create(Uint16List buffer, int length, bool isLatin1)
      native "StringBuffer_createStringFromUint16Array";
}
