import { layers, destroyLayers } from "../module/views/layers";
import { RES } from "../module/RES";
import { changeScene, destroyAllCtrls } from "../module/ctrls";
import { GAME_EVENT, GDispatcher } from "./index";
import { GameScene } from "./scenes/GameScene";
import { ResJson } from "./ResJson";
import { SkinJson } from "./SkinJson";
import { destroyWebNetData } from "./tools/WebNet";
import Tween = FYGE.Tween;
import Stage = FYGE.Stage;
import RENDERER_TYPE = FYGE.RENDERER_TYPE;
import Event = FYGE.Event;
import getEnv = FYGE.getEnv;
import {preloadRes} from "./PreloadRes";


export class Game {
	// 主舞台
	stage: Stage;
	private requestID;
	private _pause: boolean;
	private canvas: HTMLCanvasElement;

	constructor(
		canvas: HTMLCanvasElement,
		desWidth = 750,
		desHeight = 1624,
		divWidth?,
		divHeight?,
		renderType = RENDERER_TYPE.WEBGL,
		stageCenter = true,
		fixedHeight = false,
		resolution?,
	) {
		let sysInfo;
		// 淘宝小程序环境就用canvas初始化
		if (!window) {  // 自行处理吧，这么判断也不保险，万一淘宝小程序加进了window
			FYGE.initedByCanvas(canvas);    // 里面会设置env为tb，这个很重要
			// @ts-ignore 存在my就初始化
			sysInfo = my.getSystemInfoSync();
		}

		divWidth = divWidth || sysInfo?.windowWidth || document.body.clientWidth;
		divHeight = divHeight || sysInfo?.windowHeight || document.body.clientHeight;
		resolution = resolution || sysInfo?.pixelRatio || window.devicePixelRatio || 1;

		// 建舞台
		const stage = this.stage = new Stage(
			canvas,
			desWidth,       // 设计宽度，按设计搞给的就行
			desHeight,      // 设计高度
			divWidth,       // 显示宽度，全屏就是屏幕宽度
			divHeight,      // 显示高度，全屏就是屏幕高度
			renderType,     // 渲染模式canvas
			stageCenter,    // 视窗居中裁切
			fixedHeight,    // 不定高，定宽适配
			resolution,     // 分辨率
		);

		this.canvas = canvas; // 赋值下，为了下面的destroy的cancelAnimationFrame

		// stage初始化
		stage.addEventListener(Event.INIT_STAGE, this.onAddToStage, this);

		// 循环
		this.loop();

	}

	private loop = () => {
		if (!this._pause) {
			Tween.flush();
			this.stage.flush();
		}

		getEnv() == "tb"
			// @ts-ignore
			? this.requestID = this.canvas.requestAnimationFrame(this.loop)
			: this.requestID = window.requestAnimationFrame(this.loop);
	}


	private async onAddToStage() {
		// 初始化层级
		layers.init(this.stage);
		console.log("初始化层级完成");

		// preload common res
		await preloadRes('common')

		// h5环境时，隐藏加载中
		if (getEnv() == "web" && document.getElementById("__loading__")) {
			document.getElementById("__loading__").style.display = "none";
		}

		changeScene(GameScene);
	}

	initWebEvent() {
		const mouseEvent = this.stage.onMouseEvent.bind(this.stage);
		this.canvas.addEventListener("touchstart", mouseEvent, false);
		this.canvas.addEventListener('touchmove', mouseEvent, false);
		this.canvas.addEventListener('touchend', mouseEvent, false);
	}

	run() {
		this._pause = false;
		// @ts-ignore Tween计时清零
		Tween._lastTime = null;
		// 触发onShow
		GDispatcher.dispatchEvent({ type: GAME_EVENT.ON_SHOW });
	}

	/**
	 * 在小程序隐藏时调用onHide
	 */
	pause() {
		// 触发onHide
		GDispatcher.dispatchEvent({ type: GAME_EVENT.ON_HIDE });
	}

	//在小程序页面卸载时调用onUnload，多次销毁后会有问题，再检查
	destroy() {
		// Tween都移除，注意吧，可能原先的也被移除,对于多page时注意，会把其他页面的也去掉
		Tween.removeAllTweens();
		// 停掉计时器

		// 为了兼容多page的canvas
		FYGE.getEnv() == "tb"
			// @ts-ignore
			? this.canvas.cancelAnimationFrame(this.requestID)
			: window.cancelAnimationFrame(this.requestID);

		// 层级销毁
		destroyLayers();

		// 销毁控制器
		destroyAllCtrls();

		// 舞台销毁
		this.stage.destroy();

		// 全局事件置空
		GDispatcher.removeAllEventListener();

		// 网络数据记录清空
		destroyWebNetData();
	}
}
