// Class: openfl.utils.ByteArrayData

var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this

$global.Object.defineProperty(exports, "__esModule", {value: true});

var __map_reserved = {};

// Imports

var $hxClasses = require("./../../hxClasses_stub").default;
var $import = require("./../../import_stub").default;
var $extend = require("./../../extend_stub").default;
function openfl_utils_IDataOutput() {return require("./../../openfl/utils/IDataOutput");}
function openfl_utils_IDataInput() {return require("./../../openfl/utils/IDataInput");}
function haxe_io_Bytes() {return require("./../../haxe/io/Bytes");}
function lime_utils_compress_Deflate() {return require("./../../lime/utils/compress/Deflate");}
function lime_utils_compress_LZMA() {return require("./../../lime/utils/compress/LZMA");}
function lime_utils_compress_Zlib() {return require("./../../lime/utils/compress/Zlib");}
function js__$Boot_HaxeError() {return require("./../../js/_Boot/HaxeError");}
function openfl_errors_EOFError() {return require("./../../openfl/errors/EOFError");}
function haxe_io_FPHelper() {return require("./../../haxe/io/FPHelper");}
function haxe_Unserializer() {return require("./../../haxe/Unserializer");}
function openfl_utils__$ByteArray_ByteArray_$Impl_$() {return require("./../../openfl/utils/_ByteArray/ByteArray_Impl_");}
function haxe_Serializer() {return require("./../../haxe/Serializer");}
function lime_system_System() {return require("./../../lime/system/System");}
function lime_system_Endian() {return require("./../../lime/system/Endian");}

// Constructor

var ByteArrayData = function(length) {
	if(length == null) {
		length = 0;
	}
	var bytes = (haxe_io_Bytes().default).alloc(length);
	(haxe_io_Bytes().default).call(this,bytes.b.buffer);
	this.__length = length;
	if(ByteArrayData.__defaultEndian == null) {
		if((lime_system_System().default).get_endianness() == (lime_system_Endian().default).LITTLE_ENDIAN) {
			ByteArrayData.__defaultEndian = "littleEndian";
		} else {
			ByteArrayData.__defaultEndian = "bigEndian";
		}
	}
	this.set_endian(ByteArrayData.__defaultEndian);
	this.position = 0;
}

// Meta

