module jg {
	export class Shape extends E {
		style:ShapeStyle;
		type:ShapeType;
		syncObj:any;
		syncFunc:(shape:Shape) => void;
		static PI_200_PER:number = Math.PI * 2;
		clip:bool;

		constructor(width:number, height:number, style?:ShapeStyle, color?:any, type?:ShapeType) {
			super();
			this.x = 0;
			this.y = 0;
			this.width = width;
			this.height = height;
			this.style = style ? style : ShapeStyle.Stroke;
			if (color)
				this.setColor(color);
			this.type = type ? type : ShapeType.Rect;
		}

		setClip(value:bool) {
			this.clip = value;
			if (this.clip)
				this.disableTransform = true;
			else
				delete this.disableTransform;
		}

		setStyle(style:ShapeStyle) {
			this.style = style;
			this.setColor(this.getColor());
		}

		setLineWidth(width:number) {
			this.setDrawOption("lineWidth", width);
		}
		getLineWidth() {
			return this.getDrawOption("lineWidth");
		}

		setColor(color:any) {
			if (this.style == ShapeStyle.Stroke)
				this.setDrawOption("strokeStyle", color);
			else
				this.setDrawOption("fillStyle", color);
		}
		getColor() {
			if (this.style == ShapeStyle.Stroke)
				return this.getDrawOption("strokeStyle");
			else
				return this.getDrawOption("filltyle");
		}

		synchronize(syncObj:any, syncFunc:(shape:Shape) => void) {
			this.syncObj = syncObj;
			this.syncFunc = syncFunc;
		}

		draw(context:CanvasRenderingContext2D) {
			//arc, rect
			//style: fill, stroke
			if (this.syncObj)
				this.syncFunc.call(this.syncObj, this);
			if (this.clip) {
				//bad code. 回転などをサポートするための苦肉の処置
				context.save();
				context.translate(this.x, this.y);
				if (this.options)
					this.scene.game.renderer.useDrawOption(this, context);
			}
			context.beginPath();
			switch(this.type) {
				case ShapeType.Rect:
					context.rect(
						0,
						0,
						this.width,
						this.height
					);
					break;
				case ShapeType.Arc:
					var w2 = this.width / 2;
					context.arc(
						w2,
						w2,
						w2,
						0,
						Shape.PI_200_PER,
						false
					);
					break;
			}

			if (this.clip) {
				context.restore();
				context.clip();
			} else if (this.style == ShapeStyle.Fill)
				context.fill();
			else
				context.stroke();
		}
	}
}