//#region Class

import { CoroutineV2 } from "../../Engine/CatanEngine/CoroutineV2/CoroutineV2";

/** 表演節目序列處理系統(playShow Sequence Processing System) */
export default class PSPS {
	//#region public

	public ShowData: ShowDataClass[] = [];

	public IsRun: boolean = false;

	// /** 可以插隊時間 */
	// public CanCutInLineTime: number = null;

	//#endregion

	//#region private

	private _playShowFunction: (data: any) => IterableIterator<any> = null;

	//#endregion

	//#region Lifecycle

	/**
	 * 表演節目序列處理系統(PlayShow Sequence Processing System)
	 * @param playShowFunction 要表演的函式
	 * @example
	 * let CoroutineFunction: (data: any) => IterableIterator<any> = function* (data: any): IterableIterator<any> {}
	 * new PSPS(this.CoroutineFunction.bind(this));
	 */
	constructor(playShowFunction: (data: any) => IterableIterator<any>) {
		this.SetPlayShowFunction(playShowFunction);
	}

	public SetPlayShowFunction(playShowFunction: (data: any) => IterableIterator<any>): void {
		this._playShowFunction = playShowFunction;
	}

	//#endregion

	//#region playShow

	/** 增加表演資料 */
	public PushPlayShowData(data: any, priority: number = 0): void {
		const playShowData: ShowDataClass = new ShowDataClass(data, priority);
		this.ShowData.push(playShowData);
		this.ShowData.ObjectSort([true], ["Priority"]);
		if (!this.IsRun) {
			CoroutineV2.Single(this._performanceShowData()).Start(this);
		}
	}

	/** 表演 */
	private *_performanceShowData(): IterableIterator<any> {
		this.IsRun = true;
		if (this._playShowFunction) {
			const showData: ShowDataClass = this.ShowData.shift();
			const data: any = showData.Data;
			yield* this._playShowFunction(data);
		}
		if (this.ShowData.length > 0) {
			CoroutineV2.Single(this._performanceShowData()).Start(this);
			return;
		}
		this.StopPerformance();
	}

	/** 停止表演 */
	public StopPerformance(): void {
		this.IsRun = false;
		CoroutineV2.StopCoroutinesBy(this);
	}

	public ClearFromPriority(priority: any): void {
		let deleteDatas: ShowDataClass[] = [];
		for (let i: number = 0; i < this.ShowData.length; i++) {
			const showData: ShowDataClass = this.ShowData[i];
			if (showData.Priority === priority) {
				deleteDatas.push(showData);
			}
		}
		for (let i: number = 0; i < deleteDatas.length; i++) {
			const deleteData: ShowDataClass = deleteDatas[i];
			for (let j: number = 0; j < this.ShowData.length; j++) {
				const showData: ShowDataClass = this.ShowData[j];
				if (showData.Priority === deleteData.Priority) {
					this.ShowData.splice(j, 1);
					break;
				}
			}
		}
	}

	/** 清除所有表演 */
	public ClearPerformance(): void {
		this.IsRun = false;
		this.ShowData = [];
		CoroutineV2.StopCoroutinesBy(this);
	}

	//#endregion
}

/** ShowDataClass */
export class ShowDataClass {
	/** 優先度(越低越前面) */
	public Priority: number = 0;

	/** Data */
	public Data: any = null;

	constructor(data: any, priority: number) {
		this.Data = data;
		this.Priority = priority;
	}
}

//#endregion