// Class: lime.utils.AssetLibrary

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 $bind = require("./../../bind_stub").default;
function js_Boot() {return require("./../../js/Boot");}
function js__$Boot_HaxeError() {return require("./../../js/_Boot/HaxeError");}
function lime_media_AudioBuffer() {return require("./../../lime/media/AudioBuffer");}
function Type() {return require("./../../Type");}
function haxe_io_Bytes() {return require("./../../haxe/io/Bytes");}
function lime_utils__$Bytes_Bytes_$Impl_$() {return require("./../../lime/utils/_Bytes/Bytes_Impl_");}
function lime_text_Font() {return require("./../../lime/text/Font");}
function lime_graphics_Image() {return require("./../../lime/graphics/Image");}
function lime_app_Future() {return require("./../../lime/app/Future");}
function lime_app_Promise() {return require("./../../lime/app/Promise");}
function haxe_ds_StringMap() {return require("./../../haxe/ds/StringMap");}
function lime_utils_Log() {return require("./../../lime/utils/Log");}
function lime_net__$HTTPRequest_$String() {return require("./../../lime/net/_HTTPRequest_String");}
function Reflect() {return require("./../../Reflect");}
function Std() {return require("./../../Std");}
function lime_utils_AssetManifest() {return require("./../../lime/utils/AssetManifest");}
function lime_app__$Event_$Void_$Void() {return require("./../../lime/app/_Event_Void_Void");}

// Constructor

var AssetLibrary = function() {
	this.types = new (haxe_ds_StringMap().default)();
	this.sizes = new (haxe_ds_StringMap().default)();
	this.preload = new (haxe_ds_StringMap().default)();
	this.paths = new (haxe_ds_StringMap().default)();
	this.pathGroups = new (haxe_ds_StringMap().default)();
	this.classTypes = new (haxe_ds_StringMap().default)();
	this.cachedText = new (haxe_ds_StringMap().default)();
	this.cachedImages = new (haxe_ds_StringMap().default)();
	this.cachedFonts = new (haxe_ds_StringMap().default)();
	this.cachedBytes = new (haxe_ds_StringMap().default)();
	this.cachedAudioBuffers = new (haxe_ds_StringMap().default)();
	this.onChange = new (lime_app__$Event_$Void_$Void().default)();
	this.bytesLoaded = 0;
	this.bytesTotal = 0;
}

// Meta

