// 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 = null;

  /**
    * 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 = null;
  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._concatAllNative(_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._concatAllNative(
          _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";
}
