class ResourceLoader {
	resource:Resource;

	constructor(resource:Resource) {
		this.resource = resource;
	}

	load(url:string, identifier:string) {

	}
}

class ImageResourceLoader extends ResourceLoader {
	load(url:string, identifier:string) {
		var image = new Image();
		image.src = "img/"+url;
		var caller = this;
		var callback = this.completed;
		image.onerror = function() {
			callback.call(caller, identifier, image, false);
		};
		image.onload = function() {
			callback.call(caller, identifier, image, true);
		};
	}

	completed(name:string, image:HTMLImageElement, is_success:bool) {
		if (! is_success)
			console.log("error: "+name);
		else
			this.resource.images[name] = image;

		this.resource.requestCompleted(name);
	}
}

class ScriptResourceLoader extends ResourceLoader {
	load(url:string, identifier:string) {
		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();
		var callback = this.completed;
		script.onload = () => {
			callback.call(this, identifier, script, true);
		}
		script.onerror = () => {
			callback.call(this, identifier, script, false);
		}
		heads[0].appendChild(script);
	}

	completed(name:string, script:HTMLScriptElement, is_success:bool) {
		if (! is_success)
			console.log("error: "+name);
		else
			this.resource.scripts[name] = script;

		this.resource.requestCompleted(name);
	}
}

class SoundResourceLoader extends ResourceLoader {
	load(url:string, identifier:string) {
		var request = new XMLHttpRequest();
		request.open("GET", "sound/"+url, true);
		request.responseType = "arraybuffer";

		var callback = this.completed;
		request.onload = () => {
			var context = SimpleSound.getAudioContext();
			if (context) {
				context.decodeAudioData(
					request.response,
					(decodedAudio:AudioBuffer) => {
						callback.call(this, identifier, decodedAudio, true);
					},
					() => {
						callback.call(this, identifier, null, false);
					}
				);
			} else {
				callback.call(this, identifier, null, false);
			}
		}
		request.onerror = () => {
			callback.call(this, identifier, null, false);
		}

		request.send();
	}

	completed(name:string, audio:AudioBuffer, is_success:bool) {
		if (! is_success)
			console.log("error: "+name);
		else
			this.resource.sounds[name] = audio;

		this.resource.requestCompleted(name);
	}
}