/**
 * Created by rockyl on 2018/11/6.
 *
 * todo 如果isUsedToMask，就禁用缓存
 */

import Renderer from "./Renderer";
import {color, decorators} from "scilla";

const {dirtyFieldDetector} = decorators;

/**
 * 图形渲染组件
 */
export default class GraphicRenderer extends Renderer {
	/**
	 * 填充颜色
	 */
	@dirtyFieldDetector
	fillColor: color = '#42bce4';
	/**
	 * 边框颜色
	 */
	@dirtyFieldDetector
	borderColor: color = '#0899d0';
	/**
	 * 边框宽度
	 */
	@dirtyFieldDetector
	borderWidth = 0;

	/**
	 * 是否为mask
	 */
	@dirtyFieldDetector
	isMask = false;
	/**
	 * 是否显示mask
	 */
	@dirtyFieldDetector
	maskVisible = false;

	protected getUseCacheMode(){
		return this._useCacheMode && !this.isMask;
	}

	/**
	 * 获取图形尺寸
	 */
	protected getRenderSize(): any {
		return {width: 0, height: 0};
	}

	/**
	 * @inheritDoc
	 */
	protected beforeDraw() {
		super.beforeDraw();
		this.applyStyle();
		this.currentCanvasContext.beginPath();
	}

	/**
	 * @inheritDoc
	 */
	protected draw() {
		super.draw();

		if (this.isMask) {
			this._context.clip();
			this.maskVisible && this.fillAndStoke()
		} else {
			this.fillAndStoke()
		}
	}

	/**
	 * 应用渲染样式
	 */
	protected applyStyle() {
		const {currentCanvasContext, fillColor, borderColor, borderWidth} = this;

		currentCanvasContext.fillStyle = fillColor;
		if (borderWidth > 0) {
			currentCanvasContext.strokeStyle = borderColor;
			currentCanvasContext.lineWidth = borderWidth;
		}
	}

	/**
	 * 绘制
	 */
	protected fillAndStoke() {
		const {currentCanvasContext, borderWidth} = this;

		currentCanvasContext.fill();
		if (borderWidth > 0) {
			currentCanvasContext.stroke();
		}
	}

	/**
	 * @inheritDoc
	 */
	protected drawClip() {
		this.isMask && this.currentCanvasContext.save();
	}

	/**
	 * @inheritDoc
	 */
	afterUpdate() {
		this.isMask && this.currentCanvasContext.restore();
	}

	afterEditorUpdate(){
		this.afterUpdate();
	}

	measureBounds() {
		if (!this.dirty) {
			return;
		}

		this._margin = this.borderWidth;

		const {bounds, transform: {explicitWidth: tWidth, explicitHeight: tHeight}} = this;
		const {width: sWidth, height: sHeight} = this.getRenderSize();

		bounds.width = isNaN(tWidth) ? sWidth : tWidth;
		bounds.height = isNaN(tHeight) ? sHeight : tHeight;

		super.measureBounds();
	}
}
