define('jls/io/BufferChannel', ['jls/lang/Class', 'jls/lang/Exception', 'jls/lang/ByteBuffer'], function (Class, Exception, ByteBuffer) {

var BufferChannel;
/**
 * @namespace Provides for system input and output through data streams, serialization and the file system.
 * @name jls.io
 */

BufferChannel = Class.create({
    initialize : function(buffer) {
        if (buffer) {
            if (! (buffer instanceof ByteBuffer)) {
                throw new Exception('Invalid Buffer argument type (' + (typeof buffer) + ')');
            }
            this._buffer = buffer; //buffer.slice();
            this._append = false;
        } else {
            this._buffer = ByteBuffer.allocate(1024);
            // TODO Use append
            this._append = true;
        }
    },
    buffer : function() {
        return this._buffer;
    },
    close : function() {
        this._buffer.free(); // ?
        return this;
    },
    flush : function() {
        return this;
    },
    readByte : function() {
        if (this._buffer.remaining() < 1) {
            return -1;
        }
        return this._buffer.getByte();
    },
    writeByte : function(b) {
        if (this._buffer.remaining() < 1) {
            return false;
        }
        this._buffer.putByte(b);
        return true;
    },
    read : function(buffer) {
        var count = buffer.remaining();
		if (count > this._buffer.remaining()) {
			count = this._buffer.remaining();
		}
        //jls.logger.trace('BufferChannel.read(' + this._buffer.remaining() + '), count: ' + count);
		if (count > 0) {
			buffer.putBuffer(this._buffer, count);
		}
        return count;
    },
    write : function(buffer) {
        var count = this._buffer.remaining();
		if (count > buffer.remaining()) {
			count = buffer.remaining();
		}
        //jls.logger.trace('BufferChannel.write(' + this._buffer.remaining() + '), count: ' + count);
		if (count > 0) {
			this._buffer.putBuffer(buffer, count);
		}
        return count;
    },
    toString : function(csn) {
        var l = this._buffer.limit();
        var p = this._buffer.position();
        this._buffer.flip();
        var s = this._buffer.getString(csn);
        this._buffer.setLimit(l);
        this._buffer.setPosition(p);
        return s;
    }
});

return BufferChannel;
});
