function AnimatedSprite(x, y, canvas) {
	AnimatedSprite.baseConstructor.call(this, x, y, canvas);
	this.spriteMaps = {};
	this.frameData = {};
	this.currentFrame = 0;
	this.animationSequence = [];
	this.doesLoop = true;
	this.frameRate = 30;
	this.frameRateStep = 1;
	this.intervalID = null;
	this.animationIsRunning = false;
}

extend(AnimatedSprite, Sprite);

AnimatedSprite.prototype.render = function(label) {
	this.frameData[label] = this.context.createImageData(this.getWidth(), this.getHeight());
	this.renderPixels(this.frameData[label], this.spriteMaps[label], this.colorMap);
}

AnimatedSprite.prototype.setDirectionH = function(direction) {
	if (this.directionH != direction) {
	    this.directionH = direction;
		for (var key in this.frameData) {
			this.render(key);
		}
	}
	return this;
}

AnimatedSprite.prototype.getCurrentFrameData = function() {
	// console.log("Getting the current frame data...");
	return this.frameData[this.getCurrentSpriteLabel()];
}

AnimatedSprite.prototype.getCurrentSpriteMap = function() {
	// console.log("Getting current sprite map...");
	return this.spriteMaps[this.getCurrentSpriteLabel()];
}

AnimatedSprite.prototype.getCurrentSpriteLabel = function() {
	// console.log("Animation Sequence: " + this.animationSequence + ", the currentFrame is: " + this.currentFrame);
	return this.animationSequence[this.currentFrame];
}

AnimatedSprite.prototype.setBaseSpriteWidth = function(width) {
	this.xPixels = width;
	return this;
}

AnimatedSprite.prototype.setBaseSpriteHeight = function(height) {
	this.yPixels = height;
	return this;
}

AnimatedSprite.prototype.setBaseSpriteSize = function(width, height) {
	return this.setBaseSpriteWidth(width).setBaseSpriteHeight(height);
}

AnimatedSprite.prototype.addSpriteMap = function(label, map) {
	this.spriteMaps[label] = map;
	this.render(label);
	return this;
}

AnimatedSprite.prototype.setMaxFrameRate = function(frameRate) {
	this.maxFrameRate = frameRate;
	return this;
}

AnimatedSprite.prototype.setFrameRate = function(frameRate) {
	this.frameRate = frameRate;
	return this;
}

AnimatedSprite.prototype.addToAnimationSequenceByLabel = function(label) {
	this.animationSequence.push(label);
	return this;
}

AnimatedSprite.prototype.setAnimationToLoop = function(value) {
	this.doesLoop = value;
	return this;
}

AnimatedSprite.prototype.startAnimation = function()  {
	if (!this.animationIsRunning) {
		this.intervalID = setInterval(this.stepAnimationSequence, 1000/this.frameRate, this);
		this.animationIsRunning = true;
	}
	return this;
}

AnimatedSprite.prototype.stopAnimation = function() {
	if (this.animationIsRunning) {
		clearInterval(this.intervalID);
		this.animationIsRunning = false;
	}
	return this;
}

AnimatedSprite.prototype.setFrameRateStep = function(frameRateStep) {
	this.frameRateStep = frameRateStep;
	return this;
}

AnimatedSprite.prototype.decelerateAnimation = function() {
	this.frameRate -= this.frameRateStep;
	return this;
}

AnimatedSprite.prototype.accelerateAnimation = function() {
	this.frameRate += this.frameRateStep;
	return this;
}

AnimatedSprite.prototype.stepAnimationSequence = function(obj) {
	if (!obj.animationIsRunning) {
		console.log("Warning: animation is not running, we're not going to step.");
		return obj;
	}
	var length = obj.animationSequence.length;
	if (length > 0) {
		if (obj.currentFrame < 0 || obj.currentFrame > length - 1) {
			obj.currentFrame = 0;
		} else {
			obj.currentFrame++;
			if (obj.doesLoop) {
				if (obj.currentFrame >= length) {
					obj.currentFrame = 0;
				}
			} else {
				obj.currentFrame--;
			}
		}
	}
	return obj;
}

AnimatedSprite.prototype.draw = function() {
	var spriteLabel = this.getCurrentSpriteLabel();
	if (!this.frameData[spriteLabel] || !this.context) {
		return false;
	}
	this.context.putImageData(this.getCurrentFrameData(), this.x, this.y);
	return this;
}
