var assetsPath = "assets/"+conf.assets;

var assets = {
	imgs: {
		player: new ImageSource("player"),
		background: new ImageSource("background", null, ".jpg"),
		wall: new ImageSource("wall")
	},

	soundtracks: {
		soundtrack1: new AudioSource("soundtracks/track1"),
		soundtrack2: new AudioSource("soundtracks/track2"),
		soundtrack3: new AudioSource("soundtracks/track3")
	}
};

/*
 * Audio source.
 */
function AudioSource(src, ext) {
	makeEventListener(this);
	var ext = ext || ".mp3";

	this.audio = document.createElement("audio");
	this.ready = false;

	this.audio.addEventListener("canplaythrough", function() {
		this.ready = true;
		this.emit("load");
	}.bind(this));

	this.audio.addEventListener("ended", function() {
		this.emit("ended");
	}.bind(this));

	this.audio.src = assetsPath+"/"+src+ext;
}
AudioSource.prototype.play = function() {
	this.audio.currentTime = 0;
	this.audio.play();
}
AudioSource.prototype.pause = function() {
	this.audio.pause();
}

/*
 * Image source.
 */
function ImageSource(src, frameh, ext) {
	var ext = ext || ".png";

	this.img = document.createElement("img");
	this.ready = false;
	this.width = 0;
	this.height = 0;
	this.frameh = frameh == null ? -1 : frameh;
	this.steps = 1;

	console.log("image", assetsPath, assetsPath+"/images/"+src+ext);

	this.img.onload = function() {
		console.log(this);
		this.ready = true;
		this.width = this.img.width;
		this.height = this.img.height;

		if (this.frameh === -1)
			this.frameh = this.height;

		this.steps = this.height / this.frameh;
		if (this.steps !== Math.round(this.steps)) {
			this.steps = Math.round(this.steps);
			console.log(
				"Warning: '"+src+ext+"': "+
				"Height isn't evenly divisible by frame height. "+
				"Height: "+this.height+", frame height: "+this.frameh);
		}
	}.bind(this);

	this.img.src = assetsPath+"/images/"+src+ext;
}
ImageSource.prototype.draw = function(ctx, step) {
	if (!step) step = 0;
	if (!this.ready)
		return;

	ctx.drawImage(this.img,
		0, this.frameh * step,
		this.width, this.frameh,
		0, 0,
		this.width, this.frameh);
}

function Animation(imgSrc, type, loop, fps) {
	this.type = type || "forward";
	this.loop = loop || false;
	this.imgSrc = imgSrc;
	this.fps = fps || 12;
	this.waitTime = 1000 / this.fps;

	this.doStep = false;

	if (type === "forward" || type === "bounce") {
		this.step = 0;
		this.direction = 1;
	} else if (type === "reverse" || type === "bounce-reverse") {
		this.step = -1;
		this.direction = -1;
	}

	// We don't care about the direction after setting this.direction
	if (this.type === "bounce-reverse")
		this.type = "bounce";
	else if (this.type === "reverse")
		this.type = "forward";
}
Animation.prototype.nextFrame = function() {
	if (!this.imgSrc.ready) {
		return;
	} else if (this.step === -1) {
		this.step = this.imgSrc.steps - 1;
		return;
	} else if (this.imgSrc.steps === 1) {
		return;
	}

	var next = this.step + this.direction;
	if (next < 0 || next > this.imgSrc.steps - 1) {
		if (this.loop) {
			if (this.type === "bounce") {
				this.direction = -this.direction;
				next = this.step + this.direction;
			} else if (this.type === "forward") {
				if (next < 0)
					next = this.imgSrc.steps - 1;
				else
					next = 0;
			}
		} else {
			this.doStep = false;
			return;
		}
	}
	this.step = next;
}
Animation.prototype.draw = function(ctx) {
	if (!this.imgSrc.ready)
		return;

	this.imgSrc.draw(ctx, this.step);

	if (this.doStep) {
		this.nextFrame();
		this.doStep = false;
		setTimeout(function() {
			this.doStep = true;
		}.bind(this), this.waitTime);
	}
}
Animation.prototype.play = function() {
	if (this.step !== -1)
		this.step = 0;
	this.doStep = true;
}
Animation.prototype.setStep = function(step) {
	if (step > this.imgSrc.steps - 1)
		this.step = this.imgSrc.steps - 1;
	else if (step < 0)
		this.step = 0;
	else
		this.step = step;
}