ByteArrayData.__name__ = ["openfl","utils","ByteArrayData"];
ByteArrayData.__interfaces__ = [(openfl_utils_IDataOutput().default),(openfl_utils_IDataInput().default)];
ByteArrayData.__super__ = (haxe_io_Bytes().default);
ByteArrayData.prototype = $extend((haxe_io_Bytes().default).prototype, {
	clear: function() {
		this.set_length(0);
		this.position = 0;
	},
	compress: function(algorithm) {
		if(algorithm == null) {
			algorithm = "zlib";
		}
		if(this.__length > this.l) {
			var cacheLength = this.l;
			this.l = this.__length;
			var data = (haxe_io_Bytes().default).alloc(cacheLength);
			data.blit(0,this,0,cacheLength);
			this.__setData(data);
			this.l = cacheLength;
		}
		var bytes;
		switch(algorithm) {
		case "deflate":
			bytes = (lime_utils_compress_Deflate().default).compress(this);
			break;
		case "lzma":
			bytes = (lime_utils_compress_LZMA().default).compress(this);
			break;
		default:
			bytes = (lime_utils_compress_Zlib().default).compress(this);
		}
		if(bytes != null) {
			this.__setData(bytes);
			this.l = this.__length;
			this.position = this.l;
		}
	},
	deflate: function() {
		this.compress("deflate");
	},
	inflate: function() {
		this.uncompress("deflate");
	},
	readBoolean: function() {
		if(this.position < this.l) {
			return this.get(this.position++) != 0;
		} else {
			throw new (js__$Boot_HaxeError().default)(new (openfl_errors_EOFError().default)());
		}
	},
	readByte: function() {
		var value = this.readUnsignedByte();
		if((value & 128) != 0) {
			return value - 256;
		} else {
			return value;
		}
	},
	readBytes: function(bytes,offset,length) {
		if(length == null) {
			length = 0;
		}
		if(offset == null) {
			offset = 0;
		}
		if(length == 0) {
			length = this.l - this.position;
		}
		if(this.position + length > this.l) {
			throw new (js__$Boot_HaxeError().default)(new (openfl_errors_EOFError().default)());
		}
		if(bytes.get_length() < offset + length) {
			bytes.__resize(offset + length);
		}
		bytes.blit(offset,this,this.position,length);
		this.position += length;
	},
	readDouble: function() {
		var ch1 = this.readInt();
		var ch2 = this.readInt();
		if(this.get_endian() == "littleEndian") {
			return (haxe_io_FPHelper().default).i64ToDouble(ch1,ch2);
		} else {
			return (haxe_io_FPHelper().default).i64ToDouble(ch2,ch1);
		}
	},
	readFloat: function() {
		return (haxe_io_FPHelper().default).i32ToFloat(this.readInt());
	},
	readInt: function() {
		var ch1 = this.readUnsignedByte();
		var ch2 = this.readUnsignedByte();
		var ch3 = this.readUnsignedByte();
		var ch4 = this.readUnsignedByte();
		if(this.get_endian() == "littleEndian") {
			return ch4 << 24 | ch3 << 16 | ch2 << 8 | ch1;
		} else {
			return ch1 << 24 | ch2 << 16 | ch3 << 8 | ch4;
		}
	},
	readMultiByte: function(length,charSet) {
		return this.readUTFBytes(length);
	},
	readObject: function() {
		var _g = this.objectEncoding;
		switch(_g) {
		case 10:
			var data = this.readUTF();
			return (haxe_Unserializer().default).run(data);
		case 12:
			var data1 = this.readUTF();
			return JSON.parse(data1);
		default:
			return null;
		}
	},
	readShort: function() {
		var ch1 = this.readUnsignedByte();
		var ch2 = this.readUnsignedByte();
		var value;
		if(this.get_endian() == "littleEndian") {
			value = ch2 << 8 | ch1;
		} else {
			value = ch1 << 8 | ch2;
		}
		if((value & 32768) != 0) {
			return value - 65536;
		} else {
			return value;
		}
	},
	readUnsignedByte: function() {
		if(this.position < this.l) {
			return this.get(this.position++);
		} else {
			throw new (js__$Boot_HaxeError().default)(new (openfl_errors_EOFError().default)());
		}
	},
	readUnsignedInt: function() {
		var ch1 = this.readUnsignedByte();
		var ch2 = this.readUnsignedByte();
		var ch3 = this.readUnsignedByte();
		var ch4 = this.readUnsignedByte();
		if(this.get_endian() == "littleEndian") {
			return ch4 << 24 | ch3 << 16 | ch2 << 8 | ch1;
		} else {
			return ch1 << 24 | ch2 << 16 | ch3 << 8 | ch4;
		}
	},
	readUnsignedShort: function() {
		var ch1 = this.readUnsignedByte();
		var ch2 = this.readUnsignedByte();
		if(this.get_endian() == "littleEndian") {
			return (ch2 << 8) + ch1;
		} else {
			return ch1 << 8 | ch2;
		}
	},
	readUTF: function() {
		var bytesCount = this.readUnsignedShort();
		return this.readUTFBytes(bytesCount);
	},
	readUTFBytes: function(length) {
		if(this.position + length > this.l) {
			throw new (js__$Boot_HaxeError().default)(new (openfl_errors_EOFError().default)());
		}
		this.position += length;
		return this.getString(this.position - length,length);
	},
	uncompress: function(algorithm) {
		if(algorithm == null) {
			algorithm = "zlib";
		}
		if(this.__length > this.l) {
			var cacheLength = this.l;
			this.l = this.__length;
			var data = (haxe_io_Bytes().default).alloc(cacheLength);
			data.blit(0,this,0,cacheLength);
			this.__setData(data);
			this.l = cacheLength;
		}
		var bytes;
		switch(algorithm) {
		case "deflate":
			bytes = (lime_utils_compress_Deflate().default).decompress(this);
			break;
		case "lzma":
			bytes = (lime_utils_compress_LZMA().default).decompress(this);
			break;
		default:
			bytes = (lime_utils_compress_Zlib().default).decompress(this);
		}
		if(bytes != null) {
			this.__setData(bytes);
			this.l = this.__length;
		}
		this.position = 0;
	},
	writeBoolean: function(value) {
		this.writeByte(value ? 1 : 0);
	},
	writeByte: function(value) {
		this.__resize(this.position + 1);
		this.set(this.position++,value & 255);
	},
	writeBytes: function(bytes,offset,length) {
		if(length == null) {
			length = 0;
		}
		if(offset == null) {
			offset = 0;
		}
		if((openfl_utils__$ByteArray_ByteArray_$Impl_$().default).get_length(bytes) == 0) {
			return;
		}
		if(length == 0) {
			length = (openfl_utils__$ByteArray_ByteArray_$Impl_$().default).get_length(bytes) - offset;
		}
		this.__resize(this.position + length);
		this.blit(this.position,bytes,offset,length);
		this.position = this.position + length;
	},
	writeDouble: function(value) {
		var int64 = (haxe_io_FPHelper().default).doubleToI64(value);
		if(this.get_endian() == "littleEndian") {
			this.writeInt(int64.low);
			this.writeInt(int64.high);
		} else {
			this.writeInt(int64.high);
			this.writeInt(int64.low);
		}
	},
	writeFloat: function(value) {
		if(this.get_endian() == "littleEndian") {
			this.__resize(this.position + 4);
			this.setFloat(this.position,value);
			this.position += 4;
		} else {
			var $int = (haxe_io_FPHelper().default).floatToI32(value);
			this.writeInt($int);
		}
	},
	writeInt: function(value) {
		this.__resize(this.position + 4);
		if(this.get_endian() == "littleEndian") {
			this.set(this.position++,value & 255);
			this.set(this.position++,value >> 8 & 255);
			this.set(this.position++,value >> 16 & 255);
			this.set(this.position++,value >> 24 & 255);
		} else {
			this.set(this.position++,value >> 24 & 255);
			this.set(this.position++,value >> 16 & 255);
			this.set(this.position++,value >> 8 & 255);
			this.set(this.position++,value & 255);
		}
	},
	writeMultiByte: function(value,charSet) {
		this.writeUTFBytes(value);
	},
	writeObject: function(object) {
		var _g = this.objectEncoding;
		switch(_g) {
		case 10:
			var value = (haxe_Serializer().default).run(object);
			this.writeUTF(value);
			break;
		case 12:
			var value1 = JSON.stringify(object);
			this.writeUTF(value1);
			break;
		default:
			return;
		}
	},
	writeShort: function(value) {
		this.__resize(this.position + 2);
		if(this.get_endian() == "littleEndian") {
			this.set(this.position++,value);
			this.set(this.position++,value >> 8);
		} else {
			this.set(this.position++,value >> 8);
			this.set(this.position++,value);
		}
	},
	writeUnsignedInt: function(value) {
		this.writeInt(value);
	},
	writeUTF: function(value) {
		var bytes = (haxe_io_Bytes().default).ofString(value);
		this.writeShort(bytes.l);
		this.writeBytes((openfl_utils__$ByteArray_ByteArray_$Impl_$().default).fromBytes(bytes));
	},
	writeUTFBytes: function(value) {
		var bytes = (haxe_io_Bytes().default).ofString(value);
		this.writeBytes((openfl_utils__$ByteArray_ByteArray_$Impl_$().default).fromBytes((haxe_io_Bytes().default).ofString(value)));
	},
	__fromBytes: function(bytes) {
		this.__setData(bytes);
		this.l = bytes.l;
	},
	__resize: function(size) {
		if(size > this.__length) {
			var bytes = (haxe_io_Bytes().default).alloc((size + 1) * 3 >> 1);
			if(this.__length > 0) {
				var cacheLength = this.l;
				this.l = this.__length;
				bytes.blit(0,this,0,this.__length);
				this.l = cacheLength;
			}
			this.__setData(bytes);
		}
		if(this.l < size) {
			this.l = size;
		}
	},
	__setData: function(bytes) {
		this.b = bytes.b;
		this.__length = bytes.l;
		this.data = bytes.data;
	},
	get_bytesAvailable: function() {
		return this.l - this.position;
	},
	get_endian: function() {
		return this.__endian;
	},
	set_endian: function(value) {
		return this.__endian = value;
	},
	set_length: function(value) {
		if(value > 0) {
			this.__resize(value);
			if(value < this.position) {
				this.position = value;
			}
		}
		this.l = value;
		return value;
	}
});
ByteArrayData.prototype.__class__ = $hxClasses["openfl.utils.ByteArrayData"] = ByteArrayData;

// Init

{
	var tmp = ByteArrayData.prototype;
	var tmp1 = { get : function () { return this.get_bytesAvailable (); }};
	var tmp2 = { get : function () { return this.get_endian (); }, set : function (v) { return this.set_endian (v); }};
	var tmp3 = function () { return this.get_length (); }
	var tmp4 = function (v) { return this.set_length (v); }
	global.Object.defineProperties(tmp,{ bytesAvailable : tmp1, endian : tmp2, "length" : { get : tmp3, set : tmp4}});
};

// Statics

ByteArrayData.fromBytes = function(bytes) {
	var result = new ByteArrayData();
	result.__fromBytes(bytes);
	return result;
}
ByteArrayData.__defaultEndian = null

// Export

exports.default = ByteArrayData;