AssetLibrary.__name__ = ["lime","utils","AssetLibrary"];
AssetLibrary.prototype = {
	exists: function(id,type) {
		var requestedType = type != null ? (js_Boot().default).__cast(type , String) : null;
		var assetType = this.types.get(id);
		if(assetType != null) {
			if(assetType == requestedType || (requestedType == "SOUND" || requestedType == "MUSIC") && (assetType == "MUSIC" || assetType == "SOUND")) {
				return true;
			}
			if(requestedType == "BINARY" || requestedType == null || assetType == "BINARY" && requestedType == "TEXT") {
				return true;
			}
		}
		return false;
	},
	getAsset: function(id,type) {
		switch(type) {
		case "BINARY":
			return this.getBytes(id);
		case "FONT":
			return this.getFont(id);
		case "IMAGE":
			return this.getImage(id);
		case "MUSIC":case "SOUND":
			return this.getAudioBuffer(id);
		case "TEMPLATE":
			throw new (js__$Boot_HaxeError().default)("Not sure how to get template: " + id);
			break;
		case "TEXT":
			return this.getText(id);
		default:
			throw new (js__$Boot_HaxeError().default)("Unknown asset type: " + type);
		}
	},
	getAudioBuffer: function(id) {
		if(this.cachedAudioBuffers.exists(id)) {
			return this.cachedAudioBuffers.get(id);
		} else if(this.classTypes.exists(id)) {
			return (lime_media_AudioBuffer().default).fromBytes((js_Boot().default).__cast((Type().default).createInstance(this.classTypes.get(id),[]) , (haxe_io_Bytes().default)));
		} else {
			return (lime_media_AudioBuffer().default).fromFile(this.paths.get(id));
		}
	},
	getBytes: function(id) {
		if(this.cachedBytes.exists(id)) {
			return this.cachedBytes.get(id);
		} else if(this.cachedText.exists(id)) {
			var bytes = (lime_utils__$Bytes_Bytes_$Impl_$().default).ofString(this.cachedText.get(id));
			this.cachedBytes.set(id,bytes);
			return bytes;
		} else if(this.classTypes.exists(id)) {
			return (js_Boot().default).__cast((Type().default).createInstance(this.classTypes.get(id),[]) , (haxe_io_Bytes().default));
		} else {
			return (lime_utils__$Bytes_Bytes_$Impl_$().default).fromFile(this.paths.get(id));
		}
	},
	getFont: function(id) {
		if(this.cachedFonts.exists(id)) {
			return this.cachedFonts.get(id);
		} else if(this.classTypes.exists(id)) {
			return (js_Boot().default).__cast((Type().default).createInstance(this.classTypes.get(id),[]) , (lime_text_Font().default));
		} else {
			return (lime_text_Font().default).fromFile(this.paths.get(id));
		}
	},
	getImage: function(id) {
		if(this.cachedImages.exists(id)) {
			return this.cachedImages.get(id);
		} else if(this.classTypes.exists(id)) {
			return (js_Boot().default).__cast((Type().default).createInstance(this.classTypes.get(id),[]) , (lime_graphics_Image().default));
		} else {
			return (lime_graphics_Image().default).fromFile(this.paths.get(id));
		}
	},
	getPath: function(id) {
		if(this.paths.exists(id)) {
			return this.paths.get(id);
		} else if(this.pathGroups.exists(id)) {
			return this.pathGroups.get(id)[0];
		} else {
			return null;
		}
	},
	getText: function(id) {
		if(this.cachedText.exists(id)) {
			return this.cachedText.get(id);
		} else {
			var bytes = this.getBytes(id);
			if(bytes == null) {
				return null;
			} else {
				return bytes.getString(0,bytes.get_length());
			}
		}
	},
	isLocal: function(id,type) {
		if(this.classTypes.exists(id)) {
			return true;
		}
		var requestedType = type != null ? (js_Boot().default).__cast(type , String) : null;
		switch(requestedType) {
		case "FONT":
			return this.cachedFonts.exists(id);
		case "IMAGE":
			return this.cachedImages.exists(id);
		case "MUSIC":case "SOUND":
			return this.cachedAudioBuffers.exists(id);
		default:
			if(!this.cachedBytes.exists(id)) {
				return this.cachedText.exists(id);
			} else {
				return true;
			}
		}
	},
	list: function(type) {
		var requestedType = type != null ? (js_Boot().default).__cast(type , String) : null;
		var items = [];
		var id = this.types.keys();
		while(id.hasNext()) {
			var id1 = id.next();
			if(requestedType == null || this.exists(id1,type)) {
				items.push(id1);
			}
		}
		return items;
	},
	loadAsset: function(id,type) {
		switch(type) {
		case "BINARY":
			return this.loadBytes(id);
		case "FONT":
			return this.loadFont(id);
		case "IMAGE":
			return this.loadImage(id);
		case "MUSIC":case "SOUND":
			return this.loadAudioBuffer(id);
		case "TEMPLATE":
			throw new (js__$Boot_HaxeError().default)("Not sure how to load template: " + id);
			break;
		case "TEXT":
			return this.loadText(id);
		default:
			throw new (js__$Boot_HaxeError().default)("Unknown asset type: " + type);
		}
	},
	load: function() {
		if(this.loaded) {
			return (lime_app_Future().default).withValue(this);
		}
		if(this.promise == null) {
			this.promise = new (lime_app_Promise().default)();
			this.bytesLoadedCache = new (haxe_ds_StringMap().default)();
			this.assetsLoaded = 0;
			this.assetsTotal = 1;
			var id = this.preload.keys();
			while(id.hasNext()) {
				var id1 = id.next();
				if(!this.preload.get(id1)) {
					continue;
				}
				(lime_utils_Log().default).verbose("Preloading asset: " + id1 + " [" + this.types.get(id1) + "]",{ fileName : "AssetLibrary.hx", lineNumber : 452, className : "lime.utils.AssetLibrary", methodName : "load"});
				var _g = this.types.get(id1);
				if(_g != null) {
					switch(_g) {
					case "BINARY":
						this.assetsTotal++;
						var future = this.loadBytes(id1);
						future.onProgress((function(id2,f) {
							return function(a1,a2) {
								f[0](id2[0],a1,a2);
							};
						})([id1],[$bind(this,this.load_onProgress)]));
						future.onError((function(id3,f1) {
							return function(a11) {
								f1[0](id3[0],a11);
							};
						})([id1],[$bind(this,this.load_onError)]));
						future.onComplete((function(id4,f2) {
							return function(a12) {
								f2[0](id4[0],a12);
							};
						})([id1],[$bind(this,this.loadBytes_onComplete)]));
						break;
					case "FONT":
						this.assetsTotal++;
						var future1 = this.loadFont(id1);
						future1.onProgress((function(id5,f3) {
							return function(a13,a21) {
								f3[0](id5[0],a13,a21);
							};
						})([id1],[$bind(this,this.load_onProgress)]));
						future1.onError((function(id6,f4) {
							return function(a14) {
								f4[0](id6[0],a14);
							};
						})([id1],[$bind(this,this.load_onError)]));
						future1.onComplete((function(id7,f5) {
							return function(a15) {
								f5[0](id7[0],a15);
							};
						})([id1],[$bind(this,this.loadFont_onComplete)]));
						break;
					case "IMAGE":
						this.assetsTotal++;
						var future2 = this.loadImage(id1);
						future2.onProgress((function(id8,f6) {
							return function(a16,a22) {
								f6[0](id8[0],a16,a22);
							};
						})([id1],[$bind(this,this.load_onProgress)]));
						future2.onError((function(id9,f7) {
							return function(a17) {
								f7[0](id9[0],a17);
							};
						})([id1],[$bind(this,this.load_onError)]));
						future2.onComplete((function(id10,f8) {
							return function(a18) {
								f8[0](id10[0],a18);
							};
						})([id1],[$bind(this,this.loadImage_onComplete)]));
						break;
					case "MUSIC":case "SOUND":
						this.assetsTotal++;
						var future3 = this.loadAudioBuffer(id1);
						future3.onProgress((function(id11,f9) {
							return function(a19,a23) {
								f9[0](id11[0],a19,a23);
							};
						})([id1],[$bind(this,this.load_onProgress)]));
						future3.onError((function(id12,f10) {
							return function(a110) {
								f10[0](id12[0],a110);
							};
						})([id1],[$bind(this,this.loadAudioBuffer_onError)]));
						future3.onComplete((function(id13,f11) {
							return function(a111) {
								f11[0](id13[0],a111);
							};
						})([id1],[$bind(this,this.loadAudioBuffer_onComplete)]));
						break;
					case "TEXT":
						this.assetsTotal++;
						var future4 = this.loadText(id1);
						future4.onProgress((function(id14,f12) {
							return function(a112,a24) {
								f12[0](id14[0],a112,a24);
							};
						})([id1],[$bind(this,this.load_onProgress)]));
						future4.onError((function(id15,f13) {
							return function(a113) {
								f13[0](id15[0],a113);
							};
						})([id1],[$bind(this,this.load_onError)]));
						future4.onComplete((function(id16,f14) {
							return function(a114) {
								f14[0](id16[0],a114);
							};
						})([id1],[$bind(this,this.loadText_onComplete)]));
						break;
					default:
					}
				}
			}
			this.__assetLoaded(null);
		}
		return this.promise.future;
	},
	loadAudioBuffer: function(id) {
		if(this.cachedAudioBuffers.exists(id)) {
			return (lime_app_Future().default).withValue(this.cachedAudioBuffers.get(id));
		} else if(this.classTypes.exists(id)) {
			return (lime_app_Future().default).withValue((Type().default).createInstance(this.classTypes.get(id),[]));
		} else if(this.pathGroups.exists(id)) {
			return (lime_media_AudioBuffer().default).loadFromFiles(this.pathGroups.get(id));
		} else {
			return (lime_media_AudioBuffer().default).loadFromFile(this.paths.get(id));
		}
	},
	loadBytes: function(id) {
		if(this.cachedBytes.exists(id)) {
			return (lime_app_Future().default).withValue(this.cachedBytes.get(id));
		} else if(this.classTypes.exists(id)) {
			return (lime_app_Future().default).withValue((Type().default).createInstance(this.classTypes.get(id),[]));
		} else {
			return (lime_utils__$Bytes_Bytes_$Impl_$().default).loadFromFile(this.paths.get(id));
		}
	},
	loadFont: function(id) {
		if(this.cachedFonts.exists(id)) {
			return (lime_app_Future().default).withValue(this.cachedFonts.get(id));
		} else if(this.classTypes.exists(id)) {
			var font = (Type().default).createInstance(this.classTypes.get(id),[]);
			return font.__loadFromName(font.name);
		} else {
			return (lime_text_Font().default).loadFromName(this.paths.get(id));
		}
	},
	loadImage: function(id) {
		if(this.cachedImages.exists(id)) {
			return (lime_app_Future().default).withValue(this.cachedImages.get(id));
		} else if(this.classTypes.exists(id)) {
			return (lime_app_Future().default).withValue((Type().default).createInstance(this.classTypes.get(id),[]));
		} else {
			return (lime_graphics_Image().default).loadFromFile(this.paths.get(id));
		}
	},
	loadText: function(id) {
		if(this.cachedText.exists(id)) {
			return (lime_app_Future().default).withValue(this.cachedText.get(id));
		} else if(this.cachedBytes.exists(id) || this.classTypes.exists(id)) {
			var bytes = this.getBytes(id);
			if(bytes == null) {
				return (lime_app_Future().default).withValue(null);
			} else {
				var text = bytes.getString(0,bytes.get_length());
				this.cachedText.set(id,text);
				return (lime_app_Future().default).withValue(text);
			}
		} else {
			var request = new (lime_net__$HTTPRequest_$String().default)();
			return request.load(this.paths.get(id));
		}
	},
	unload: function() {
	},
	__assetLoaded: function(id) {
		this.assetsLoaded++;
		if(id != null) {
			(lime_utils_Log().default).verbose("Loaded asset: " + id + " [" + this.types.get(id) + "] (" + (this.assetsLoaded - 1) + "/" + (this.assetsTotal - 1) + ")",{ fileName : "AssetLibrary.hx", lineNumber : 698, className : "lime.utils.AssetLibrary", methodName : "__assetLoaded"});
		}
		if(id != null) {
			var size = this.sizes.get(id);
			if(!this.bytesLoadedCache.exists(id)) {
				this.bytesLoaded += size;
			} else {
				var cache = this.bytesLoadedCache.get(id);
				if(cache < size) {
					this.bytesLoaded += size - cache;
				}
			}
			this.bytesLoadedCache.set(id,size);
		}
		if(this.assetsLoaded < this.assetsTotal) {
			this.promise.progress(this.bytesLoaded,this.bytesTotal);
		} else {
			this.loaded = true;
			this.promise.progress(this.bytesTotal,this.bytesTotal);
			this.promise.complete(this);
		}
	},
	__cacheBreak: function(path) {
		return path;
	},
	__fromManifest: function(manifest) {
		var hasSize = manifest.version >= 2;
		var size;
		var id;
		var pathGroup;
		var classRef;
		var basePath = manifest.rootPath;
		if(basePath == null) {
			basePath = "";
		}
		if(basePath != "") {
			basePath += "/";
		}
		var _g = 0;
		var _g1 = manifest.assets;
		while(_g < _g1.length) {
			var asset = _g1[_g];
			++_g;
			if(hasSize && (Reflect().default).hasField(asset,"size")) {
				size = asset.size;
			} else {
				size = 100;
			}
			id = asset.id;
			if((Reflect().default).hasField(asset,"path")) {
				this.paths.set(id,this.__cacheBreak(basePath + (Std().default).string((Reflect().default).field(asset,"path"))));
			}
			if((Reflect().default).hasField(asset,"pathGroup")) {
				pathGroup = (Reflect().default).field(asset,"pathGroup");
				var _g3 = 0;
				var _g2 = pathGroup.length;
				while(_g3 < _g2) {
					var i = _g3++;
					pathGroup[i] = this.__cacheBreak(basePath + pathGroup[i]);
				}
				this.pathGroups.set(id,pathGroup);
			}
			this.sizes.set(id,size);
			this.types.set(id,asset.type);
			if((Reflect().default).hasField(asset,"preload")) {
				this.preload.set(id,(Reflect().default).field(asset,"preload"));
			}
			if((Reflect().default).hasField(asset,"className")) {
				classRef = (Type().default).resolveClass((Reflect().default).field(asset,"className"));
				this.classTypes.set(id,classRef);
			}
		}
		this.bytesTotal = 0;
		var _g4 = 0;
		var _g11 = manifest.assets;
		while(_g4 < _g11.length) {
			var asset1 = _g11[_g4];
			++_g4;
			id = asset1.id;
			if(this.preload.exists(id) && this.preload.get(id)) {
				this.bytesTotal += this.sizes.get(id);
			}
		}
	},
	loadAudioBuffer_onComplete: function(id,audioBuffer) {
		this.cachedAudioBuffers.set(id,audioBuffer);
		if(this.pathGroups.exists(id)) {
			var pathGroup = this.pathGroups.get(id);
			var otherID = this.pathGroups.keys();
			while(otherID.hasNext()) {
				var otherID1 = otherID.next();
				if(otherID1 == id) {
					continue;
				}
				var _g = 0;
				while(_g < pathGroup.length) {
					var path = pathGroup[_g];
					++_g;
					if(this.pathGroups.get(otherID1).indexOf(path) > -1) {
						this.cachedAudioBuffers.set(otherID1,audioBuffer);
						break;
					}
				}
			}
		}
		this.__assetLoaded(id);
	},
	loadAudioBuffer_onError: function(id,message) {
		if(message != null && message != "") {
			(lime_utils_Log().default).warn("Could not load \"" + id + "\": " + (Std().default).string(message),{ fileName : "AssetLibrary.hx", lineNumber : 883, className : "lime.utils.AssetLibrary", methodName : "loadAudioBuffer_onError"});
		} else {
			(lime_utils_Log().default).warn("Could not load \"" + id + "\"",{ fileName : "AssetLibrary.hx", lineNumber : 887, className : "lime.utils.AssetLibrary", methodName : "loadAudioBuffer_onError"});
		}
		this.loadAudioBuffer_onComplete(id,new (lime_media_AudioBuffer().default)());
	},
	loadBytes_onComplete: function(id,bytes) {
		this.cachedBytes.set(id,bytes);
		this.__assetLoaded(id);
	},
	loadFont_onComplete: function(id,font) {
		this.cachedFonts.set(id,font);
		this.__assetLoaded(id);
	},
	loadImage_onComplete: function(id,image) {
		this.cachedImages.set(id,image);
		this.__assetLoaded(id);
	},
	loadText_onComplete: function(id,text) {
		this.cachedText.set(id,text);
		this.__assetLoaded(id);
	},
	load_onError: function(id,message) {
		if(message != null && message != "") {
			this.promise.error("Error loading asset \"" + id + "\": " + (Std().default).string(message));
		} else {
			this.promise.error("Error loading asset \"" + id + "\"");
		}
	},
	load_onProgress: function(id,bytesLoaded,bytesTotal) {
		if(bytesLoaded > 0) {
			var size = this.sizes.get(id);
			var percent;
			if(bytesTotal > 0) {
				percent = bytesLoaded / bytesTotal;
				if(percent > 1) {
					percent = 1;
				}
				bytesLoaded = Math.floor(percent * size);
			} else if(bytesLoaded > size) {
				bytesLoaded = size;
			}
			if(this.bytesLoadedCache.exists(id)) {
				var cache = this.bytesLoadedCache.get(id);
				if(bytesLoaded != cache) {
					this.bytesLoaded += bytesLoaded - cache;
				}
			} else {
				this.bytesLoaded += bytesLoaded;
			}
			this.bytesLoadedCache.set(id,bytesLoaded);
			this.promise.progress(this.bytesLoaded,this.bytesTotal);
		}
	}
};
AssetLibrary.prototype.__class__ = AssetLibrary.prototype.constructor = $hxClasses["lime.utils.AssetLibrary"] = AssetLibrary;

