import { ActionEnumerator } from "./Core/ActionEnumerator";
import { BaseEnumerator } from "./Core/BaseEnumerator";
import { CoroutineExecutor } from "./Core/CoroutineExecutor";
import { ParallelEnumerator } from "./Core/ParallelEnumerator";
import { SingleEnumerator } from "./Core/SingleEnumerator";
import { WaitTimeEnumerator } from "./Core/WaitTimeEnumerator";
import { IEnumeratorV2, IEnumeratorV2Started } from "./IEnumeratorV2";

export module CoroutineV2 {
	/**
	 * 啟動一般協程
	 */
	export function StartCoroutine(iterator: Iterator<any>, target?: any): IEnumeratorV2Started {
		return Single(iterator).Start(target);
	}

	/**
	 * 依據IEnumeratorV2.Start(target)綁定的目標, 來停止協程
	 * @param target
	 */
	export function StopCoroutinesBy(target: any) {
		CoroutineExecutor.instance.StopCoroutineBy(target);
	}

	/**
	 * 單一協程
	 */
	export function Single(iterator: Iterator<any>): IEnumeratorV2 {
		if (iterator instanceof BaseEnumerator) {
			return iterator;
		} else {
			return new SingleEnumerator(iterator);
		}
	}

	/**
	 * 平行協程
	 */
	export function Parallel(...iterators: Iterator<any>[]): IEnumeratorV2 {
		return new ParallelEnumerator(iterators);
	}

	/**
	 * 序列協程
	 */
	export function Serial(...iterators: Iterator<any>[]): IEnumeratorV2 {
		let [iterator, ...others] = iterators;
		if (iterator instanceof BaseEnumerator) {
			return iterator.ThenSerial(...others);
		} else {
			return new SingleEnumerator(iterator).ThenSerial(...others);
		}
	}

	/**
	 * 執行方法協程
	 * @param action 方法
	 * @param delaySeconds 延遲秒數
	 */
	export function Action(action: Function, delaySeconds?: number): IEnumeratorV2 {
		if (delaySeconds > 0) {
			return new WaitTimeEnumerator(delaySeconds).Then(new ActionEnumerator(action));
		} else {
			return new ActionEnumerator(action);
		}
	}

	/**
	 * 等待時間協程
	 * @param seconds 秒數
	 */
	export function WaitTime(seconds: number): IEnumeratorV2 {
		return new WaitTimeEnumerator(seconds);
	}
}