enum ShapeStyle {
	stroke,
	fill
}
enum ShapeType {
	rect,
	arc
}
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(area:Area, 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(area.x + this.x, area.y + 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();
	}
}