import { onHomeworkFinish, RandomInt, playAudio, playDragonBoneAnimation, getSprNode, popParticle, asyncDelay, getSprNodeByUrl, playAudioByUrl } from "../script/util_op_spy";
import { GameServer } from "../script/server_op_spy";
import { NetworkHelper_op_spy } from "../script/NetworkHelper_op_spy";




cc.Class({

	extends: cc.Component,

	properties: {
		

	},

	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()
		})

	},

	

	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);

			// parent.parent.addChild(tooth, 5);
			// tooth.x += parent.x;
			// tooth.y += parent.y;

			// 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 {"startAudio":"https://staging-teach.cdn.ireadabc.com/c0ab05fa5a866dd8e3f255f6818e5270.mp3","waitAudio":"https://staging-teach.cdn.ireadabc.com/c0ab05fa5a866dd8e3f255f6818e5270.mp3","finishAudio":"https://staging-teach.cdn.ireadabc.com/126c125b051954d3b5eec1b5a63cb309.mp3","finishWaitAudio":"https://staging-teach.cdn.ireadabc.com/6162b1d0ce9c0a46ac1b6a03eb2768c3.mp3","rightAudio":"https://teach.cdn.ireadabc.com/e3921a16a8313df274d8bc4e3f2bedd8.mp3","wrongAudio":"https://teach.cdn.ireadabc.com/1ebdd8267b0f9161f1b6b83a3b44fb4b.mp3","bg":"https://staging-teach.cdn.ireadabc.com/7a8ce0871844b13212e23a7f174a7914.png","images":[{"img":"https://staging-teach.cdn.ireadabc.com/b04e6aabab9ba17d5236ff91bbfdd619.png"},{"img":"https://staging-teach.cdn.ireadabc.com/5611fe1930af2e03424319b345153d09.png"},{"img":"https://staging-teach.cdn.ireadabc.com/7398639bec9bc98580cd9812635d505f.png"},{"img":"https://staging-teach.cdn.ireadabc.com/e962deb78221cb6b2c518d64d9e227d7.png"}]}
		return {"quesArr":[],"begin_1_audio_url":"http://staging-teach.cdn.ireadabc.com/66abb69d1833758f8971544498092874.mp3","begin_2_audio_url":"http://staging-teach.cdn.ireadabc.com/2b4014839157557c560e6f70fc4291fa.mp3","talk_start_audio_url":"http://staging-teach.cdn.ireadabc.com/f0899cb23a6829e60c8f1376b75fac58.mp3","search_start_audio_url":"http://staging-teach.cdn.ireadabc.com/592b7efe821d246342760f202c5383e0.mp3","talk_right_audio_url":"http://staging-teach.cdn.ireadabc.com/6162b1d0ce9c0a46ac1b6a03eb2768c3.mp3","talk_wrong_audio_url":"http://staging-teach.cdn.ireadabc.com/ad243d509d9e11a5e077ea569b48f0c6.mp3","next_round_audio_url":"http://staging-teach.cdn.ireadabc.com/073119200c5b48634d337e7b9a1ff5d1.mp3","search_right_audio_url":"http://staging-teach.cdn.ireadabc.com/6162b1d0ce9c0a46ac1b6a03eb2768c3.mp3","search_wrong_audio_url":"http://staging-teach.cdn.ireadabc.com/bba8d9ca8ed511744fe9459502dc4d42.mp3","search_idle_audio_url":"http://staging-teach.cdn.ireadabc.com/592b7efe821d246342760f202c5383e0.mp3","talk_idle_audio_url":"http://staging-teach.cdn.ireadabc.com/66abb69d1833758f8971544498092874.mp3"};
	},

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

	preloadAudio() {

		this._audioResList.push({ url: this.data.begin_1_audio_url || '' });
		this._audioResList.push({ url: this.data.begin_2_audio_url || '' });
		this._audioResList.push({ url: this.data.talk_idle_audio_url || '' });
		this._audioResList.push({ url: this.data.search_idle_audio_url || '' });
		this._audioResList.push({ url: this.data.talk_start_audio_url || '' });
		this._audioResList.push({ url: this.data.search_start_audio_url || '' });
		this._audioResList.push({ url: this.data.talk_right_audio_url || '' });
		this._audioResList.push({ url: this.data.talk_wrong_audio_url || '' });
		this._audioResList.push({ url: this.data.search_right_audio_url || '' });
		this._audioResList.push({ url: this.data.search_wrong_audio_url || '' });
		this._audioResList.push({ url: this.data.next_round_audio_url || '' });


	},

	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;
		}

	},

	maxPlayer: null,
	loadEnd() {

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

		this.maxPlayer = 2;
		this.initNetwork();
	},


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

		this.addNetworkListener(nh);

		this.playerId = await nh.init('op_spy', this.maxPlayer);
		const room = nh.room;

		console.log('room: ', room);
		console.log('this.playerId: ', this.playerId);
		this.initServerAllUser(room);

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



		await this.initMatchingView();


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


		// this.networkHelper.startFrameSync(() => {

		// });

		this.checkGameStart();

		this.checkIsTeacher();


	},



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



		this.addUser(user);
	},



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

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

			this.checkIsTeacher();
			console.log('this.isTeacher: ' , this.isTeacher);

			if (this.isTeacher) {
				this.networkHelper.closeRoom().then(() => {
					this.addAiUser();
				});
			} else {

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

	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 headUrl = this.playerInfoData[i].headUrl;
			const data = { playerId: aiId.toString(), name: this.playerInfoData[i].name, headUrl, isAi: true }


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

	checkIsTeacher() {

		// this.isTeacher = this.networkHelper.checkIsOwner();

		console.log("this.networkHelper.room.ownerId : ", this.networkHelper.room.ownerId );
		console.log("this.playerId: ", this.playerId);
		this.isTeacher = this.networkHelper.room.ownerId == this.playerId;
		return

		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;
		this.serverAllUser = this.networkHelper.room.players;
		console.log('this.serverAllUser: ', this.serverAllUser.toString());
		console.log('this.serverAllUser.length: ', this.serverAllUser.length);
	},

	addNetworkListener(nh) {

		this.isOffLine = false;
		nh.on("playerLeave", (event) => {
			cc.find("Canvas/PlayerOffLineLayer").active = true;
      this.log("playerLeave" + JSON.stringify(event));
      nh.leaveRoom();
			this.isOffLine = true;
    });
    nh.on("playerOffLine", (event) => {
      cc.find("Canvas/PlayerOffLineLayer").active = true;
      this.log("playerOffLine" + JSON.stringify(event));
      nh.leaveRoom();
			this.isOffLine = true;

    });

		nh.on('playerJoin', (event) => {

			if (this.isOffLine) {
				return;
			}
			this.log("playerJoin", (event));

			this.onPlayerJoin(event);

		});

		nh.on('gameStart', (event) => {

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

			if (this.isOffLine) {
				return;
			}

			console.log(' on frameEvent``', event);

			const frameInfo = event?.data?.frame?.items;
			if (!frameInfo || frameInfo.length == 0) {
				return;
			} 
			console.log('frameEvent~~~~: ', event)


			frameInfo.forEach((frameData) => {

				// frameData.data = JSON.parse(frameData.data);
				const res = frameData.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 'word_data':
						this.getWordData(res.data);
						break;

					case 'next_round':
						this.nextRound();
						break;

					case 'add_score':
						this.addScore();
						break;
					
					case 'show_talk_icon':
						this.showTalkIcon(res.data);
						break;

					case 'show_search_icon':
						this.showSearchIcon(res.data);
						break;

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


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

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

				

					case 'add_player':
						this.onAddPlayer(res.data);
						break;

					case 'refresh_player_list':
						console.log(' on refresh_player_list')
						this.onRefreshPlayerList(res.data);
						return;

				}

			})
		});


	},

	onPlayerJoin(data) {


		const middleLayer = cc.find("middleLayer");
		if (middleLayer) {
			const middleLayerComponent = middleLayer.getComponent("middleLayer");
			if (middleLayerComponent.getUserInfo && middleLayerComponent.getHeadUrl) {
				middleLayerComponent.getUserInfo().then((kidInfo) => {
					const playerHeadUrl = middleLayerComponent.getHeadUrl(kidInfo.avatar_url || kidInfo.id);
					// playerInfo.playerHeadUrl = playerHeadUrl;
					// playerInfo.playerName = kidInfo.nick_name || '拼读达人';

					data.name = kidInfo.nick_name || '拼读达人';
					data.playerHeadUrl = playerHeadUrl
					this.sendServerEvent('add_player', data);
					return;
					
				})
			}
		}




		data.name = '拼读达人';
		data.headUrl = 'http://staging-teach.cdn.ireadabc.com/2e3d7b4c386400974bf9d6a1bb8550a7.png';
		this.sendServerEvent('add_player', data);
		return;



		console.log(" in onPlayerJoin  : ", data);

		let user = { playerId: data.playerId };

		console.log(' in onPlayerJoin 1 ', JSON.stringify(user));
		const len = this.serverAllUser.length;
		user.name = this.playerInfoData[len].name;

		const playerList = this.networkHelper.room.players;
		console.log('playerList: ', playerList);
		for (let i = 0; i < playerList.length; i++) {
			if (playerList[i].playerId == user.id) {
				user.name = playerList[i].name;
				console.log('in playerlist');
			}
		}

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

		this.addUser(user)
	},


	onAddPlayer(data) {
		
		console.log('onAddPlayer data: ', data);

		if (this.isTeacher) {
			this.addUser({ playerId: data.playerId, name: data.name, headUrl: data.headUrl })
		}
		this.isPVP = true;

	},

	onAddAi(data) {


		if (this.isPVP) {
			return;
		}
		console.log(' in onAddAi data: ', data);
		// if (this.isTeacher) {
			this.addUser(data)
		// }
		this.initAiGameData();
	},

	initAiGameData() {
		
		// 默认数据
		this.aiGameData = {"talkGroup":[{"word":"die"},{"word":"spy"},{"word":"pie"},{"word":"lie"},{"word":"light"}],"searchGroup":[{"word":"key","isRight":false},{"word":"candy","isRight":false},{"word":"jeep","isRight":false},{"word":"leaf","isRight":false},{"word":"bee","isRight":false}]}

	},

	setAiGameData(callback) {

		const node = cc.find('middleLayer');
		if (node) {
			console.log('node exist');
			const mScript = node.getComponent('middleLayer');
			const coursewareid = mScript?.courseItem?.id;
			if (!coursewareid) {
				console.log(" !coursewareid~: ");
				callback();
				return;
			}

			console.log('~ coursewareid :' , coursewareid);
			const count = 1;
			const token = cc.sys.localStorage.getItem('token');
			const url = "/api/oxford/courseware/v1/" + coursewareid + "/getanswer"
			mScript.callNetworkApiGet(url, {coursewareid, token, count},  (res)=> {
				console.log("res~: ", res);

				if (typeof(res) == "string") {
					res = JSON.parse(res);
					console.log('objRes: ', res);
				}

				if(res.code == 200) {

					if (res.rows && res.rows[0]?.result) {
						this.aiGameData = JSON.parse(res.rows[0].result);
					}
					callback();

				} else {
					callback();
				}

	
			});

		} else {
			console.log('node not exist');
			callback();
		}
	},



	onRefreshPlayerList(data) {
		console.log('onRefreshPlayerList data: ', data);
		for (let i=0; i<data.length; i++) {
			this.addUser(data[i]);
		}
	},

	setPlayerResult(data) {
		console.log(' in setPlayerResult');
		const { uuid } = data;
		this.gameEndData[uuid] = data;

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

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



	initData() {

		const baseData = [
			{word: 'bee', data: {bottomSpr: "item/bee_1", topSpr: "item/bee_0", audioClip: this.getAudioClicp("item/bee")}},
			{word: 'candy', data: {bottomSpr: "item/candy_1", topSpr: "item/candy_0", audioClip: this.getAudioClicp("item/candy")}},
			{word: 'jeep', data: {bottomSpr: "item/jeep_1", topSpr: "item/jeep_0", audioClip: this.getAudioClicp("item/jeep")}},
			{word: 'key', data: {bottomSpr: "item/key_1", topSpr: "item/key_0", audioClip: this.getAudioClicp("item/key")}},
			{word: 'leaf', data: {bottomSpr: "item/leaf_1", topSpr: "item/leaf_0", audioClip: this.getAudioClicp("item/leaf")}},
			{word: 'light', data: {bottomSpr: "item/light_1", topSpr: "item/light_0", audioClip: this.getAudioClicp("item/light")}},
			{word: 'die', data: {bottomSpr: "item/die_1", topSpr: "item/die_0", audioClip: this.getAudioClicp("item/die")}},
			{word: 'spy', data: {bottomSpr: "item/spy_1", topSpr: "item/spy_0", audioClip: this.getAudioClicp("item/spy")}},
			{word: 'pie', data: {bottomSpr: "item/pie_1", topSpr: "item/pie_0", audioClip: this.getAudioClicp("item/pie")}},
			{word: 'lie', data: {bottomSpr: "item/lie_1", topSpr: "item/lie_0", audioClip: this.getAudioClicp("item/lie")}},
		];

		this._searchTime = 10;

		this.resultDataArr = [];
		this.playerAudioDataArr = [];
		this.round = 1;
		this.roundChangeCount = 0;
		this.searchWrongCount = 0;
		this.score = 0;
		this.totalScore = 20;
		this.selfScore = 0;
		this.resultTalkGroup = [];
		this.resultSearchGroup = [];

		this.wordDataArr = baseData //JSON.parse( JSON.stringify(baseData) );

		if (this.isPVP) {
			this.aiGameData = null;
		}

		this.initPlayerAB();
		if (this.isPlayer1) {
			this.initDataGroup(baseData);
			this.initCurData();
		}
	},

	getAudioClicp (audioName) {
		const audioNode = cc.find('res/audio/' + audioName);
		return audioNode.getComponent(cc.AudioSource).clip;
	},

	gameStart() {

		console.log('!!!gameStart')
		if (this.isGameStart) {
			return;
		}
		this.isGameStart = true;



		const startShow = () => {
			this.initData();
			this.initView();
			this.hideLoadingLayer();
		}

		if (this.aiGameData) {
			this.setAiGameData(() => {
				startShow();
			});
		} else {
			startShow();
		}

	
	},

	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++) {

			console.log('this.serverAllUser[i]: ', JSON.stringify( this.serverAllUser[i]) );
			console.log('uuid: ', uuid);
			if (this.serverAllUser[i].playerId == 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;
		}
	},







	addScore() {
		console.log('in addScore')
		this.score += 1;
		this.progressBar.progress = this.score / this.totalScore;
	},

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

		this.cleanTimer();
		this._totalTime = 3; //总时长
		this._curTime = 0;
	},


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

		this._curTime += dt
		let percent = Math.round(this._curTime / this._totalTime * 10000) / 10000;
		if (percent >= 1) {
			percent = 1;
			this.timingEnd();
			this.isTimingShow = false;
		}
		this.recordLayer.progressBar.progress = percent;
	},

	updateWatch(dt) {
		if (!this.isWatchCountDown) {
			return;
		}

		this._watchTime += dt
		let percent = Math.round((this._searchTime - this._watchTime) / this._searchTime * 10000) / 10000;
		if (percent <= 0) {
			percent = 0;
			this.watchEnd();
			this.isWatchCountDown = false;
		}
		this.watchNode.progressBar.progress = percent;
	},

	watchEnd() {

		this.searchWrongCount = 3;
		this.searchWrong();
	},

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

	timingEnd() {
		this.recordLayer.active = false;
		this.hideBgMask();
		this.cleanTimer();
		this.serverStopTest();
	},


	_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;

		this.getAnswer(aiArr);
	
		// this.teacherEnd();

	},

	async getAnswer(aiArr) {

		const node = cc.find('middleLayer');
		if (node) {
			console.log('node exist');
			const mScript = node.getComponent('middleLayer');
			const coursewareid = mScript?.courseItem?.id;
			if (!coursewareid) {
				console.log(" !coursewareid~: ");
				this.teacherEnd();
				return;
			}

			console.log('~ coursewareid :' , coursewareid);

			const token = cc.sys.localStorage.getItem('token');
			const url = "/api/oxford/courseware/v1/" + coursewareid + "/getanswer"
			mScript.callNetworkApiGet(url, {coursewareid, token, count: aiArr.length}, async (res)=> {
				console.log("res~: ", res);

				if (typeof(res) == "string") {
					res = JSON.parse(res);
					console.log('objRes: ', res);
				}


				console.log('getanswer  res: ', JSON.stringify(res));

				if(res.code == 200) {
					// const rankArr = res.data?.rows || [];
					// OP12.rank.inst.onShow(rankArr);


					const rows = res?.rows || [];
				
					await this.addAiResult(rows, aiArr);
		
					// await this.asyncDelay(1);

					console.log("res: ", res);
				}

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

			});

		} else {
			console.log('node not exist');
				this._timeoutIds.push(setTimeout(() => {
					this.teacherEnd();
				}, 200));
		}



		
		// 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++) {

			if (!randomResultArr[i]) {
				console.log(' continue ~ ');
				continue;
			}
			const resultStr = randomResultArr[i]?.result;
			if (!resultStr) {

				console.log(' continue ');

				continue;
			} else {
				console.log('resultStr: ', resultStr);
			}
			const result = JSON.parse(resultStr);
			const aiUser = aiArr[i];
			if (aiUser && result) {
				
				const resultData = { teethDataArr: result.teethDataArr, uuid: aiUser.playerId, isAi: true }
				this.sendServerEvent('send_result', resultData);
				// await asyncDelay(0.02);
			}
		}

	},

	getAiArr() {

		let aiArr = [];
		for (let i = 0; i < this.serverAllUser.length; i++) {
			console.log('serverAllUser[i]: ', this.serverAllUser[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;

		bg.addComponent(cc.Button);

		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;

		const rank = this.getRank();

		if (this.selfScore == 0) {
			this.sendServerEvent('get_good', this.playerId)
		}

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

		const data = { teethDataArr: this.teethDataArr, uuid: this.playerId, rank: rank };
		console.log('send data: ', JSON.stringify(data));

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

			onHomeworkFinish(data);

		});
	},

	getRank() {

		let maxScore = 0;
		for (let i = 0; i < this.resultItemArr.length; i++) {
			const item = this.resultItemArr[i];
			const score = Number(item.scoreLabel.string);
			// item.score = score;

			if (maxScore < score) {
				maxScore = score;
			}
		}

		const rank = maxScore - this.selfScore + 1;
		return rank;

	},

	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));

			console.log('key: ', id);
			console.log("itemData: ", JSON.stringify(itemData));

			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,
	async initMatchingView() {


		const playerData = [{
			isSelf: false,
			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('op_spy_LoadingLayer');
		script.setMaxPlayerNumber(this.maxPlayer);
		script.onLoadFinished(() => {
			if (!this.isOffLine) {
				this.sendServerEvent('game_start');
			}
		})
		this.loadingScript = script;

		if (!this.serverAllUser) {
			return;
		}

	

		for (let i = 0; i < this.serverAllUser.length; i++) {
			const user = this.serverAllUser[i];
			const isSelf = user.playerId == this.playerId;
			let headUrl = user.headUrl || playerData[i].headUrl;
			if (isSelf) {

				user.name = '拼读达人';
				// user.name = playerData[i].name;

				const middleLayer = cc.find("middleLayer");
				if (middleLayer) {
					const middleLayerComponent = middleLayer.getComponent("middleLayer");
					if (middleLayerComponent.getUserInfo && middleLayerComponent.getHeadUrl) {
						const kidInfo = await middleLayerComponent.getUserInfo();
						const playerHeadUrl = middleLayerComponent.getHeadUrl(kidInfo.avatar_url || kidInfo.id);
						// playerInfo.playerHeadUrl = playerHeadUrl;
						// playerInfo.playerName = kidInfo.nick_name || '拼读达人';
						user.name =  kidInfo.nick_name || '拼读达人';
						headUrl = playerHeadUrl;
					}
				}



				// user.name = user.nick_name
				// headUrl = user.playerInfo.avatar;

				script.addPlayer(user.name, isSelf, headUrl);
				user.headUrl = headUrl;
				console.log('this.serverAllUser : ' , JSON.stringify( this.serverAllUser ))
			} else {
				user.name = playerData[i].name;
				this.serverAllUser = [];
				return;
			}
			// script.addPlayer(user.name, isSelf, headUrl);
		}

		// 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 >= this.maxPlayer) {
			return;
		}

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


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


		const isSelf = this.playerId == user.playerId;


		let headUrl = user.headUrl 
		this.loadingScript.addPlayer(user.name, isSelf, headUrl);


		console.log('isSelf: ', isSelf);
		console.log('this.isTeacher: ', this.isTeacher);
		console.log('user.isAi: ', user.isAi);
		if (this.isTeacher && !user.isAi) {

			setTimeout(() => {

				this.sendServerEvent('refresh_player_list', this.serverAllUser);

			}, 1);
		}
	},

	initPlayerAB() {
		if (this.playerId == this.serverAllUser[0].playerId) {
			this.isPlayer1 = true;
		} else {
			this.isPlayer2 = true;
		}
	},

	initDataGroup(baseData) {

		console.log('baseData: ', baseData);
		console.log('this.aiGameData: ', this.aiGameData);


		if (this.aiGameData) {
			const {searchGroup} = this.aiGameData;
			this.dataGroup1 = [];
			for(let j=0; j<baseData.length; j++) {
				
				const data = baseData[j];
				if (!data) {
					continue;
				}
				for(let i=0; i<searchGroup.length; i++) {
					if (searchGroup[i].word == data.word) {
						this.dataGroup1.push(data);
						baseData.splice(j, 1);
						j--;
						break;
					}
				}
			}

			this.dataGroup2 = baseData;

		} else {
			this.dataGroup1 = baseData.splice(0, 5);
			this.dataGroup2 = baseData;
		}


	},

	initView() {

		this.initBg();
		this.initCat();
		this.initHead();
		this.initBtn();
		this.initRecord();
		this.initWatchNode()
		this.initProgressBar();
		this.initResultLayer();

		this.playStartAnim();

	  // cc.find("Canvas/PlayerOffLineLayer").active = true

	},

	initBg() {
		const bg = cc.find("Canvas/bg");
		bg.scale = this.canvas.height / bg.height;
		this.bg = bg;

		this.bgMask = cc.find("Canvas/bgMask");

		bg.on('touchstart', () => {
			if (!this.isShowSearchIcon || !this.curData) {
				return;
			}

			this.searchWrongCount ++;

			if (this.searchWrongCount == 3) {
				this.searchWrong();
			} else if (this.searchWrongCount < 3) {
				
				playDragonBoneAnimation(this.coolcat, 'begin', -1);

				
				playAudioByUrl(this.data.search_wrong_audio_url, () => {
				// this.playAudioByName('bad', () => {
					playDragonBoneAnimation(this.coolcat, 'normal', -1);
				});
			}
		})
	},

	initCat() {
		this.coolcat = cc.find("Canvas/bg/catNode/anim");

		const btn = cc.find("Canvas/bg/catNode/anim/clickBtn");
		btn.on("click", () => {
			
			if ((this.round == 1 && this.isPlayer1) 
				|| (this.round == 2 && this.isPlayer2)) {

					playDragonBoneAnimation(this.coolcat, 'begin', -1);
					playAudioByUrl(this.data.talk_idle_audio_url, () => {
						playDragonBoneAnimation(this.coolcat, 'normal', -1);

					})
			} else {

				playDragonBoneAnimation(this.coolcat, 'begin', -1);
				playAudioByUrl(this.data.search_idle_audio_url, () => {
					playDragonBoneAnimation(this.coolcat, 'normal', -1);

				})
			}
		})
	},

	initHead() {
		const playerArr = this.serverAllUser;
		const player1Node = cc.find("Canvas/bg/player_1");
		const player2Node = cc.find("Canvas/bg/player_2");
		this.setPlayerHead(player1Node, playerArr[0]);
		this.setPlayerHead(player2Node, playerArr[1]);
	},

	initBtn() {
		const talkBtn = cc.find("Canvas/bg/talkNode/talk_btn");
		console.log('talkBtn: ', talkBtn);
		talkBtn.on("click", () => {
			this.talkBtnClick();
		})
		this.talkBtn = talkBtn;

		const talkBtnWave = cc.find("Canvas/bg/talkNode/wave");
		talkBtn.wave = talkBtnWave;

		const talkBtnShake = cc.find("Canvas/bg/talkNode/shake");
		talkBtn.shake = talkBtnShake;



		this.hideTalkBtn();
	},

	initWatchNode() {

		this.watchNode = cc.find("Canvas/bg/watchNode");

		const progressBar = cc.find("ProgressBar", this.watchNode).getComponent(cc.ProgressBar);
		this.watchNode.progressBar = progressBar;


		this._watchTime = 0;

	},

	initRecord() {

		const node = cc.find("Canvas/recordLayer");
		const wordLabel = cc.find("wordNode/word_bg/label", node).getComponent(cc.Label);
		node.wordLabel = wordLabel;
	
		this.initTimer();
		const progressBar = cc.find("Canvas/recordLayer/progressNode/progressBar").getComponent(cc.ProgressBar);
		node.progressBar = progressBar;

		this.recordLayer = node;


	},

	initProgressBar() {
		this.progressBar = cc.find("Canvas/bg/progressNode/ProgressBar").getComponent(cc.ProgressBar);
	},

	initResultLayer() {

		const resultLayer = cc.find("Canvas/resultLayer");
		const totalScoreLabel = cc.find("result_panel/totalScoreLabel", resultLayer).getComponent(cc.Label);
		// totalScoreLabel.string = '100'

		const headBg1 = cc.find("result_panel/player1/result_head", resultLayer);
		const nameLabel1 = cc.find("result_panel/player1/nameLabel", resultLayer).getComponent(cc.Label);
		const scoreLabel1 = cc.find("result_panel/player1/scoreLabel", resultLayer).getComponent(cc.Label);

		const data1 = this.serverAllUser[0];		
		getSprNodeByUrl(data1.headUrl, (spr) => {
			spr.node.scale = headBg1.width * 0.85 / spr.node.width;
			headBg1.addChild(spr.node);
		})
		nameLabel1.string =  data1.name;
		// scoreLabel1.string = 11 //this.selfScore;


		const headBg2 = cc.find("result_panel/player2/result_head", resultLayer);
		const nameLabel2 = cc.find("result_panel/player2/nameLabel", resultLayer).getComponent(cc.Label);
		const scoreLabel2 = cc.find("result_panel/player2/scoreLabel", resultLayer).getComponent(cc.Label);

		const data2 = this.serverAllUser[1];		
		getSprNodeByUrl(data2.headUrl, (spr) => {
			spr.node.scale = headBg2.width * 0.85 / spr.node.width;
			headBg2.addChild(spr.node);
		})
		nameLabel2.string =  data2.name;
		// scoreLabel2.string = 12 //this.selfScore;

		resultLayer.active = false;
		resultLayer.score1 = scoreLabel1;
		resultLayer.score2 = scoreLabel2;
		resultLayer.totalScore = totalScoreLabel;
		this.resultLayer = resultLayer;

	},


	initCurData(word = null) {

		if (!word) {
			let arr;
			if (this.round == 1) {
				arr = this.dataGroup1;
			} else {
				arr = this.dataGroup2;
			}

			const randomIndex = RandomInt(arr.length);
			this.curData = arr.splice(randomIndex, 1)[0];
			this.resultDataArr.push(this.curData);

		} else {
			let index = -1;
			for (let i=0; i<this.wordDataArr.length; i++) {
				if (this.wordDataArr[i].word == word) {
					index = i;
					break;
				}
			}
			if (index != -1) {
				this.curData = this.wordDataArr.splice(index, 1)[0];
				this.resultDataArr.push(this.curData);
			} else {
				console.log('wordDataArr: ', this.wordDataArr);
				console.log("error 没找到对应word")
			}

			this.showShake();
		}
	
		console.log('this.curData: ', this.curData);
		console.log("wordDataArr: ", this.wordDataArr);
	},


	setPlayerHead(playerNode, data) {

		const {headUrl, name} = data;

		const headBg = cc.find("head_bg", playerNode);
		getSprNodeByUrl(headUrl, (spr) => {
			spr.node.scale = headBg.width * 0.65 / spr.node.width;
			spr.node.y = -1;
			spr.node.x = 0.5;
			headBg.addChild(spr.node);
		})

		const nameBg = cc.find("head_name_bg", playerNode);
		const labelNode = this.getCommonLabel();
		const label = labelNode.getComponent(cc.Label);
		label.string = name;
		label.fontSize = 27
		labelNode.color = new cc.Color().fromHEX('#564e47');
		labelNode.y = -112;
		label.horizontalAlign = "center";
		label.verticalAlign = "center";
		label._forceUpdateRenderData(true);

		if (labelNode.width >= 150) {
			labelNode.scale = 150 / labelNode.width;
		}
		nameBg.addChild(labelNode);
	},

	playStartAnim() {

		// todo
		const anim = cc.find("Canvas/startAnimNode/startAnim");
		anim.parent.active = true;
		playDragonBoneAnimation(anim, 'normal', -1);
		this.showBgMask();
		
		let tipNameUrl;
		if (this.isPlayer1) {
			tipNameUrl = this.data.begin_1_audio_url;
		} else {
			tipNameUrl = this.data.begin_2_audio_url
		}
		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		playAudioByUrl(tipNameUrl, () => {
		// this.playAudioByName(tipName, () => {

			playDragonBoneAnimation(this.coolcat, 'normal', -1);
			if (this.isPlayer1) {
				this.showTalkBtn();
				this.showShake();
			}
			anim.parent.active = false;
			this.hideBgMask();
		});
	

	},


	getCommonLabel() {

		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;
	},

	talkBtnClick() {
		if ((this.isPlayer1 && this.round == 1) || (this.isPlayer2 && this.round == 2)) {
			this.talkTypeClick();
		
		} else {
			this.searchTypeClick();
		}
	
	},

	talkTypeClick() {
		this.showRecordLayer();
		this.hideTalkBtn();
		this.sendServerEvent("show_talk_icon", true)
	},

	searchTypeClick() {
		this.showRecordAudio();
		this.hideShake();
		if (!this.isShowSearchIcon) {
			this.isShowSearchIcon = true;
			this.sendServerEvent("show_search_icon", true)
		}
	},

	showRecordLayer() {

		const wordLabel = this.recordLayer.wordLabel;
		wordLabel.string = this.curData.word;

		this.recordLayer.active = true;

		this.startRecord();
		this.showBgMask();
	},

	showBgMask() {
		this.bgMask.active = true;
	},

	hideBgMask() {
		this.bgMask.active = false;
	},

	startRecord() {


		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		playAudioByUrl(this.data.talk_start_audio_url, () => {
		// this.playAudioByName('word_tip', () => {
			playDragonBoneAnimation(this.coolcat, 'normal', -1);

			this._curTime = 0;
			this.isTimingShow = true;
			this.serverStartTest(this.curData.word);
		});
	},

	recordEnd(data, callback) {

		console.log('curData: ', this.curData);
		if (data.errCode) {
			callback();
			return;
		}

		let audio_url = data.audioUrl;
		const score = data.result?.overall;
		if (score >= 70) {
			callback(audio_url, score);
		} else {
			callback(null, score);
		}

	},


	serverStartTest(text) {

		console.log(' in serverStartTest: ', text);
		const cw = window?.courseware
		if (cw) {
			cw.startTest(text);
		}
	},

	serverStopTest() {

		const cw = window?.courseware
		if (cw) {
			cw.stopTest(data => {
				console.log('stopTest data: ', data);

				if (data && typeof (data) == 'string') {
					data = JSON.parse(data)
				}

				this.recordEnd(data, (audio_url, score) => {
					
					const sendData = {word: this.curData.word, score}
					if (audio_url) {
						sendData.audio_url = audio_url;
					}
		
					this.sendServerEvent('word_data', sendData);
					this.resultTalkGroup.push(sendData);

					this.showItemLight(audio_url, () => {
						this.changeNewWord();
					});
				});
			});
		}
	},

	showItemLight(isGood, callback = null) {

		console.log("in showItemLight")
		const bottomSpr = this.getSprNode(this.curData.data.bottomSpr);
		const topSpr = this.getSprNode(this.curData.data.topSpr);
		
		const bs = bottomSpr.getComponent(cc.Sprite);
		bs.trim = false;
		bs.sizeMode = cc.Sprite.SizeMode.RAW;
		
		const ts = topSpr.getComponent(cc.Sprite);
		ts.trim = false;
		ts.sizeMode = cc.Sprite.SizeMode.RAW;

		this.bg.addChild(bottomSpr);
		this.bg.addChild(topSpr);

		// let audioClip;
		let url
		if (isGood) {
			bottomSpr.color = cc.Color.GREEN;
			// audioClip = this.getAudioClicp('good');
			if ((this.round == 1 && this.isPlayer1) 
				|| (this.round == 2 && this.isPlayer2)) {
				url = this.data.talk_right_audio_url;
			} else {
				url = this.data.search_right_audio_url;
			}
			this.sendServerEvent('add_score')
			this.selfScore ++;
		} else {
			bottomSpr.color = cc.Color.RED;
			// audioClip = this.getAudioClicp('bad');
			if ((this.round == 1 && this.isPlayer1) 
				|| (this.round == 2 && this.isPlayer2)) {
				url = this.data.talk_wrong_audio_url;
			} else {
				url = this.data.search_wrong_audio_url;
			}

		}
		
		cc.audioEngine.stopAllEffects();
		
		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		
		playAudioByUrl(url, () => {
		// playAudio(audioClip, () => {
			playDragonBoneAnimation(this.coolcat, 'normal', -1);

			callback && callback();
		});

		cc.tween(bottomSpr)
			.to(0.3, {opacity: 0})
			.to(0.3, {opacity: 255})
			.to(0.3, {opacity: 0})
			.to(0.3, {opacity: 255})
			.to(0.3, {opacity: 0})
			.to(0.3, {opacity: 255})
			.start();
	},



	getWordData(data) {
		console.log(' getWordData: ', data);
		this.showTalkIcon(false);

		if(this.round == 1 && this.aiGameData) {
			this.showAiSearching(data);
		}

		if ((this.isPlayer1 && this.round == 1) || (this.isPlayer2 && this.round == 2)) {
			return;
		}

		this.playerAudioDataArr.push(data);
		const audio_url = data.audio_url;
		if (audio_url) {
			cc.assetManager.loadRemote(audio_url, (err, audioClip) => {

			});
		}

		if (this.isSearching) {
			return;
		}

		if (this.isListenTipEnd) {
			this.setSearchData();
			return;
		}
		this.isListenTipEnd = true;
		
		this.isSearching = true;
		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		playAudioByUrl(this.data.search_start_audio_url, () => {
		// this.playAudioByName('search_tip', () => {
			playDragonBoneAnimation(this.coolcat, 'normal', -1);

			this.setSearchData();
		});

	},

	setSearchData() {
		console.log(' in setSearchData')
		this.isSearching = true;

		const data = this.playerAudioDataArr.shift();
		const audio_url = data.audio_url;

		this.initCurData(data.word);
		this.initCurClickSpr();
		this.searchWrongCount = 0;

		if (audio_url) {
			cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
				this.curData.data.audioClip = audioClip;
				this.showTalkBtn()
				this.showWatch();
				this.searchTypeClick();
			});
		} else {
			this.showTalkBtn()
			this.showWatch();
			this.searchTypeClick();
		}

	},


	showAiSearching(data) {
		const {searchGroup} = this.aiGameData;

		let index = -1;
		for(let i=0; i<searchGroup.length; i++) {
			if (searchGroup[i].word == data.word) {
				index = i;
				break;
			}
		}

		const subData = searchGroup.splice(index, 1)[0];
		this.sendServerEvent("show_search_icon", true)

		setTimeout(() => {
			console.log('subData: ', JSON.stringify(subData));
			if (subData.isRight) {
				this.sendServerEvent('add_score')
			}
			this.sendServerEvent("show_search_icon", false)

			if (searchGroup.length == 0) {
				console.log('next_round 444 ')
				this.sendServerEvent("next_round")
			}			

		}, 3000);
	},

	showAiTalking() {

		this.sendServerEvent("show_talk_icon", true)

		setTimeout(() => {
			
			const {talkGroup} = this.aiGameData;
			const subData = talkGroup.shift();

			console.log('subData: ', JSON.stringify(subData));


			this.sendServerEvent('word_data', subData);

			if (talkGroup.length > 0) {
				setTimeout(() => {
					this.showAiTalking();
				}, 1500);
			} else {
				console.log('next_round 555 ')
				this.sendServerEvent("next_round")
			}

		}, 3000);

	
	},


	showWatch() {
		console.log(' in showWatch')
		this.watchNode.active = true;
		this._watchTime = 0;
		this.isWatchCountDown = true;
	},

	hideWatch() {
		this.isWatchCountDown = false;
		this.watchNode.active = false;
	},
	

	hideTalkBtn() {
		this.talkBtn.active = false;
		this.hideWave();
		this.hideShake();
	},

	showTalkBtn() {
		this.talkBtn.active = true;
	},

	playWave() {
		// console.log(' in playWave')

		const wave = this.talkBtn.wave;
		wave.active = true;
		wave.opacity = 0;

		if(wave.tween) {
			wave.tween.stop();
		}

		wave.tween = cc.tween(wave)
			.to(0.3, {opacity: 255}, {easing: "cubicOut"})
			.to(0.3, {opacity: 0}, {easing: "cubicIn"})
			.call(() => {
				if (this.isShowWave) {
					this.playWave();
				} else {
					this.hideWave();
				}
			})
			.start();
	},

	showWave() {
		// console.log(' in showWave ');
		if (this.isShowWave) {
			return;
		}
		this.isShowWave = true;
		this.playWave();
	},

	hideWave() {
		// console.log(' in hideWave ');

		this.isShowWave = false;
		this.talkBtn.wave.active = false;
	},

	playShake() {
		// console.log(' in playShake')
		const shake = this.talkBtn.shake;
		shake.active = true;
		shake.opacity = 0;

		if (shake.tween) {
			shake.tween.stop();
		}

		shake.tween = cc.tween(shake)
			.to(0.3, {opacity: 255}, {easing: "cubicOut"})
			.to(0.3, {opacity: 0}, {easing: "cubicIn"})
			.call(() => {
				if (this.isShowShake) {
					this.playShake();
				} else {
					this.hideShake();
				}
			})
			.start();
	},

	showShake() {
		// console.log(' in showShake ');

		if (this.isShowShake) {
			return;
		}
		this.isShowShake = true;
		this.playShake();
	},

	hideShake() {
		// console.log(' in hideShake ');

		this.isShowShake = false;
		this.talkBtn.shake.active = false;
	},


	showRecordAudio() {
		this.showWave();

		playAudio(this.curData.data.audioClip, () => {
			playAudio(this.curData.data.audioClip, () => {
				this.hideWave();
				// if (this.isShowSearchTip) {
				// 	return;
				// }
				// this.isShowSearchTip = true;
				// this.showSearchTip();
			})
		})
	},

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

		});
	},

	initCurClickSpr() {

		const topSpr = this.getSprNode(this.curData.data.topSpr);
		const ts = topSpr.getComponent(cc.Sprite);
		ts.trim = false;
		ts.sizeMode = cc.Sprite.SizeMode.RAW;

		this.bg.addChild(topSpr);

		topSpr.opacity = 1;
		topSpr._hitTest = this._hitTest.bind(this);

		this.curTopSpr = topSpr;

		topSpr.on(cc.Node.EventType.TOUCH_START, (e) => {
			e.stopPropagation();

			this.searchRight();
		})

	},

	searchRight() {

		this.hideWatch();

		this.hideTalkBtn();

		this.showItemLight(true, ()=> {

			this.searchEnd();
		});

		this.resultSearchGroup.push({word: this.curData.word, isRight: true});
		this.curTopSpr.active = false;
	},
	
	searchWrong() { 

		this.hideWatch();

		this.hideTalkBtn();

		this.showItemLight(false, ()=> {

			this.searchEnd();
		});

		this.resultSearchGroup.push({word: this.curData.word, isRight: false});
		this.curTopSpr.active = false;
	},

	searchEnd() {
		console.log(' in searchEnd' )

		this.isShowSearchIcon = false;
		this.sendServerEvent('show_search_icon', false)

		if (this.playerAudioDataArr.length > 0) {
			this.setSearchData();
		} else {
			this.isSearching = false;
			if ((this.isPlayer2 && this.wordDataArr.length == 5)
				|| (this.wordDataArr.length == 0)) {
					console.log('next_round 111 ')
				this.sendServerEvent("next_round")
			}
		}
	},

	changeNewWord() {
		if (this.isPlayer1) {
			if (this.dataGroup1.length > 0) {
				this.initCurData();
				this.showTalkBtn();
			} else {
				console.log('next_round 222 ')
				this.sendServerEvent('next_round')
			}
		} else {
			if (this.dataGroup2.length > 0) {
				this.initCurData();
				this.showTalkBtn();
			} else {
				console.log('next_round 333 ')
				this.sendServerEvent('next_round')
			}
		}
	},

	nextRound() {
		console.log(" in nextRound")

		this.roundChangeCount ++;
		if (this.roundChangeCount < 2) {
			return;
		}
		this.roundChangeCount = 0;

		this.round ++;
		if (this.round >= 3) {
			this.gameEnd();
			return;
		}

		playDragonBoneAnimation(this.coolcat, 'begin', -1);
		playAudioByUrl(this.data.next_round_audio_url, () => {
		// this.playAudioByName('round_tip', () => {

			playDragonBoneAnimation(this.coolcat, 'normal', -1);

			if (this.isPlayer1) {
				if (this.aiGameData) {
					this.showAiTalking();
				}
			} else {
				this.dataGroup2 = this.wordDataArr;
				this.initCurData();
				this.showTalkBtn();
			}
		});

	
	},

	gameEnd() {
		console.log('in game end');
		this.showResultLayer();
		this.saveAnswer();
		// console.log('this.resultDataArr: ', this.resultDataArr)
		console.log('this.resultTalkGroup: ', JSON.stringify( this.resultTalkGroup) );
		console.log('this.resultSearchGroup: ', JSON.stringify( this.resultSearchGroup) );

		onHomeworkFinish();
	},

	saveAnswer() {

		console.log(' in saveAnswer')
		const resultData = {
			talkGroup: this.resultTalkGroup,
			searchGroup: this.resultSearchGroup
		}


		const node = cc.find('middleLayer');
		if (node) {
			console.log('node exist');
			const mScript = node.getComponent('middleLayer');

			console.log(' saveAnswer ~ :', JSON.stringify(resultData));

			mScript.saveAnswer(resultData, () => {
				callback && callback();
			})
		}
	},

	showResultLayer() {

		this.resultLayer.totalScore.string = this.score;
		const friendScore = this.score - this.selfScore;
		if (this.isPlayer1) {
			this.resultLayer.score1.string = this.selfScore;
			this.resultLayer.score2.string = friendScore;
		} else {
			this.resultLayer.score1.string = friendScore;
			this.resultLayer.score2.string = this.selfScore;;
		}

		this.resultLayer.active = true;
		this.resultLayer.opacity = 0;

		cc.tween(this.resultLayer)
			.to(0.3, {opacity: 255})
			.start();
	},

	showTalkIcon(value) {
		let talkIcon;
		if (this.round == 1) {
			talkIcon = cc.find("Canvas/bg/player_1/head_talk");
		} else {
			talkIcon = cc.find("Canvas/bg/player_2/head_talk");
		}

		talkIcon.active = value;
	},

	showSearchIcon(value) {
		let searchIcon;
		if (this.round == 2) {
			searchIcon = cc.find("Canvas/bg/player_1/head_search");
		} else {
			searchIcon = cc.find("Canvas/bg/player_2/head_search");
		}

		searchIcon.active = value;

	},



	



	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('');
		this.color_selector.active = true;
		// this.color_selector.x = this.color_buttons[0].x;
		// this.color_selector.y = this.color_buttons[0].y;
		this._color = this.getColor("f8ed21");

		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 );
		// }

		this.isTimingShow = false;
		
		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, (e) => {

			e.stopPropagation();

			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');

				console.log(' ~		this._can_tap = true;  ')
				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();
		}

		// console.log('data~ : ', data);

		if (data[3] > 0) {
			console.log(" return true");
			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 };

		// const node = cc.find('middleLayer');
		// if (node) {
		// 	console.log('node exist');
		// 	const mScript = node.getComponent('middleLayer');

		// 	console.log(' saveAnswer ~ :', JSON.stringify(data));

		// 	mScript.saveAnswer(data, () => {
		// 		callback && callback();
		// 	})
		// }

		
		// 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:"aaaa", data:{a:"1"}});

		this.networkHelper.sendFrame({
			type: key,
			data
		});

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

	log (str) {
    const node = cc.find('middleLayer');
    if(node){
      node.getComponent('middleLayer').log(str);
    }else{
      cc.log(str);
    }
  },


	update(dt) {
		this.updateTimer(dt)
		this.updateWatch(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);
		});
	},
});