// Init



// Statics

AssetLibrary.fromBytes = function(bytes,rootPath) {
	return AssetLibrary.fromManifest((lime_utils_AssetManifest().default).fromBytes(bytes,rootPath));
}
AssetLibrary.fromFile = function(path,rootPath) {
	return AssetLibrary.fromManifest((lime_utils_AssetManifest().default).fromFile(path,rootPath));
}
AssetLibrary.fromManifest = function(manifest) {
	if(manifest == null) {
		return null;
	}
	var library = null;
	if(manifest.libraryType == null) {
		library = new AssetLibrary();
	} else {
		var libraryClass = (Type().default).resolveClass(manifest.libraryType);
		if(libraryClass != null) {
			library = (Type().default).createInstance(libraryClass,manifest.libraryArgs);
		} else {
			(lime_utils_Log().default).warn("Could not find library type: " + manifest.libraryType,{ fileName : "AssetLibrary.hx", lineNumber : 140, className : "lime.utils.AssetLibrary", methodName : "fromManifest"});
			return null;
		}
	}
	library.__fromManifest(manifest);
	return library;
}
AssetLibrary.loadFromBytes = function(bytes,rootPath) {
	return (lime_utils_AssetManifest().default).loadFromBytes(bytes,rootPath).then(function(manifest) {
		return AssetLibrary.loadFromManifest(manifest);
	});
}
AssetLibrary.loadFromFile = function(path,rootPath) {
	return (lime_utils_AssetManifest().default).loadFromFile(path,rootPath).then(function(manifest) {
		return AssetLibrary.loadFromManifest(manifest);
	});
}
AssetLibrary.loadFromManifest = function(manifest) {
	var library = AssetLibrary.fromManifest(manifest);
	if(library != null) {
		return library.load();
	} else {
		return (lime_app_Future().default).withError("Could not load asset manifest");
	}
}


// Export

exports.default = AssetLibrary;