// 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 {
  /** Backing store for collected UTF-16 code units. */
  Uint16List _buffer;
  /** Number of code units collected. */
  int _length = 0;
  /**
   * Collects the approximate maximal magnitude of the added code units.
   *
   * 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 is a Latin-1 string.
   */
  int _codeUnitMagnitude = 0;

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

  /* patch */ int get length => _length;

  /// Adds [obj] to the buffer.
  /* 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;
    _ensureCapacity(str.length);
    for (int i = 0; i < str.length; i++) {
      int unit = str.codeUnitAt(i);
      _buffer[_length + i] = unit;
      _codeUnitMagnitude |= unit;
    }
    _length += str.length;
  }

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

  /** Makes the buffer empty. */
  /* patch */ void clear() {
    _length = 0;
    _codeUnitMagnitude = 0;
  }

  /** Returns the contents of buffer as a string. */
  /* patch */ String toString() {
    if (_length == 0) return "";
    bool isLatin1 = _codeUnitMagnitude <= 0xFF;
    return _create(_buffer, _length, isLatin1);
  }

  /** Ensures that the buffer has enough capacity to add n code units. */
  void _ensureCapacity(int n) {
    int requiredCapacity = _length + n;
    if (requiredCapacity > _buffer.length) {
      _grow(requiredCapacity);
    }
  }

  /** Grows the buffer until it can contain [requiredCapacity] entries. */
  void _grow(int requiredCapacity) {
    int newCapacity = _buffer.length;
    do {
      newCapacity *= 2;
    } while (newCapacity < requiredCapacity);
    List<int> newBuffer = new Uint16List(newCapacity);
    newBuffer.setRange(0, _length, _buffer);
    _buffer = newBuffer;
  }

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