// this._degToRad = function(degree){ return Math.PI * degree / 180; };
// this._radToDeg = function(radian){ return radian / Math.PI * 180; };

var Matrix2D = Class.create({
	initialize: function(arg){
		Object.extend(this, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0})
		if (arg) {
			Object.extend(this, arg)
		}
	}

	, multiply: function(other){
		var ret = new Matrix2D()
		other = Matrix2D.normalize(other)
		ret.xx = this.xx * other.xx + this.xy * other.yx
		ret.xy = this.xx * other.xy + this.xy * other.yy
		ret.yx = this.yx * other.xx + this.yy * other.yx
		ret.yy = this.yx * other.xy + this.yy * other.yy
		ret.dx = this.xx * other.dx + this.xy * other.dy + this.dx
		ret.dy = this.yx * other.dx + this.yy * other.dy + this.dy
		return ret
	}
	
	, translate: function(x, y){
		return this.multiply(new Matrix2D({dx: x, dy: y}))
	}
	, scale: function(xs, ys){
		return this.multiply(new Matrix2D({xx: xs, yy: ys}))
	}
	, rotate: function(angle) {
		var c = Math.cos(angle);
		var s = Math.sin(angle);
		return this.multiply(new Matrix2D({xx: c, xy: -s, yx: s, yy: c}))
	}
	, skewX: function(angle) {
		return this.multiply(new Matrix2D({xy: -Math.tan(angle)}))
	}
	, skewY: function(angle){
		return this.multiply(new Matrix2D({yx: Math.tan(angle)}))
	}

	, scaleAt: function(xs, ys, x, y){
		return this.translate(x, y).scale(xs, ys).translate(-x, -y)
	}
	, rotateAt: function(angle, x, y){
		return this.translate(x, y).rotate(angle).translate(-x, -y)
	}
	, skewXAt: function(angle, x, y){
		return this.translate(x, y).skewX(angle).translate(-x, -y)
	}
	, skewYAt: function(angle, x, y){
		return this.translate(x, y).skewY(angle).translate(-x, -y)
	}
})

Matrix2D.identity = new Matrix2D()
Matrix2D.flipX = new Matrix2D({xx: -1})
Matrix2D.flipY = new Matrix2D({yy: -1})
Matrix2D.flipXY = new Matrix2D({xx: -1, yy: -1})
Matrix2D.normalize = function(matrix){
	return (matrix instanceof Matrix2D) ? matrix : new Matrix2D(matrix)
}
