var CollisionEngine = Class.create({
	sprite: null,
	topLeftAngle: 0,
	topRightAngle: 0,
	bottomRightAngle: 0,
	bottomLeftAngle: 0,
	exclude: null,

	TOP: 0,
	RIGHT: 1,
	BOTTOM: 2,
	LEFT: 3,

	initialize: function(sprite, exclude) {
		this.sprite = sprite;
		this.exclude = exclude;
	},

	checkCollision: function(sprite1, sprite2) {
		return false;
	},

	getDirection: function(vector) {
		angle = Math.atan2(vector.y, vector.x);

		if(angle >= 0 && angle <= Math.PI) {
			if(angle <= this.topLeftAngle && angle >= this.topRightAngle) {
				return this.BOTTOM;
			} else if (angle > this.topLeftAngle) {
				return this.RIGHT;
			} else if (angle < this.topRightAngle) {
				return this.LEFT;
			}
		} else {
			angle = -1 * angle;
			if(angle <= -1 * this.bottomLeftAngle && angle >= -1 * this.bottomRightAngle) {
				return this.TOP;
			} else if (angle > -1 * this.bottomLeftAngle) {
				return this.RIGHT;
			} else if (angle < -1 * this.bottomRightAngle) {
				return this.LEFT;
			}
		}
		return this.BOTTOM;
	}
});

var SquareCollisionEngine = Class.create(CollisionEngine, {
	initialize: function($super, sprite, exclude) {
		$super(sprite, exclude);

		center = this.getCentrePoint(sprite);

		vector = new Vector();
		topLeft = new Vector(sprite.getX(), sprite.getY());
		bottomLeft = new Vector(sprite.getX(), sprite.getY() + sprite.getHeight());
		topRight = new Vector(sprite.getX() + sprite.getWidth(), sprite.getY());
		bottomRight = new Vector(sprite.getX() + sprite.getWidth(), sprite.getY() + sprite.getHeight());

		topLeftVector = vector.subtract(topLeft, center);
		topRightVector = vector.subtract(topRight, center);
		bottomRightVector = vector.subtract(bottomRight, center);
		bottomLeftVector = vector.subtract(bottomLeft, center);

		// Invert the angles because we have changes the (0,0) (The y-axis is inverted)
		this.topLeftAngle = -1 * topLeftVector.toPolar().angle;
		this.topRightAngle = -1 * topRightVector.toPolar().angle;
		this.bottomLeftAngle = -1 * bottomLeftVector.toPolar().angle;
		this.bottomRightAngle = -1 * bottomRightVector.toPolar().angle;
	},

	getCentrePoint: function(sprite) {
		return new Vector(sprite.getX() + (sprite.getWidth()) / 2, sprite.getY() + (sprite.getHeight() / 2));
	},

	checkCollision: function(sprite) {
		classNames = sprite.element.className.split(' ');
		
		for(var i = 0; i < classNames.length; i++) {
			if(this.exclude.indexOf(classNames[i]) != -1) {
				return false;
			}
		}

		centre1X = this.sprite.getX() + (this.sprite.getWidth() / 2);
		centre1Y = this.sprite.canvas.getHeight() - this.sprite.getY() + (this.sprite.getHeight() / 2);
		
		centre2X = sprite.getX() + (sprite.getWidth() / 2);
		centre2Y = sprite.canvas.getHeight() - sprite.getY() + (sprite.getHeight() / 2);

		distanceX = Math.abs(centre1X - centre2X);
		distanceY = Math.abs(centre1Y - centre2Y);

		if((this.sprite.getWidth() / 2) + (sprite.getWidth() / 2) > distanceX && (this.sprite.getHeight() / 2) + (sprite.getHeight() / 2) > distanceY) {
			vector = new Vector();
			var direction = this.getDirection(vector.subtract(new Vector(centre2X, centre2Y), new Vector(centre1X, centre1Y)));
			return new Collision(direction, sprite);
		}
		return false;
	
	}
});

var CircularCollisionEngine = Class.create(CollisionEngine, {
	initialize: function($super, sprite, exclude) {
		$super(sprite, exclude);
	
		this.topLeftAngle = 135;
		this.topRightAngle = -135;
		this.bottomRightAngle = -45;
		this.bottomLeftAngle = 45;
	},

	getCollisionRadius: function(sprite) {
		return Math.max(sprite.getHeight() / 2, sprite.getWidth() / 2);
	},

	getCentrePoint: function(sprite) {
		return new Vector(sprite.getX() + Math.floor(sprite.getWidth() / 2), sprite.getY() + Math.floor(sprite.getHeight() / 2));
	},

	checkCollision: function(sprite) {
		vector = new Vector();

		radius1 = this.getCollisionRadius(this.sprite);
		radius2 = this.getCollisionRadius(sprite);
		centre1 = this.getCentrePoint(this.sprite);
		centre2 = this.getCentrePoint(sprite);

		resultant = vector.subtract(centre1, centre2);

		if(Math.pow(radius1 + radius2, 2) > Math.pow(resultant.x, 2) + Math.pow(resultant.y, 2)) {
			var direction = this.getDirection(resultant);
			return new Collision(direction, sprite);
		}
		return false;
	}
});

