define('jls/lang/Buffer', [
  'jls/lang/Class',
  'jls/lang/IllegalArgumentException',
  'jls/lang/BufferOverflowException',
  'jls/lang/BufferUnderflowException'
], function (
  Class,
  IllegalArgumentException,
  BufferOverflowException,
  BufferUnderflowException
) {

var Buffer;
/**
 * @class A container for data of a specific primitive type. 
 * @see jls.lang.ByteBuffer
 * @see jls.lang.CharBuffer
 * @name jls.lang.Buffer
 */
Buffer = Class.create(/** @lends jls.lang.Buffer.prototype */
{
    initialize : function(capacity, limit, position, offset) {
        this._capacity = (typeof capacity != 'undefined') ? capacity : 0;
        this._limit = (typeof limit != 'undefined') ? limit : this._capacity;
        this._position = position || 0;
        this._offset = offset || 0;
    },
    /**
     * Returns this buffer's offset into the native byte array.
     * 
     * @returns {Number} The offset of this buffer.
     */
    getOffset : function() {
        return this._offset;
    },
    /**
     * Returns the byte array position, considering the offset.
     * 
     * @returns {Number} The position of the byte array.
     */
    offset : function() {
        return this._offset + this._position;
    },
    /**
     * Clears this buffer, setting the position to zero and the limit to the capacity.
     * 
     * @returns {jls.lang.Buffer} This buffer.
     */
    clear : function() {
        this._position = 0;
        this._limit = this._capacity;
        return this;
    },
    /**
     * Flips this buffer, setting the limit to the position and the position to zero.
     * 
     * @returns {jls.lang.Buffer} This buffer.
     */
    flip : function() {
        this._limit = this._position;
        this._position = 0;
        return this;
    },
    /**
     * Returns this buffer's position.
     * 
     * @returns {Number} The position of this buffer.
     */
    position : function() {
        return this._position;
    },
    /**
     * Returns this buffer's capacity.
     * 
     * @returns {Number} The capacity of this buffer.
     */
    capacity : function() {
        return this._capacity;
    },
    /**
     * Returns this buffer's limit.
     * 
     * @returns {Number} The limit of this buffer.
     */
    limit : function() {
        return this._limit;
    },
    /**
     * Returns this buffer's remaining.
     * 
     * @returns {Number} The remaining of this buffer.
     */
    remaining : function() {
        return this._limit - this._position;
    },
    /**
     * Increments this buffer's position and then returns the resulting position.
     * 
     * @param {Number} d The delta to increment.
     * @returns {Number} The position of this buffer.
     */
    incrementPosition : function(d) {
        if (this._position + d > this._limit) {
            throw new IllegalArgumentException();
        }
        this._position += d;
        return this._position;
    },
    /**
     * Sets this buffer's position.
     * 
     * @param {Number} position The position to set.
     * @returns {jls.lang.Buffer} This buffer.
     */
    setPosition : function(position) {
        if (position > this._limit) {
            throw new IllegalArgumentException();
        }
        this._position = position;
        return this;
    },
    /**
     * Sets this buffer's limit.
     * 
     * @param {Number} limit The limit to set.
     * @returns {jls.lang.Buffer} This buffer.
     */
    setLimit : function(limit) {
        if (limit > this._capacity) {
            throw new IllegalArgumentException();
        }
        this._limit = limit;
        return this;
    }
});

Object.extend(Buffer, /** @lends jls.lang.Buffer */
{
    // Byte order constants.
    /*
     * The bytes are ordered from most significant to least significant. 
     */
    BIG_ENDIAN : 1,
    /*
     * The bytes are ordered from least significant to most significant.
     */
    LITTLE_ENDIAN : 2
});

return Buffer;
});
