import { onHomeworkFinish, RandomInt, playAudio, playDragonBoneAnimation, getSprNode, popParticle, asyncDelay } from "../script/util";
import { defaultData } from "../script/defaultData";
import { GameServer } from "../script/server";
import { NetworkHelper } from "../script/NetworkHelper";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";


cc.Class({

	extends: MyCocosSceneComponent,//cc.Component,

	properties: {
		paint: {
			default: null,
			type: cc.Node
		},

		paint2: {
			default: null,
			type: cc.Node
		},

		color_paint: {
			default: null,
			type: cc.Node
		},

		color_selector: {
			default: null,
			type: cc.Node
		},

		coolcat: {
			default: null,
			type: cc.Node
		},

		btn_submit: {
			default: null,
			type: cc.Button
		},

		btn_next: {
			default: null,
			type: cc.Button
		},

		btn_return: {
			default: null,
			type: cc.Button
		},

		color_buttons: {
			default: [],
			type: cc.Button
		}

	},

	ctor() {
		cc.macro.CLEANUP_IMAGE_CACHE = false;
	},

	// 生命周期 onLoad
	onLoad() {

		this._timeoutIds = [];
		this._intervalIds = [];
		this.initSceneData();
		this.initSize();
	},

	_imageResList: null,
	_audioResList: null,
	_animaResList: null,
	initSceneData() {
		this._imageResList = [];
		this._audioResList = [];
		this._animaResList = [];
	},

	_designSize: null,  // 设计分辨率
	_frameSize: null,  // 屏幕分辨率
	_mapScaleMin: null,  // 场景中常用缩放（取大值）
	_mapScaleMax: null,  // 场景中常用缩放（取小值）
	_cocosScale: null,  // cocos 自缩放 （较少用到）
	canvas: null,
	initSize() {
		// 注意cc.winSize只有在适配后(修改fitHeight/fitWidth后)才能获取到正确的值,因此使用cc.getFrameSize()来获取初始的屏幕大小
		let screen_size = cc.view.getFrameSize().width / cc.view.getFrameSize().height
		let design_size = cc.Canvas.instance.designResolution.width / cc.Canvas.instance.designResolution.height
		let f = screen_size >= design_size
		cc.Canvas.instance.fitHeight = f
		cc.Canvas.instance.fitWidth = !f

		const frameSize = cc.view.getFrameSize();
		this._frameSize = frameSize;

		this._designSize = cc.view.getDesignResolutionSize();

		let sx = cc.winSize.width / frameSize.width;
		let sy = cc.winSize.height / frameSize.height;
		this._cocosScale = Math.min(sx, sy);

		sx = frameSize.width / this._designSize.width;
		sy = frameSize.height / this._designSize.height;
		this._mapScaleMin = Math.min(sx, sy) * this._cocosScale;
		this._mapScaleMax = Math.max(sx, sy) * this._cocosScale;

		this.canvas = cc.find("Canvas");
	},


	// 生命周期 start
	isTeacher: null,
	serverAllUser: null,
	start() {

		console.log(" in start~~~",window.courseware)

		let getData = this.getData.bind(this);
		if (window && window.courseware) {
			getData = window.courseware.getData;
		}		

		getData((data, aspect) => {

			if (window['air']?.airClassInfo?.user?.classRole == 'tea') {
				this.isTeacher = true;
			}

			if (aspect) {
				console.log('aspect : ', aspect);
				this.serverAllUser = aspect.all_user;
			}

			this.user = window['air']?.airClassInfo?.user;
			console.log('this.user: ', this.user);

			console.log('data:', data);
			this.data = data || this.getDefaultData();
			this.data = JSON.parse(JSON.stringify(this.data))
			this.preloadItem()
		})

		this.preView();
	},

	preView() {
		this.coolcat.active = false;
		this._can_tap = false;
		this._submitted = false;

		let item, len = this.color_buttons.length;
		for (let i = 0; i < len; i++) {
			item = this.color_buttons[i];
			this.bindColorButton(item);
		}

		// this._alligator = this.bindAlligator(this.paint);
		// this._alligator2 = this.bindAlligator(this.paint2);
		this._alligator = this.paint.children[0];//this.bindAlligator(this.paint);
		this._alligator2 = this.paint2.children[0];//this.bindAlligator(this.paint2);


		// this.bindAlligatorButton(this._alligator);

		// this.btn_submit.node.on('click', ()=>{
		// 	if (this._can_tap != true)
		// 		return;

		// 	this._can_tap = false;
		// 	if (this.incomplete()){
		// 		playDragonBoneAnimation(this.coolcat, 'wrong', -1);
		// 		this.playAudioByName('lack', ()=>{
		// 			playDragonBoneAnimation(this.coolcat, 'normal');
		// 			this._can_tap = true;
		// 		});
		// 		return;
		// 	}

		// 	this.showResult();
		// 	playDragonBoneAnimation(this.coolcat, 'finish', -1);
		// 	this.playAudioByName('click');
		// 	this.playAudioByName('finish', ()=>{
		// 		playDragonBoneAnimation(this.coolcat, 'normal');
		// 		this._can_tap = true;
		// 		this._submitted = true;
		// 	});
		// });

		// if (this.btn_next != null){
		// 	this.btn_next.node.on('click', ()=>{
		// 		if (this._can_tap != true)
		// 			return;
		// 		if (this._submitted != true)
		// 			return;
		// 		this._can_tap = false;
		// 		this.playAudioByName('click');
		// 		this.updateItem();
		// 	});	
		// }

		// if (this.btn_return != null){
		// 	this.btn_return.node.on('click', ()=>{
		// 		this.playAudioByName('click');
		// 	});
		// }
		this.paint.on("click",()=>{
			if (this._can_tap != true)
			return;
			this._can_tap=false;
			cc.log("paint 点击");
			playDragonBoneAnimation(this.coolcat, 'wrong', -1);
			this.playAudioByUrl(this.data.wrongAudio,()=>{
				playDragonBoneAnimation(this.coolcat, 'normal', -1);
				this._can_tap = true;

			})	
		})
		this.paint.active = false;
		this.paint2.active = false;
		this.color_paint.active = false;
		this.coolcat.active = false;
		this.btn_submit.node.active = false;
	},

	showResult() {
		this.copyColor();
		this.paint.active = false;
		this.paint2.active = true;
		this.color_paint.active = false;
		this.btn_submit.node.active = false;
	},

	cleanColor() {
		this.color_paint.active = true;
		this.color_selector.active = false;
		this._color = cc.Color.WHITE;
		//this.initAlligator(this._alligator);
		//this.initAlligator(this._alligator2);
		this.paint.active = true;
		this.paint2.active = false;
		this.btn_submit.node.active = false;
	},

	copyColor() {
		let a1 = this._alligator;
		let a2 = this._alligator2;
		let len = a1.teeth.length;
		for (let i = 0; i < len; i++) {			
			let node=cc.instantiate(a1.teeth[i]);
			a2.addChild(node);
			// a2.teeth[i].color = a1.teeth[i].color;
			// a2.teeth[i].word.node.color = a1.teeth[i].word.node.color;
			// a2.teeth[i].word.string = a1.teeth[i].word.string;
		}
	},

	copyColorOnline() {
		let a1 = this._alligator;
		let len = a1.teeth.length;
		const teethDataArr = []
		for (let i = 0; i < len; i++) {
			const data = { color: '', wordColor: '', word: '' };
			data.color = a1.children[i].color.toHEX();//a1.teeth[i].color.toHEX();
			// data.wordColor = a1.teeth[i].word.node.color.toHEX();
			// data.word = a1.teeth[i].word.string;
			teethDataArr.push(data);
		}
		return teethDataArr;
	},

	async initAlligator(parent) {
		for(let i=0;i<this.data.images.length;i++){
			let image=this.data.images[i];
			let tooth=await this.getSprNodeByUrl(image.img);
			parent.addChild(tooth);
			// tooth.color = cc.Color.WHITE;
			tooth.painted = null;
		}
		// let tooth, len = node.teeth.length;
		// for (let i = 0; i < len; i++) {
		// 	tooth = node.teeth[i];
		// 	tooth.color = cc.Color.WHITE;
		// 	tooth.word.node.color = cc.Color.BLACK;
		// 	tooth.painted = null;
		// 	tooth.word.string = words[i];
		// }
	},

	bindAlligator(parent) {
		let node = parent.children[0];

		let teeth = [];
		let len = node.children.length;
		for (let i = 0; i < len; i++) {
			teeth[i] = node.children[i];
			// teeth[i].word = teeth[i].children[0].getComponent(cc.Label);
		}

		node.teeth = teeth;
		this.log(parent.name+"_bind:"+node.teeth.length);
		return node;
	},

	bindAlligatorButton(node) {
		let len = node.teeth.length;
		for (let i = 0; i < len; i++) {
			node.teeth[i].t_idx = i;
			this.bindTeethHit(node.teeth[i]);
		}
	},

	bindColorButton(button) {
		var clickEventHandler = new cc.Component.EventHandler();
		clickEventHandler.target = this.node;
		clickEventHandler.component = "Coloring_OL";
		clickEventHandler.handler = "moveSelector";
		clickEventHandler.customEventData = button.node;

		button.clickEvents.push(clickEventHandler);
	},

	moveSelector(event, customEventData) {
		if (this._can_tap != true)
			return;

		this.color_selector.active = true;
		this.color_selector.x = customEventData.x;
		this.color_selector.y = customEventData.y;
		this._color = this.getColor(customEventData.name);
		this.playAudioByName('click');
		playDragonBoneAnimation(this.coolcat, 'normal');
	},

	getData(func) {
		if (window && window.courseware) {
			window.courseware.getData(func, 'scene');
			return;
		}

		const middleLayer = cc.find('middleLayer');
		if (middleLayer) {
			const middleLayerComponent = middleLayer.getComponent('middleLayer');
			middleLayerComponent.getData(func);
			return;
		}

		func(this.getDefaultData());
	},

	getDefaultData() {
		return defaultData;
	},

	preloadItem() {
		this.preload();
	},

	preload() {

		console.log(' in preload~ ')
		const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
		cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {

			this.addServerListener();
			// this.loadEnd();
			if (window && window["air"]) {
				window["air"].hideAirClassLoading();
			}

			cc.debug.setDisplayStats(false);
		});
	},

	addServerListener() {

		console.log(' in addServerListener');
		if (window.air) {
			window.air.onCourseInScreen = (next) => {
				this.loadEnd();
				next();
			}
		}
		else{
			this.loadEnd();
		}

		const c = window.courseware;
		if (!c) {
			return;
		}

		// c.onEvent('userchange', (data, next) => {
		// 	console.log('in userchange : ', data);
		// 	this.checkAddUser(data);
		// 	next();
		// });

		// c.onEvent('game_start', (data, next) => {
		// 	console.log('in game_start : ', data);
		// 	this.gameStart()
		// 	// next();
		// });

		// c.onEvent('game_end', (data, next) => {
		// 	console.log('in game_end : ', data);
		// 	this.gameEnd(data);
		// 	next();
		// });

		// c.onEvent('get_good', (data, next) => {
		// 	console.log('in get_good : ', data);
		// 	this.getGood(data);
		// 	next();
		// });
		

	},

	checkAddUser(user) {
		if (!user.connected) {
			console.log('connected = false , user: ', user)
			this.serverAllUser = user.all_user;
			return;
		}



		this.addUser(user);
	},


	loadEnd() {

		console.log('~~~~~~~');
		this.initNetwork();
		// this.initGameServer();
		// this.initMatchingView();

	},

	async initNetwork() {
		console.log(' in initNetwork ');
		const nh = new NetworkHelper();
		this.networkHelper = nh;

		this.addNetworkListener(nh);

		console.log('~~~~~~~ 2');


		this.playerId = await nh.init('OP10_online', 6);
		const room = nh.room;

		console.log('room: ', room);
		// console.log('room Json: ', JSON.stringify(room.roomInfo));
		console.log('this.playerId: ', this.playerId);
		this.initServerAllUser(room);

		console.log('~~~~~~~ 3');



		this.initMatchingView();


		console.log('~~~~~~~ 4');


		this.networkHelper.startFrameSync();

		this.checkGameStart();



	},

	checkGameStart() {
		// 8秒后自动开始

		if (this.isGameStart) {
			return;
		}
		this._timeoutIds.push(setTimeout(() => {
			this.checkIsTeacher();
			if (this.isTeacher) {

				this.networkHelper.closeRoom();
				this.addAiUser();
			} else {

				this.checkGameStart();
			}
		}, 8000));
	},

	startForce() {
		this._timeoutIds.push(setTimeout(() => {
			this.networkHelper.closeRoom();
			this.addAiUser();
		}, 5000));
	},


	addAiUser() {
		const id = new Date().getTime();
		const len = 8 - this.serverAllUser.length;
		for (let i = 0; i < len; i++) {
			const aiId = id + i;

			const data = { id: aiId, name: this.playerInfoData[i].name }

			this.sendServerEvent('add_ai', data);
		}
	},

	checkIsTeacher(room) {
		const playerList = this.networkHelper.room.roomInfo.playerList;

		console.log(' playerList: ', JSON.stringify(playerList));
		for (let i = 0; i < playerList.length; i++) {
			if (playerList[i].commonNetworkState == 1) {

				console.log('this.playerId : ', this.playerId);
				console.log('playerList[i].id : ', playerList[i].id);
				if (this.playerId == playerList[i].id) {
					this.isTeacher = true;
					return;
				}
			}
		}

	},

	teacherEnd() {

		this.networkHelper.sendFrame({ type: 'game_end', data: {} });
		return;

		const c = window.courseware;
		if (!c) {
			return;
		}
		console.log('getAnswer  start ..')

		c.getAnswer({ templateName: 'OP10_online' }, (res) => {
			console.log('getAnswer res: ', res);

			if (res) {
				this.networkHelper.sendFrame({ type: 'game_end', data: res });

				// this.sendEvent('game_end', res);
			}
		})

	},

	initServerAllUser(room) {
		const roomInfo = room.roomInfo
		this.serverAllUser = roomInfo.playerList;
	},

	addNetworkListener(nh) {


		nh.on('playerJoin', (event) => {
			// if (this.server) {
			// 		this.server.onPlayerJoin(event);
			// }
			this.log("playerJoin", (event));

			this.onPlayerJoin(event.data);

		});
		nh.on('playerLeave', (event) => {
			this.log("playerLeave" + JSON.stringify(event));
		});
		nh.on('gameStart', (event) => {

		});
		nh.on('frameEvent', (event) => {

			if (event.data.frame.items.length > 0) {
				console.log('frameEvent: ', event)
			}

			event.data.frame.items.forEach(item => {

				const res = item.data;
				switch (res.type) {
					case 'game_end':
						console.log(' in game_end ~')
						this.gameEnd(res.data);
						break;

					case 'game_start':
						console.log('in game_start ~ ');
						this.gameStart()
						return;

					case 'send_result':
						console.log('in send_result ~ ');
						this.setPlayerResult(res.data);
						return;

					case 'get_good':
						console.log('in get_good ~ ');
						this.getGood(res.data);
						return;

					case 'add_ai':
						this.onAddAi(res.data);
						return;

				}

			})
		});


	},

	onPlayerJoin(data) {

		let user = { id: data.joinPlayerId };

		console.log(' in onPlayerJoin 1 ', JSON.stringify(user));

		const playerList = data.roomInfo.playerList;
		for (let i = 0; i < playerList.length; i++) {
			if (playerList[i].id == user.id) {
				user.name = playerList[i].name;
			}
		}

		const len = this.serverAllUser.length;
		user.name = this.playerInfoData[len].name;

		console.log(' in onPlayerJoin 2 ', JSON.stringify(user));

		this.addUser(user)
	},

	onAddAi(data) {
		this.addUser({ id: data.id, name: data.name, isAi: true })
	},

	setPlayerResult(data) {
		const { uuid } = data;
		this.gameEndData[uuid] = data;

		for (let i = 0; i < this.serverAllUser.length; i++) {
			if (this.serverAllUser[i].id == uuid) {
				this.serverAllUser[i].result = data;
			}
		}

		if (this.resultLayer) {
			this.initOtherPlayerItem();
		}
	},


	gameEndData: null,
	initData() {
		this.gameEndData = {};
	},


	gameStart() {

		console.log('!!!gameStart')
		if (this.isGameStart) {
			return;
		}
		this.isGameStart = true;
		this.initData();
		this.initView();
		this.hideLoadingLayer();
		// this.showResultView();
	},

	hideLoadingLayer() {
		const ll = cc.find('Canvas/OP10_LoadingLayer');
		if (ll) {
			ll.active = false;
		}
	},


	initOnlinePart() {



		this.initTimeStrip();
		this.initTimer();

		// if (this.isTeacher) {
		// 	this.gameServer.gameTimeStart();
		// }

	},


	gameServer: null,
	initGameServer() {

		console.log(' in initMatching ');
		if (this.isTeacher) {

			console.log('gameserver start')

			const gameServer = new GameServer();
			gameServer.setNetworkHelper(this.networkHelper);
			this.gameServer = gameServer;
		}

	},

	async getOneItem(teethDataArr, uuid) {

		const mainArea = cc.find('Canvas/bg/main_area_small');
		const item = cc.instantiate(mainArea);
		item.active = true;
		const paint = cc.find('paint', item)

		let spriteFrame=await this.getSpriteFrimeByUrl(this.data.bg);
		let bg1=paint.getChildByName("alligator_img");
		bg1.getComponent(cc.Sprite).spriteFrame=spriteFrame;

		const alligator = this.bindAlligator(paint);
		alligator.destroyAllChildren();
		if (teethDataArr && teethDataArr.length > 0) {
			for (let i = 0; i < teethDataArr.length; i++) {
				let image=this.data.images[i];
				let tooth=await this.getSprNodeByUrl(image.img);
				tooth.color = new cc.Color().fromHEX(teethDataArr[i].color);
				alligator.addChild(tooth);
				// alligator.teeth[i].color = new cc.Color().fromHEX(teethDataArr[i].color);
				// alligator.teeth[i].word.node.color = new cc.Color().fromHEX(teethDataArr[i].wordColor);
				// alligator.teeth[i].word.string = teethDataArr[i].word;
			}
		} else {

			teethDataArr = this.teethDataArr;
			for (let i = 0; i < teethDataArr.length; i++) {
				alligator.teeth[i].color = cc.Color.WHITE
				// alligator.teeth[i].word.node.color = cc.Color.BLACK;
				// alligator.teeth[i].word.string = teethDataArr[i].word;
			}
		}
		item.userId = uuid;

		this.addItemName(item);
		this.addItemIcon(item);
		return item;
	},

	addItemName(item) {

		console.log(' in addItemName, item.userId: ', item.userId);
		console.log('serverAllUser:', this.serverAllUser);

		const nameBg = this.getSprNode('name_bg');
		nameBg.y = -100 // + nameBg.height / 2;

		const labelNode = this.getScoreLabel();
		const label = labelNode.getComponent(cc.Label);
		nameBg.addChild(labelNode);
		label.string = this.getUserName(item.userId);

		item.addChild(nameBg);
	},

	getUserName(uuid) {
		const arr = this.serverAllUser;
		for (let i = 0; i < arr.length; i++) {
			if (this.serverAllUser[i].id == uuid) {
				return this.serverAllUser[i].name;
			}
		}
	},

	selfScoreLabel: null,
	addItemIcon(item) {

		const scoreBg = this.getSprNode('score_bg');
		item.addChild(scoreBg);
		scoreBg.y = -220;
		scoreBg.x = scoreBg.width / 2;

		const scoreLabelNode = this.getScoreLabel();
		const scoreLabel = scoreLabelNode.getComponent(cc.Label);
		scoreLabel.lineHeight = scoreBg.height;
		scoreLabel.string = '0';
		scoreLabelNode.x = 7;
		scoreLabelNode.y = -22;
		scoreBg.addChild(scoreLabelNode);

		item.scoreLabel = scoreLabel;

		const icon = this.getSprNode('smiling_face');
		item.addChild(icon);
		icon.y = -220;

		icon.on('touchstart', () => {
			if (icon.isClicked) {
				return;
			}
			if (this.isGoodEnd) {
				return
			}

			if (item.userId == this.playerId) {
				return;
			}
			icon.isClicked = true;
			// icon.active = false;
			this.sendServerEvent('get_good', item.userId)
			// this.addItemParticle(item);
		})

		item.scoreLabelBg = scoreBg;
		item.icon = icon;
		// this.selfScoreLabel = scoreLabel;

	},

	addItemParticle(item) {
		const particle = this.getSprNode('star');
		popParticle(item, { x: 0, y: 0 }, particle, 0.8);
		this.playAudioByName('star');
	},

	getGood(userId) {

		console.log('in getGood userId: ', userId);
		console.log('resultItemArr: ', this.resultItemArr);

		for (let i = 0; i < this.resultItemArr.length; i++) {
			const item = this.resultItemArr[i];
			if (item.userId == userId) {

				// if (userId == this.user.uuid) {
				// 	this.addScore();
				// }
				this.addScore(item);
				this.addItemParticle(item);

				return;
			}
		}
	},

	addScore(item) {
		const score = Number(item.scoreLabel.string);
		item.scoreLabel.string = (score + 1).toString();

		if (item.userId == this.playerId) {
			this.selfScore += 1;
		}
	},

	_timer: null,
	_curTime: null,
	_totalTime: null,
	initTimer() {

		this.cleanTimer();
		this._totalTime = 20; //总时长
		this._curTime = 0;

		this.isTimingShow = true;
	},


	updateTimer(dt) {
		if (!this.isTimingShow) {
			return;
		}

		this._curTime += dt
		let percent = 1 - Math.round(this._curTime / this._totalTime * 10000) / 10000;
		if (percent <= 0) {
			percent = 0;
			this.timingEnd();
			this.isTimingShow = false;
		}
		this.refreshTimeStrip(percent);
	},

	cleanTimer() {
		if (this._timer) {
			clearInterval(this._timer);
		}
	},


	_timeStrip: null,
	initTimeStrip() {

		const canvas = cc.find('Canvas');

		const timeStripBg = this.getSprNode('time_strip_bg');
		timeStripBg.scale = this._mapScaleMin;
		timeStripBg.y = canvas.height / 2 - timeStripBg.height * this._mapScaleMin;
		canvas.addChild(timeStripBg);

		const timeStrip = this.getSprNode('time_strip');
		timeStrip.baseW = timeStrip.width;
		timeStrip.anchorX = 1;
		timeStrip.x = timeStrip.width / 2;
		timeStripBg.addChild(timeStrip);
		this._timeStrip = timeStrip;
	},

	refreshTimeStrip(percent) {

		const timeStrip = this._timeStrip;
		const spr = timeStrip.getComponent(cc.Sprite);
		const rect = spr.spriteFrame.getRect();
		rect.width = timeStrip.baseW * percent;
		rect.x = timeStrip.baseW * (1 - percent);
		timeStrip.width = rect.width;
		spr.spriteFrame.setRect(rect);

	},

	timingEnd() {

		this.showEndMask();
		this.cleanTimer();
		this.sendPlayerColorData();

		this._timeoutIds.push(setTimeout(() => {
			this.checkIsTeacher();

			if (this.isTeacher) {
				this.fillAiData();
				// this.teacherEnd();
			}
		}, 1000));
	},

	async fillAiData() {

		const c = window.courseware;
		// this.log("fillAiData:",c);
		if (!c) {
			return;
		}

		const aiArr = this.getAiArr();
		if (aiArr.length == 0) {
			this.teacherEnd();
			return;
		}

		// const teethDataArr = this.teethDataArr;

		// const data = [
		// 	{teethDataArr, uuid: this.playerId},
		// 	{teethDataArr, uuid: this.playerId},
		// 	{teethDataArr, uuid: this.playerId},
		// 	{teethDataArr, uuid: this.playerId},
		// 	{teethDataArr, uuid: this.playerId},
		// 	{teethDataArr, uuid: this.playerId},
		// ];

		// this.addAiResult(data, aiArr);
		// setTimeout(() => {
		// 	this.teacherEnd();
		// }, 200);

		// return;

		c.getAnswer({ count: aiArr.length }, (res) => {
			console.log('getAnswer res: ', res);

			if (res) {

				if (typeof (res) == 'string') {
					res = JSON.parse(res);
				}

				this.addAiResult(res, aiArr);
				this._timeoutIds.push(setTimeout(() => {
					this.teacherEnd();
				}, 200));

				// await this.asyncDelay(1);

			} else {
				this._timeoutIds.push(setTimeout(() => {
					this.teacherEnd();
				}, 200));
			}
		})

	},

	async addAiResult(data, aiArr) {

		console.log(' in addAiResult')

		const randomResultArr = data;
		for (let i = 0; i < aiArr.length; i++) {

			const resultStr = randomResultArr[i].result;
			const result = JSON.parse(resultStr);
			const aiUser = aiArr[i];
			if (aiUser && result) {



				const resultData = { teethDataArr: result.teethDataArr, uuid: aiUser.id, isAi: true }
				this.sendServerEvent('send_result', resultData);
				await asyncDelay(0.02);
			}
		}

	},

	getAiArr() {

		let aiArr = [];
		for (let i = 0; i < this.serverAllUser.length; i++) {
			if (!this.serverAllUser[i].result) {
				aiArr.push(this.serverAllUser[i]);
			}
		}
		return aiArr;
	},

	showEndMask() {
		const canvas = cc.find('Canvas');
		const maskNode = new cc.Node();

		this._can_tap = false;

		maskNode.x = -canvas.width / 2;
		maskNode.y = -canvas.height / 2;

		const ctx = maskNode.addComponent(cc.Graphics);
		ctx.fillColor = cc.Color.BLACK.setA(100);
		ctx.fillRect(0, 0, canvas.width, canvas.height);
		canvas.addChild(maskNode);
	},

	showResultView() {

		this.initResultView();
		this.initOtherPlayerItem();


		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		this.playAudioByName('tip_result', () => {
			this.countDownStart();
			playDragonBoneAnimation(this.coolcat, 'normal');

		});
	},

	resultView: null,
	scoreLabel: null,
	countDownLabel: null,
	countDownNum: null,
	selfScore: null,
	initResultView() {

		console.log(' in initResultView')

		const canvas = cc.find('Canvas');
		const bg = this.getSprNode('online_bg');
		bg.scale = this._mapScaleMax * 2;
		canvas.addChild(bg, 5);
		this.resultView = bg;

		const resultLayer = new cc.Node();
		this.canvas.addChild(resultLayer, 15);
		this.resultLayer = resultLayer;

		const labelNode = this.getCountDownLabel(); //this.getScoreLabel();
		labelNode.color = cc.Color.WHITE;
		labelNode.scale = this._mapScaleMin;
		this.canvas.addChild(labelNode, 16);
		const label = labelNode.getComponent(cc.Label);
		label.fontSize = 70 * this._mapScaleMin;
		label.string = '5';
		labelNode.y = - 520 * this._mapScaleMin;
		label.lineHeight = label.fontSize;
		this.countDownLabel = label;
		// this.scoreLabel = label;

		this.coolcat.parent = this.canvas;
		this.coolcat.x = 0//this.canvas.width / 2 - 100 * this._mapScaleMin;
		this.coolcat.y = 0 // this.canvas.height / 2;
		this.coolcat.active = true;
		this.coolcat.zIndex = 25;

		// setInterval(() => {
		// 	this.coolcat.x -= 10;
		// 	this.coolcat.y = 0;
		// }, 1000)

		this.countDownNum = 5;
		// this.countDownStart();

		this.selfScore = 0;
	},

	countDownStart() {
		this._timeoutIds.push(setTimeout(() => {
			this.countDownNum--;
			this.countDownLabel.string = this.countDownNum.toString();
			if (this.countDownNum == 0) {
				this.countDownLabel.node.active = false;
				this.countDownEnd();
			} else {
				this.countDownStart();
			}
		}, 1000));
	},

	isGoodEnd: null,
	countDownEnd() {
		this.isGoodEnd = true;
		if (this.selfScore == 0) {
			this.sendServerEvent('get_good', this.playerId)
		}

		let id = this.selfScore
		if (id == 0) {
			id = 1;
		}

		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		this.playAudioByName('result_' + id, () => {
			playDragonBoneAnimation(this.coolcat, 'normal');
		});
	},

	getCountDownLabel() {
		const label = this.getScoreLabel();
		return label;
	},


	getScoreLabel() {

		const label = cc.find('res/font/MMTextBook-Bold');
		const labelNode = cc.instantiate(label);
		labelNode.active = true;
		labelNode.x = 0;
		labelNode.y = 0;
		labelNode.color = cc.Color.WHITE;
		return labelNode;
	},

	addSelfIcon(item) {
		const icon = this.getSprNode('me');
		icon.anchorX = 1;
		icon.anchorY = 0;
		item.addChild(icon, 10);
		icon.x = 340;
		icon.y = 205;

		// item.icon.active = item.scoreLabelBg.active = false;
	},

	resultItemArr: null,
	async initOtherPlayerItem() {

		console.log(' in initOtherPlayerItem')


		this.resultLayer.removeAllChildren();

		const itemArr = [];
		// const resultArr = this.gameEndData;
		let s=0;
		let a=[
			[0,0],[1,0],[2,0],
			[0,1],[1,1],[2,1]
		];
		for (let key in this.gameEndData) {
			const itemData = this.gameEndData[key];

			const id = key;
			const { teethDataArr } = itemData

			this.log(teethDataArr.length+"_endData:"+JSON.stringify(teethDataArr));

			const item = await this.getOneItem(teethDataArr, id);
			item.x=(item.width+50)*a[s][0];
			item.y=(item.height+50)*a[s][1];
			s++;
			itemArr.push(item);
			this.resultLayer.addChild(item);

			if (id == this.playerId) {
				this.addSelfIcon(item);
			}
		}

		// for (let i=0; i<resultArr.length; i++) {
		// 	const {teethDataArr, uuid} = resultArr[i];
		// 	const item =	this.getOneItem(teethDataArr, uuid);
		// 	itemArr.push(item);
		// 	this.resultView.addChild(item);

		// 	if (uuid == this.user.uuid) {
		// 		this.addSelfIcon(item);
		// 	}
		// }


		this.resultItemArr = itemArr;

		this._timeoutIds.push(setTimeout(() => {
			console.log(' in setTimeOut, itemArr.length: ', itemArr.length);

			const disW = 720 * this._mapScaleMin;
			const disH = 500 * this._mapScaleMin;
			let x = - disW;
			let y = disH / 2 + 190 * this._mapScaleMin;
			let row = 0;
			let col = 0;
			for (let i = 0; i < itemArr.length; i++) {

				const item = itemArr[i]
				item.scale = 0.8 * this._mapScaleMin;
				item.x = x + col * disW;
				item.y = y - row * disH;
				col++;

				if (i == 2) {
					col = 0;
					row++;
				}

				// console.log('item:', item);
			}
		}, 1));
	},

	playerInfoData: null,
	loadingScript: null,
	initMatchingView() {

		// 		http://staging-teach.cdn.ireadabc.com/0751c28419a0e8ffb1f0e84435b081ce.png
		// http://staging-teach.cdn.ireadabc.com/f596e586a31ac2813b1702557941c022.png
		// http://staging-teach.cdn.ireadabc.com/f0f396c52c42239913fd94523db979fa.png
		// http://staging-teach.cdn.ireadabc.com/9f2d2ef622fa33d4e2abcbdc4b40ab6a.png

		// http://staging-teach.cdn.ireadabc.com/f40ce4a8630039c4cf48a63fc1399c52.png

		// http://staging-teach.cdn.ireadabc.com/9963905cc7fbfb53f22325ad0a9db3e9.png
		// http://staging-teach.cdn.ireadabc.com/2e3d7b4c386400974bf9d6a1bb8550a7.png



		const playerData = [{
			isSelf: true,
			name: 'Chris',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/0751c28419a0e8ffb1f0e84435b081ce.png'
		}, {
			isSelf: false,
			name: 'Benny',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/f596e586a31ac2813b1702557941c022.png'
		}, {
			isSelf: false,
			name: 'Leslie',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/f0f396c52c42239913fd94523db979fa.png'
		}, {
			isSelf: false,
			name: 'Devin',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/9f2d2ef622fa33d4e2abcbdc4b40ab6a.png'
		}, {
			isSelf: false,
			name: 'Sam',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/f40ce4a8630039c4cf48a63fc1399c52.png'
		}, {
			isSelf: false,
			name: 'Kerry',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/9963905cc7fbfb53f22325ad0a9db3e9.png'
		}, {
			isSelf: false,
			name: 'Joey',
			headUrl: 'http://staging-teach.cdn.ireadabc.com/2e3d7b4c386400974bf9d6a1bb8550a7.png'
		},

		];
		this.playerInfoData = playerData;


		const script = cc.find('Canvas/OP10_LoadingLayer').getComponent('OP10_LoadingLayer');
		script.setMaxPlayerNumber(6);
		script.onLoadFinished(() => {
			this.sendServerEvent('game_start');
		})
		this.loadingScript = script;

		if (!this.serverAllUser) {
			return;
		}

		// const nameList = [
		// 	'Hailey', 'Fred', 'Arrow',
		// 	'Tony', 'Michael',
		// ];

		for (let i = 0; i < this.serverAllUser.length; i++) {
			const user = this.serverAllUser[i];

			const isSelf = user.id == this.playerId;
			// if (isSelf) {
			// 	user.name = nameList[RandomInt(0, 4)];
			// } else {
				user.name = playerData[i].name
			// }
			script.addPlayer(user.name, isSelf, playerData[i].headUrl);

			if (this.isTeacher) {
				// setTimeout(() => {
				// 	this.gameServer.addUser(user);
				// }, 1000);
			}
		}

		// this.checkAddAi();
		console.log('script: ', script);
	},

	checkAddAi() {
		if (this.serverAllUser.length < 6) {

			if (window.courseware) {
				// if (this.isTeacher) {
				// 	window.courseware.addAiUser(1); 
				// }

				this.checkAddUser({ name: 'player', id: this.serverAllUser.length + 1, connected: true });

				this._timeoutIds.push(setTimeout(() => {
					this.checkAddAi()
				}, 2000));
			}
		} else {
			this.networkHelper.closeRoom().then(() => {

			})


		}

	},

	addUser(user) {


		if (this.serverAllUser.length >= 6) {
			return;
		}

		for (let i = 0; i < this.serverAllUser.length; i++) {
			if (this.serverAllUser[i].id == user.id) {
				console.log(' 该用户已经存在 无需再加入。')
				return;
			}
		}


		this.serverAllUser.push(user);
		const len = this.serverAllUser.length;


		const isSelf = this.playerId == user.id;
		this.loadingScript.addPlayer(user.name, isSelf, this.playerInfoData[len - 1].headUrl);

		// if (this.isTeacher) {
		// 	setTimeout(() => {
		// 		console.log(' aaa addUser, ');
		// 		this.gameServer.addUser(user);
		// 	}, 2000);
		// }
	},



	initView() {
		this._textureIdMapDataContainer = {};

		this._index = 0;

		this.updateItem();

		// this._start = cc.find('Canvas/start');
		// this._start.on('click',()=>{
		// 	this._start.active = false;
		// 	this.updateItem();
		// });
	},

	async updateItem() {
		this._submitted = false;
		this.cleanColor();
		this.coolcat.active = true;

		// let info = this.data.items[this._index];
		// let words = info.words.split('');
		// let answers = info.answers.split('');
		// let words = 'aAcBaCbA'.split('');
		// let answers = '0147'.split('');

		let spriteFrame=await this.getSpriteFrimeByUrl(this.data.bg);
		let bg1=this.paint.getChildByName("alligator_img");
		this.log("bg:"+bg1.name);
		bg1.getComponent(cc.Sprite).spriteFrame=spriteFrame;

		let bg2=this.paint2.getChildByName("alligator_img");
		bg2.getComponent(cc.Sprite).spriteFrame=spriteFrame;

		this._alligator.destroyAllChildren();
		this._alligator2.destroyAllChildren();
		// this._timeoutIds.push(setTimeout(() => {
			await this.initAlligator(this._alligator);
		// }, 1));

		this._alligator = this.bindAlligator(this.paint);
		this._alligator2 = this.bindAlligator(this.paint2);

		this.bindAlligatorButton(this._alligator);

		// console.log(words, answers);
		this._ids=[];
		for(let i=0;i<this.data.images.length;i++){
			this._ids[i]=i;
		}
		// this._ids = answers;
		this._id_count = this._ids.length;

		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		this.playAudioByName('demo', () => {
			this.initOnlinePart();
			playDragonBoneAnimation(this.coolcat, 'normal');
			this._can_tap = true;
		});
	},

	// ------------------------------------------------
	getSprNode(resName) {
		const sf = cc.find('res/img/' + resName).getComponent(cc.Sprite).spriteFrame;
		const node = new cc.Node();
		node.addComponent(cc.Sprite).spriteFrame = sf;
		return node;
	},


	async getSpriteFrimeByUrl(url, cb) {
		return new Promise((resolve)=>{
			cc.loader.load({ url }, (err, img) => {
				const spriteFrame = new cc.SpriteFrame(img)
				resolve(spriteFrame);
				// if (cb) {
				// 	cb(spriteFrame);
				// }
			})	
		});
	},

	async getSprNodeByUrl(url) {
		const node = new cc.Node();
		const spr = node.addComponent(cc.Sprite);
		spr.spriteFrame=await this.getSpriteFrimeByUrl(url);
		return node;
	},

	playAudioByUrl(audio_url, cb = null) {
		if (audio_url) {
			cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
				const audioId = cc.audioEngine.play(audioClip, false, 0.8);
				if (cb) {
					cc.audioEngine.setFinishCallback(audioId, () => {
						cb();
					});
				}
			});
		}
	},

	// ------------------------------------------

	getColor(hstr) {
		var color = new cc.Color();
		color.fromHEX(hstr);
		return color;
	},

	tryFinish() {
	},

	gameEnd(data) {

		// if (data) {

		// 	this.gameEndData = JSON.parse( data );
		// }

		if (this.isGameEnd) {
			return;
		}
		this.isGameEnd = true;
		this.showResultView()
	},

	// gameEnd(){
	// 	if (window && window.courseware) {
	// 		window.courseware.gameEnd();
	// 	}
	// },

	// sendAnswer(answer="", isRight = false){
	// 	console.log(this._aiexerciseid, answer, isRight, this._startTime);

	// 	if (window && window.courseware) {
	// 		window.courseware.sendAnswer(this._aiexerciseid, answer, isRight, this._startTime);
	// 	}
	// },

	incomplete() {
		let len = this._ids.length;
		for (let i = 0; i < len; i++) {
			if (this._ids[i] >= 0) {
				return true;
			}
		}
		return false;
	},

	playAudioByName(audioName, cb = null) {
		return new Promise((resolve, reject) => {
			try {
				const audioNode = cc.find('res/audio/' + audioName);
				const audioClip = audioNode.getComponent(cc.AudioSource).clip;
				playAudio(audioClip, cb);
			} catch (e) {
				reject(e);
			}
		});
	},
	// ------------------------------------------

	bindTeethHit(tooth) {

		let sprite = tooth;
		// sprite.word.node.color = cc.Color.WHITE;

		sprite.on(cc.Node.EventType.TOUCH_START, () => {
			if (this._can_tap != true)
				return;

			// if (sprite.painted == true)
			// 	return;
			this._can_tap = false;
			if (this.color_selector.active == false)
				return;
			console.log('area:' + sprite.t_idx);
			console.log('this.ids:' + this._ids);

			// this._ids[find_id] = -1;
			if (this.btn_submit.node.active == false) {
				// this.btn_submit.node.active = true;
			}

			//correct
			playDragonBoneAnimation(this.coolcat, 'right', -1);
			this.playAudioByName('correct', () => {
				playDragonBoneAnimation(this.coolcat, 'normal');
				this._can_tap = true;
			});
			this.playAudioByName('painted');

			// let find_id = this._ids.indexOf(sprite.t_idx + '');
			// if (find_id >= 0) {
			// 	// this._ids[find_id] = -1;
			// 	if (this.btn_submit.node.active == false) {
			// 		// this.btn_submit.node.active = true;
			// 	}

			// 	//correct
			// 	playDragonBoneAnimation(this.coolcat, 'right', -1);
			// 	this.playAudioByName('correct', () => {
			// 		playDragonBoneAnimation(this.coolcat, 'normal');
			// 		this._can_tap = true;
			// 	});
			// 	this.playAudioByName('painted');
			// }
			// else {
			// 	//incorrect
			// 	this._can_tap = false;
			// 	playDragonBoneAnimation(this.coolcat, 'wrong', -1);
			// 	this.playAudioByName('incorrect', () => {
			// 		playDragonBoneAnimation(this.coolcat, 'normal');
			// 		this._can_tap = true;
			// 	});
			// 	return;
			// }

			sprite.painted = true;
			sprite.color = this._color;
			// sprite.word.node.color = cc.Color.WHITE;
			// this.tryFinish();
		});

		sprite._hitTest = this._hitTest.bind(this);
	},

	_hitTest(location, listener) {

		const sprite = listener.owner;

		let spriteFrame = sprite.getComponent(cc.Sprite).spriteFrame;
		if (spriteFrame == null) {
			return false;
		}
		let posInNode = sprite.convertToNodeSpaceAR(location);
		let rect = spriteFrame.getRect();
		let offset = spriteFrame.getOffset();
		if ((posInNode.x < offset.x - (rect.width * sprite.anchorX))
			|| (posInNode.y < offset.y - (rect.height * sprite.anchorY))
			|| (posInNode.x > (offset.x + (rect.width * (1 - sprite.anchorX))))
			|| (posInNode.y > (offset.y + (rect.height * (1 - sprite.anchorY))))) {
			return false;
		}

		if (!this.camera) {
			const checkCameraNode = cc.find('Canvas/CheckCamera');
			if (!checkCameraNode) {
				throw '找不到[Canvas/CheckCamera]。';
			}
			this.camera = checkCameraNode.getComponent(cc.Camera);
		}
		if (this.camera.cullingMask != -2) {
			console.warn(`[${this.camera.cullingMask}]: 检查CheckCamera的cullingMask值，应该只选择camera`);
		}
		this.camera.node.active = true;
		let posInRect = cc.v2(
			parseInt(posInNode.x - offset.x + rect.width * sprite.anchorX),
			parseInt(posInNode.y - offset.y + rect.height * sprite.anchorY)
		);
		let tex = spriteFrame.getTexture();
		this.camera.enable = true;
		let rt;
		let destory = false;
		if (tex instanceof cc.RenderTexture) {
			rt = tex;
		} else {
			rt = new cc.RenderTexture()
			rt.initWithSize(tex.width, tex.height, cc.gfx.RB_FMT_S8);
			rt.drawTextureAt(tex, 0, 0);
			destory = true;
		}
		// data就是这个texture的rgba值数组
		this.camera.targetTexture = rt;
		this.camera.render(undefined);
		let data;
		//图集里的图片可能会旋转
		if (spriteFrame.isRotated()) {
			data = rt.readPixels(null, rect.x + posInRect.y, rect.y + posInRect.x, 1, 1);
		} else {
			data = rt.readPixels(null, rect.x + posInRect.x, rect.y + rect.height - posInRect.y, 1, 1);
		}
		this.camera.targetTexture = null;
		this.camera.enable = false;
		this.camera.node.active = false;

		if (destory) {
			rt.destroy();
		}

		if (data[3] > 0) {
			return true;
		} else {
			return false;
		}
	},

	teethDataArr: null,
	sendPlayerColorData() {
		const teethDataArr = this.copyColorOnline();
		console.log('teethDataArr ', teethDataArr);

		this.teethDataArr = teethDataArr;

		const data = { teethDataArr, uuid: this.playerId };

		this.sendServerEvent('send_result', data);

		this.sendResult();
	},

	sendResult() {
		const data = { teethDataArr: this.teethDataArr, uuid: this.playerId };

		if (window && window.courseware) {
			window.courseware.sendAnswer(data);
		}
	},

	sendServerEvent(key, data) {

		console.log("sendServerEvent key: ", key);
		console.log("sendServerEvent data: ", data);
		this.networkHelper.sendFrame({
			type: key,
			data
		});

		// const c = window.courseware;
		// if (c) {
		// 	c.sendEvent(key, data);
		// }
	},

	update(dt) {
		this.updateTimer(dt)
	},


	_timeoutIds: null,
	_intervalIds: null,
	// 生命周期
	onDestroy() {
		this.cleanTimer();
		if (this.gameServer) {
			this.gameServer.onDestroy();
		}
		if (this.networkHelper) {
			this.networkHelper.onDestroy();
		}
		cc.macro.CLEANUP_IMAGE_CACHE = true;

		this._timeoutIds.forEach(id => {
			clearTimeout(id);
		});
		this._intervalIds.forEach(id => {
			clearInterval(id);
		});
	},
});
