/**
 * Created by rockyl on 2018-12-12.
 *
 * 弹层
 */

import DialogContent from "./DialogContent";
import RectRenderer from "components/renderer/RectRenderer";
import TouchInterrupt from "components/base/TouchInterrupt";
import Transform from "components/base/Transform";
import ScillaComponent from "components/base/ScillaComponent";
import {none} from "./PopupEffect";
import {createTween} from "scilla";

export default class Popup extends ScillaComponent {
	blackLayerDuration = 300;

	private _bgRenderer: RectRenderer;
	private _touchInterrupt: TouchInterrupt;
	private _dialogStack = [];

	onAwake() {
		super.onAwake();

		this._touchInterrupt = this.getComponent(TouchInterrupt);
		this._touchInterrupt.enabled = false;

		const bgRenderer = this._bgRenderer = this.getComponent(RectRenderer);
		bgRenderer.enabled = false;
	}

	onUpdate(t) {
		super.onUpdate(t);
	}

	onSleep() {
		super.onSleep();
	}

	onDestroy() {
		super.onDestroy();
	}

	setBgVisible(visible) {
		if(visible){
			this._bgRenderer.enabled = true;
		}
		this._bgRenderer.alpha = visible ? 0 : 1;
		createTween(this, this._bgRenderer, true)
			.to({alpha: visible ? 1 : 0}, this.blackLayerDuration)
			.call(()=>{
				if(!visible){
					this._bgRenderer.enabled = false;
				}
			});
	}

	getDialogInStack(name){
		let result;
		for(let dialog of this._dialogStack){
			if(dialog.name === name){
				result = dialog;
				break;
			}
		}
		return result;
	}

	private bringToTop(dialogConfig){
		let index = this._dialogStack.indexOf(dialogConfig);
		if(index >= 0){
			this._dialogStack.splice(index, 1);
		}
		this._dialogStack.push(dialogConfig);
	}

	private delete(dialogConfig){
		let index = this._dialogStack.indexOf(dialogConfig);
		this._dialogStack.splice(index, 1);
	}

	async showDialog(name, data?, callback?) {
		let dialogConfig = this.getDialogInStack(name);

		let dialog = this.entity.getChildrenByName(name)[0];

		if(!dialogConfig){
			dialogConfig = {
				name, data, callback, dialog
			};
			dialog.enabled = true;
		}

		this.bringToTop(dialogConfig);

		const parent = dialog.parent;
		parent.removeChild(dialog);
		parent.addChildAt(dialog, parent.children.length);

		this.setBgVisible(true);
		this._touchInterrupt.enabled = true;

		const content: DialogContent = dialog.getComponent(DialogContent);
		content && content.setup(data);

		const transform = dialog.getComponent(Transform);

		const effect = content ? content.effectImpl : none;
		const effectOptions = content ? content.showEffectOptions : null;

		await effect.show(transform, effectOptions);
	}

	async hideDialog(name, action?: string, data?) {
		let dialogConfig = this.getDialogInStack(name);

		if(!dialogConfig){
			return;
		}

		let dialog = this.entity.getChildrenByName(name)[0];

		this.delete(dialogConfig);
		if(this._dialogStack.length === 0){
			this.setBgVisible(false);
			this._touchInterrupt.enabled = false;
		}

		const transform = dialog.getComponent(Transform);

		const content: DialogContent = dialog.getComponent(DialogContent);

		const effect = content ? content.effectImpl : none;
		const effectOptions = content ? content.hideEffectOptions : null;

		await effect.hide(transform, effectOptions);
		dialog.enabled = false;

		if (dialogConfig.callback) {
			dialogConfig.callback(action, data);
			dialogConfig.callback = null;
		}
	}

	hideAll(){
		for(let dialog of this._dialogStack){
			this.hideDialog(dialog.name);
		}
	}
}
