class Resource {
	images: {[key:string]: HTMLImageElement; };
	scripts: {[key:string]: HTMLScriptElement; };
	requests: any[];
	loaded: Trigger;

	static instance:Resource;

	static getInstance():Resource {
		return () => {
			if (! Resource.instance)
				Resource.instance = new Resource();
			return Resource.instance;
		}();
	}

	constructor() {
		this.requests = [];
		this.loaded = new Trigger();
		this.images = {};
		this.scripts = {};
	}

	get(name:string) {
		return this.images[name];
	}

	loadScript(url:string, identifier:string, caller:any, callback?:(string,HTMLScriptElement, bool) => void) {
		var script = <HTMLScriptElement>document.createElement("script");
		var heads = document.getElementsByTagName("head");
		if (heads.length == 0)
			throw "can not find head tag";
		script.src = url+"?"+(new Date()).getTime();
		script.onload = function() {
			callback.call(caller, identifier, script, true);
		}
		script.onerror = function() {
			callback.call(caller, identifier, script, false);
		}
		heads[0].appendChild(script);
	}

	loadScriptComplete(name:string, script:HTMLScriptElement, is_success:bool) {
		if (! is_success) {
			console.log("error: "+name);
		} else {
			this.scripts[name] = script;
		}
		for (var i=0; i<this.requests.length; i++) {
			if (this.requests[i] == name) {
				this.requests.splice(i, 1);
				break;
			}
		}
		this.loaded.fire(this.requests.length);
	}

	loadImage(url:string, identifier:string, caller:any, callback?:(string,HTMLImageElement, bool) => void) {
		var image = new Image();
		image.src = "img/"+url;
		image.onerror = function() {
			callback.call(caller, identifier, image, false);
		};
		image.onload = function() {
			callback.call(caller, identifier, image, true);
		};
	}

	loadImageComplete(name:string, image:HTMLImageElement, is_success:bool) {
		if (! is_success) {
			console.log("error: "+name);
		} else {
			this.images[name] = image;
		}
		for (var i=0; i<this.requests.length; i++) {
			if (this.requests[i] == name) {
				this.requests.splice(i, 1);
				break;
			}
		}
		this.loaded.fire(this.requests.length);
	}

	load(name:string, url?:string) {
		if (! url)
			url = name;

		this.requests.push(name);
		if (url.length > 3 && url.substr(-3).toLowerCase() == ".js") {
			this.loadScript(url, name, this, this.loadScriptComplete);
		} else {
			this.loadImage(url, name, this, this.loadImageComplete);
		}
	}
}