/**
 * Created by rockyl on 2018/11/6.
 */

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

const {dirtyFieldDetector} = decorators;

export enum FillMode {
	/**
	 * 正常
	 */
	NORMAL,
	/**
	 * 裁切
	 */
	SLICED,
	/**
	 * 瓦片
	 */
	TILED,
}

/**
 * 纹理渲染组件
 */
export default class TextureRenderer extends Renderer {
	/**
	 * 纹理资源
	 */
	@dirtyFieldDetector
	texture: Texture;

	/**
	 * 填充模式
	 */
	@dirtyFieldDetector
	fillMode: FillMode = FillMode.NORMAL;

	/**
	 * 滤镜数组
	 */
	@dirtyFieldDetector
	filters = [];

	private get hasFilters() {
		return this.filters && this.filters.length > 0;
	}

	/**
	 * 异步资源
	 * @param promise
	 */
	private set async_texture(promise: Promise<Texture>) {
		if(!promise){
			return;
		}
		promise.then(
			(texture) => {
				this.texture = texture;
			}
		)
	}

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

		this.drawImage();
		this.applyFilters();

		/*const {context, texture, hasFilters} = this;
		if (texture && hasFilters) {
			const {bounds: {width: textureWidth, height: textureHeight}} = texture;

			//筛选阴影滤镜Shadow
			let s = this;
			let cf = s.filters;
			let cfLen = cf.length;
			let fId = -1;
			if (cfLen) {
				for (let i = 0; i < cfLen; i++) {
					if (s.filters[i].type == "Shadow") {
						fId = i;
						break;
					}
				}
			}
			if (fId >= 0) {
				let ctx: any = context;
				ctx.shadowBlur = cf[fId].blur;
				ctx.shadowColor = cf[fId].color;
				ctx.shadowOffsetX = cf[fId].offsetX;
				ctx.shadowOffsetY = cf[fId].offsetY;
				ctx.drawImage(this.cacheCanvas, 0, 0, textureWidth, textureHeight);
				ctx.shadowBlur = 0;
				ctx.shadowOffsetX = 0;
				ctx.shadowOffsetY = 0;
			} else {
				context.drawImage(this.cacheCanvas, 0, 0, textureWidth, textureHeight);
			}

			// context.drawImage(texture.img, x, y, textureWidth, textureHeight, -width * this.anchor.x, -height * this.anchor.y, width, height);
		}*/
	}

	/**
	 * 应用滤镜
	 */
	applyFilters() {
		if (!this.hasFilters) return;

		const {texture, filters, currentCanvasContext} = this;
		const {bounds: {width: textureWidth, height: textureHeight}} = texture;

		let imageData = currentCanvasContext.getImageData(0, 0, textureWidth, textureHeight);
		for (const filter of filters) {
			filter.drawFilter(imageData);
		}
		currentCanvasContext.putImageData(imageData, 0, 0);
	}

	/**
	 * 根据模式绘制图片
	 */
	drawImage() {
		if (!this.texture) {
			return;
		}

		const {texture, fillMode, currentCanvasContext, bounds: {width, height}} = this;
		const {bounds: {x, y, width: textureWidth, height: textureHeight}} = texture;

		switch (fillMode) {
			case FillMode.NORMAL:
				texture.drawToCanvas(currentCanvasContext, 0, 0, undefined, undefined, width, height);
				break;
			case FillMode.SLICED:

				break;
			case FillMode.TILED:
				const textureCanvas = texture.getCacheCanvas();
				const pattern = currentCanvasContext.createPattern(textureCanvas, 'repeat');
				currentCanvasContext.rect(0, 0, width, height);
				currentCanvasContext.fillStyle = pattern;
				currentCanvasContext.fill();
				break;
		}
	}

	/**
	 * @inheritDoc
	 */
	measureBounds() {
		if (!this.dirty) {
			return;
		}

		const {bounds, transform: {explicitWidth: tWidth, explicitHeight: tHeight}} = this;

		if (this.texture) {
			const {width: textureWidth, height: textureHeight} = this.texture;

			bounds.width = isNaN(tWidth) ? textureWidth : tWidth;
			bounds.height = isNaN(tHeight) ? textureHeight : tHeight;
		} else {
			bounds.width = isNaN(tWidth) ? 0 : tWidth;
			bounds.height = isNaN(tHeight) ? 0 : tHeight;
		}

		super.measureBounds();
	}
}
