import { getDragonboneByUrl, getSprNode, onHomeworkFinish, playAudio, playAudioByUrl } from "../script/util";
import { defaultData, questionData } from "../script/defaultData";

cc.Class({

	extends: cc.Component,

	properties: {
	},

	// 生命周期 onLoad
	onLoad() {
		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 自缩放 （较少用到）
	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
	start() {
		let getData = this.getData.bind(this);
		if (window && window.courseware) {
			getData = window.courseware.getData;
		}

		getData((data) => {
			console.log('data:', data);
			this.data = data || this.getDefaultData();
			this.data = JSON.parse(JSON.stringify(this.data))

			console.log('this.data Json:', JSON.stringify(this.data));

			this.preloadItem()
		})
	},

	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.addPreloadImage();
		this.addPreloadAudio();
		this.addPreloadAnima();
		this.preload();
	},


	addPreloadImage() {

		if (this.data.exercises) {
			// this._imageResList.push({ url: this.data.picUrl });
		}
	},

	addPreloadAudio() {

		// if (this.data.exercises) {

		// 	this._audioResList.push({ url: this.data.exercises.audioUrl });
		// }

		for (let i=0; i<this.data.letterArr.length; i++) {
			this._audioResList.push({ url: this.data.letterArr[i].audio_url || '' });
		}

		this._audioResList.push({ url: this.data.begin_audio_url || '' });
		this._audioResList.push({ url: this.data.tip_audio_url || '' });
		this._audioResList.push({ url: this.data.end_audio_url || '' });


	},

	addPreloadAnima() {

			this._animaResList.push({ url: this.data.skeJsonData?.url || '' });
			this._animaResList.push({ url: this.data.texJsonData?.url || '' });
			this._animaResList.push({ url: this.data.texPngData?.url || '' });

			this._animaResList.push({ url: this.data.letterAnim?.skeJsonData?.url || '' });
			this._animaResList.push({ url: this.data.letterAnim?.texJsonData?.url || '' });
			this._animaResList.push({ url: this.data.letterAnim?.texPngData?.url || '' });


	},

	preload() {

		const preloadArr = this._imageResList.concat(this._audioResList).concat(this._animaResList);
		cc.assetManager.loadAny(preloadArr, null, null, (err, data) => {

			this.addServerListener();
	

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

	addServerListener() {

		if (window && window["air"]) {

			// cc.find('Canvas').opacity = 0;
			window.air.onCourseInScreen = (next) => {
			//  cc.find('Canvas').opacity = 255;
			 this.loadEnd();
			 next();
			}
			window.air.hideAirClassLoading();
		 } else {
			this.loadEnd();
		 }



		 if (window.air) {
			window.air.osmoHandwritingCallback = (data) => {

				// this.log('in osmoHandwritingCallback');
				if (!data) {
					// this.log('data is not exist!!!');
					return;
				}
			
				console.log('osmoHandwritingCallback data: ', data);

				if (typeof (data) == 'string') {
					this.log('data is string ');
					const dataObj = JSON.parse(data);

					this.photoEnd(dataObj);
					return;
				}

				// 哲学逻辑
				this.photoEnd(data);
			}
		}
	},

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


	loadEnd() {

		if (this.isInitEnd) {
			this.log(' isInitEnd ')
			return;
		}
		this.initData();
		this.initAudio();
		this.initView();

		this.isInitEnd = true;


		// this.initListener();
	},


	_cantouch: null,
	initData() {
		// 所有全局变量 默认都是null 
		this._cantouch = false;

	},

	audioBtn: null,
	audioBegin: null,
	audioTipArea: null,
	audioTipLetter: null,
	audioTipIcon: null,
	audioTipSuccess: null,

	audioTipError: null,
	audioTipNotFill: null,
	audioTipFillWrong: null,
	audioOsmoTip: null,
	audioRight: null,
	initAudio() {
		const audioNode = cc.find('Canvas/res/audio');

		const getAudioByResName = (resName) => {
			return audioNode.getChildByName(resName).getComponent(cc.AudioSource);
		}

		this.audioBtn = getAudioByResName('btn');

		this.audioBegin = getAudioByResName('begin');

		this.audioTipArea = getAudioByResName('tip_area');
		
		this.audioTipError = getAudioByResName('tip_error');
		this.audioTipNotFill = getAudioByResName('tip_not_fill');
		this.audioTipFillWrong = getAudioByResName('tip_fill_wrong');

		this.audioTipLetter = getAudioByResName('tip_letter');
		this.audioTipIcon = getAudioByResName('tip_icon');
		this.audioTipSuccess = getAudioByResName('tip_success');

		this.audioTip1 = getAudioByResName('tip_1');
		this.audioTip2 = getAudioByResName('tip_2');
		this.audioTip3 = getAudioByResName('tip_3');

		this.audioOsmoTip = getAudioByResName('osmo_tip');
		this.audioRight = getAudioByResName('right');

		this.audioDefault = getAudioByResName('default');


	},



		//调起检测
		startTesting() {

			// this.getPhotoData((data) => {
			// 	this.photoEnd(data);
			// });  
			// return;

			const cw = window.courseware;
			if (!cw || !cw.openOsmoHandwriting) {

				console.log('cw.openOsmoHandwriting not exist');
				return;
			}


			const para =
			{
				"library_id": "iplayabc",
				"page_id": 15, //27,
				"book_id": 'opw1',//"opw1",
				"part_name": 'd', //"d",
				"is_hand_writing": true,
				"is_line_link": false,
				"ques_region": [
					0, 0.332,
					1, 0.332,
					1, 0.727,
					0, 0.727
				]
			}

	
			cw.openOsmoHandwriting(para);


			// setInterval(() => {
				// this.getPhotoData((data) => {
				// 	this.photoEnd(data);
				// });           
				
			// }, 1000);
		},
	
		//结束检测
		endTesting() {
			const cw = window.courseware;
			if (!cw || !cw.closeOsmoHandwriting) {

				return;
			}
			cw.closeOsmoHandwriting();
			// this.isTesting = false;
		},

	initView() {

		this.initBg();
		this.initCatListener();

		this.initLetterItem();
		// this.initPhotoBtn();
		this.initContent();

		this.initDebugLayer();

		this.gameStart();

		// this.showPhotoBtn();

		// this.addDefaultMusic();

		this.initMask();



	},


	initCatListener() {

		const cat = cc.find('Canvas/content/catFrame/cat');
		const dragonDisplay = cat.getComponent(dragonBones.ArmatureDisplay);


		const clickBox = cc.find("Canvas/content/catFrame/clickBox");
		clickBox.on('touchstart', () => {

			if (dragonDisplay.animationName != 'normal') {
				return;
			}

			if (this.isLetterPlaying) {
				return;
			}
	
			dragonDisplay.playAnimation('begin', 0);
			playAudioByUrl(this.data.tip_audio_url, () => {
				this.playAni('normal', -1);
			})

		})
	},


	maskNode: null,
	initMask() {

		const maskNode = new cc.Node();
		maskNode.width = this.canvas.width;
		maskNode.height = this.canvas.height;
		maskNode.anchorX = 0.5;
		maskNode.anchorY = 0.5;
		const mask = maskNode.addComponent(cc.Graphics);
		mask.fillColor = cc.Color.BLACK.setA(100);
		mask.fillRect(-this.canvas.width/2, -this.canvas.height/2, this.canvas.width, this.canvas.height);
		this.canvas.addChild(maskNode, 9);

		maskNode.addComponent(cc.BlockInputEvents);
		maskNode.active = false;
		this.maskNode = maskNode;
	},

	addDefaultMusic() {
		// console.log(' in ')
		// playAudio(this.audioDefault.clip, () => {
		// 	console.log(' wusheng end');
		// })
		cc.audioEngine.play(this.audioDefault.clip, true, 0.8);

	},


	initBg() {
		const bgNode = cc.find('Canvas/bg');
		bgNode.scale = this._mapScaleMax;

		const canvas = cc.find('Canvas');
		bgNode.scale = Math.max((canvas.width / bgNode.width), (canvas.height / bgNode.height));
		
		const bgSpr = getSprNode("bg_egg");
		// bgSpr.y = -0 * this._mapScaleMin;
		// bgSpr.scale = this._mapScaleMin * 2;
		bgSpr.scale = this._mapScaleMin;
		canvas.addChild(bgSpr)
	},


	letterItemArr: null,
	initLetterItem() {

		this.letterItemArr = [];
		const letterArr = this.data.letterArr //questionData.letter_arr;
		let row = 0;
		let col = 0;
		const disH = 310 * this._mapScaleMin;
		const disW = 315 * this._mapScaleMin;
		const baseX =  - (disW * 4) / 2 + disW / 2 + 5 * this._mapScaleMin;
		const baseY = 20*this._mapScaleMax + disH / 2;
		for (let i=0; i<letterArr.length; i++) {

			const item = this.getOneItem(letterArr[i], i);
			// console.log('item: ', item);
			this.canvas.addChild(item);
			item.x = baseX + col * disW;
			item.y = baseY - row * disH;

			col ++;

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

			item.hitCount = 0;
			this.letterItemArr.push(item);

		}
		
	},

	getOneItem(data, index) {
		const item = getSprNode('item_bg');
		item.scale = this._mapScaleMin;

		const id = index + 1;
		const icon = getSprNode('icon_' + id)
		icon.x = -item.width / 2 + 30;
		icon.y = item.height / 2 - 30;
		item.addChild(icon);

		



		// let resName = 'letter';

		// if (!data.is_right) {
		// 	resName = 'x';
		// }

		// const anim = cc.find("Canvas/res/anim/" + resName)
		// const letter = cc.instantiate(anim)	

		// letter.name = resName;



		// item.addChild(letter);
		// letter.active = false;
		// item.letter = letter;

		const btnSound = getSprNode('btn_sound');
		btnSound.x = item.width / 2 - 30;
		btnSound.y = item.height / 2 - 30;
		item.addChild(btnSound, 2);
		btnSound.active = false;
		item.btnSound = btnSound;


		let letter;

		const addBtnSoundListener = () => {
			btnSound.addComponent(cc.Button);
			btnSound.on('click', () => {
				console.log('btnSond click');
	
				cc.audioEngine.stopAll();
				// this.stopCat();
				this.isLetterPlaying = true;
				this.playAudioByUrl(data.audio_url, () => {
					this.isLetterPlaying = false;
				});
	
				// if (index == 0 || index == 1) {
				// 	letter.isShow = false;
				// 	this.showItemAniNew(letter);
				// }
			})
		}

		
		if (!data.is_right) {
			this.getAnimX((animNode) => {

				letter = animNode;
				letter.parent = item;
				letter.active = false;
				item.letter = letter;

				letter.animationNames = ['Sprite'];

				addBtnSoundListener();
			});
		} else {
			 this.getAnimLetter((animNode) => {

				letter = animNode;
				letter.parent = item;
				letter.active = false;
				item.letter = letter;

				addBtnSoundListener();


				// this.showFirstLetter();
			});
		}

		return item;
	},

	getAnimX(cb) {

		if (!this.animX) {
			this.animX = cc.find('Canvas/res/anim/x');
		}

		const animNode = cc.instantiate(this.animX);
		cb(animNode);
	},

	getAnimLetter(cb) {
		this.getOneAnim(this.data.letterAnim, cb);
	},


	getOneAnim(data ,cb) {

		const animaNode = new cc.Node();
		// animaNode.name = 'anima_' + data.index;
		// this.hotZoneBg.addChild(animaNode);

		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}
		
		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
		cc.loader.load(image, (error, texture) => {

			cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {

				cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

					const asset = new dragonBones.DragonBonesAsset();
					asset.dragonBonesJson = dragonBonesJson;

					dragonDisplay.dragonAtlasAsset = atlas;
					dragonDisplay.dragonAsset = asset;


					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];

					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}

					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
			
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						let animationNames = [];
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

						animaNode.animationNames = animationNames;

					}


					cb(animaNode);

				});
			});
		});

	},



	stopCat() {
		this.playAni('normal', -1);
	},

	initContent() {

		const content = cc.find('Canvas/content');
		content.zIndex = 10;
	},

	debugLayer: null,
	initDebugLayer() {
		const layer = new cc.Node();
		layer.x = -this.canvas.width / 2 + 50;
		layer.y = this.canvas.height / 2 - 50;
		layer.opacity = 180;
		if (!this.data.isDebug) {
			layer.active = false;
		}

		const sample = getSprNode('sample');
		sample.anchorX = 0;
		sample.anchorY = 1;
		this.sample = sample;
	
		layer.addChild(sample);

		layer.width = sample.width;
		layer.height = sample.height;
		layer.anchorX = 0;
		layer.anchorY = 1;
		layer.scale = this.canvas.height / layer.height / 2;


		const topLeftRect = [
			{x1: 0.129, y1:0.446},
			{x2: 0.288, y2:0.446},
			{x3: 0.288, y3:0.535},
			{x4: 0.129, y4:0.535},
		]

		this.dotArr = [];

		const len = 8;
		const disW = 0.198;// * sample.width; 322
		const disH = 0.139;// * sample.height;
		let row = 0;
		let col = 0;
		for (let i=0; i<len; i++) {

			const posArr = JSON.parse(JSON.stringify(topLeftRect))
			posArr[0].x1 += col * disW;
			posArr[1].x2 += col * disW;
			posArr[2].x3 += col * disW;
			posArr[3].x4 += col * disW;

			posArr[0].y1 += row * disH;
			posArr[1].y2 += row * disH;
			posArr[2].y3 += row * disH;
			posArr[3].y4 += row * disH;

			const colorRect = this.getColorRectByPos(posArr, 'blue')
			// colorRect.x += col * disW;
			// colorRect.y -= row * disH;


			sample.addChild(colorRect);

			this.dotArr.push(colorRect);

			col ++;

			if (i == (len/2 -1)) {
				col = 0;
				row ++;
			}


		}


	
		this.canvas.addChild(layer, 100)
		this.debugLayer = layer;


		this.addDebugLayerListener();
	},
	

  addDebugLayerListener() {

		if (!this.data.isDebug) {
			return;
		}

		this.debugLayer.on('touchstart', (e) => {

			const worldPos = e.getLocation();

			const localPos = this.debugLayer.convertToNodeSpaceAR(worldPos)

			this.addDebugLayerDot(localPos.x, localPos.y);
			// this.debugLayer

		})
	},

	addDebugLayerDot(x, y, r=10, color = null) {
    const dotNode = new cc.Node();

    const ctx = dotNode.addComponent(cc.Graphics);
    ctx.fillColor = color || cc.Color.BLUE;
    ctx.circle(x, y, r);
    ctx.fill();

    this.sample.addChild(dotNode);

    const w = this.debugLayer.width;
    const h = this.debugLayer.height;
    const rateX = x / w;
    const rateY = y / h;
    
    console.log('ratePos: {x: ' + rateX + ', y: ' + rateY + '}')
  },

 
	gameStart() {


		this.playAni('begin', 0)

		//播放引导音频1

		playAudioByUrl(this.data.begin_audio_url, () => {

			if (this.isDestroy) {
				return;
			}

			this.playAni('normal', 0);
			this.showAllSound();
			this.startTesting();


		})



		// playAudio(this.audioTip1.clip, ()=> {

		// 	// this.playAudioByUrl(this.data.guideAudioUrl1, () => {
		// 	this.showFirstLetter();

		// });
	},


	showFirstLetter() {

		if (this.isShowFirstEnd) {
			return;
		}

		this.isShowFirstEnd = true;
		this.showLetter(0);
		this.showLetter(1);

		return
	
		this.showLetter(0, () => {

			playAudio(this.audioTip2.clip, () => {


			//播放引导音频2
			// this.playAudioByUrl(this.data.guideAudioUrl2, () => {
			if (this.isDestroy) {
				return;
			}
			
				this.showSecondLetter();
			});
			
		})
	},

	showSecondLetter() {
		this.showLetter(1, () => {

			playAudio(this.audioTip3.clip, () => {

				if (this.isDestroy) {
					return;
				}
				

				this.showAllSound();
				// this.showPhotoBt n();
				this.startTesting();

				this.playAni('normal', 0);

			});
	
		})
	},


	showLetter(index, cb, needCheck = false) {

		const item = this.letterItemArr[index];

		if (needCheck) {
			item.hitCount ++;
			if (item.hitCount < 1) {
				return;
			}

		}
	

		if (item.isShow) {
			return;
		}

		if (needCheck) {
			playAudio(this.audioRight.clip)
		}

		item.isShow = true;

		this.timer_1 = setTimeout(() => {
			
			this.showItemAni(item.btnSound, null);
			this.showItemAniNew(item.letter, () => {
				if (cb) {
					cb();
				}
			});

		}, 100 * Math.random());



	},

	showItemAniNew(item, cb) {
		if (item.isShow) {
			return;
		}
		item.isShow = true;
		item.active = true;


		var dragonDisplay = item.getComponent(dragonBones.ArmatureDisplay);
		dragonDisplay.playAnimation(item?.animationNames[0] , 1);
		dragonDisplay.on(dragonBones.EventObject.COMPLETE, () => {
			cb && cb();
		})

		// const anim = item.getComponent(cc.Animation);
		// console.log(' showItemAniNew  item: ', item);

		// anim.play(item.name);
		// anim.on('finished', () => {
		// 	console.log('in finished');
		// 	if (cb) {
		// 		cb();
		// 	}
		// });

	},

	showItemAni(item, cb) {
		if (item.isShow) {
			return;
		}
		item.isShow = true;

		item.opacity = 0;
		item.active = true;
		cc.tween(item)
		.to(1,{opacity: 255})
		.call(() =>{
			if (cb) {
				cb();
			}
		})
		.start();
	},

	showAllSound() {
		const letterItemArr = this.letterItemArr;
		for (let i=0; i<letterItemArr.length; i++) {
			const item = letterItemArr[i];
			this.showItemAni(item.btnSound);
		}
	},






	playAni(name, times = 1) {

		const cat = cc.find('Canvas/content/catFrame/cat');

		var dragonDisplay = cat.getComponent(dragonBones.ArmatureDisplay);

		const state = dragonDisplay.playAnimation(name, times);
		return state;
	},

	playTipAni(name, times = 1, cb=null) {

		const tip = cc.find('Canvas/tipFrame/tip');
		tip.parent.zIndex = 10;
		tip.active = true;

		var dragonDisplay = tip.getComponent(dragonBones.ArmatureDisplay);

		const state = dragonDisplay.playAnimation(name, times);

		dragonDisplay.on(dragonBones.EventObject.COMPLETE, () => {
			tip.active = false;
			if (cb) {
				cb();
			}
		})

		return state;
	},

	moveHand(index, callback = null) {

		let textNode = cc.find("Canvas/content/bg_green/bg_word-background/text");

		let wordNodeArr = textNode.wordNodeArr

		let wordNode = wordNodeArr[2 * index];

		if (!wordNode) {

			if (callback) {
				callback();
			}
			return;
		}

		let handNode = cc.find("Canvas/content/bg_green/bg_word-background/text/icon_hand");
		handNode.x = wordNode.x;

		this.handAni();

		if (callback) {
			callback();
		}
	},

	/**
	 * 播放文本音频
	 * @param {*} callback 
	 */
	playTextAutio(callback = null) {

		this.playAudioByUrl(this.data.exercises.audioUrl, () => {

			if (this.isDestroy) {
				return;
			}
			

			//停止监听动画
			this._stopAni = true;

			if (callback) {
				callback();
			}
		},(audioId) => {

			//显示完成，不再播放动画
			if (this._shown) {
				return;
			}

			//设置可播放动画
			this._stopAni = false;

			//隐藏手指
			let handNode = cc.find("Canvas/content/bg_green/bg_word-background/text/icon_hand");
			handNode.opacity = 0;

			let lyrics = this.data.exercises.lrcData.lyrics;

			//临时音频打点数组
			let arr = JSON.parse(JSON.stringify(lyrics));
			console.log(arr);
		
			this.monitor(audioId, arr);
		})
	},

	/**
	 * 重新设置文字位置
	 */
	resetTextPosition() {

		let textNode = cc.find("Canvas/content/bg_green/bg_word-background/text");

		let wordNodeArr = textNode.wordNodeArr;

		//间隔
		let space = 40;

		let tW = 0;

		for (let i = 0; i < wordNodeArr.length; ++i) {

			let wordNode = wordNodeArr[i];
			wordNode.removeFromParent();
			wordNode.parent = textNode;
			tW += wordNode.width;

			let widget = wordNode.getComponent(cc.Widget);
			widget.bottom = - wordNode.getComponent(cc.Label).fontSize / 2;
			widget.updateAlignment();

			wordNode.initScale = wordNode.scale;
		}

		tW += (this.data.exercises.wordArr.length - 1) * space;

		let startX = -  tW / 2;

		for (let i = 0; i < wordNodeArr.length; ++i) {
			let width = wordNodeArr[i].width;
			wordNodeArr[i].x = startX + width / 2;
			startX += width;

			if (wordNodeArr[i].isInitial) {
				continue;
			}
			startX += space;
		}

		if(tW > textNode.width){
			const sx = textNode.width / tW;

			textNode.scale = Math.round(sx * 1000) / 1000;

			textNode.initScale = textNode.scale;
		}
	},


	/**
	 * 显示结束
	 */
	_shown: null,
	showEnd() {

		console.log(' in showEnd');

		if (this._curIndex < this.data.exercises.wordArr.length) {
			return;
		}

		if (this._shown) {
			return;
		}

		this._shown = true;

		let handNode = cc.find("Canvas/content/bg_green/bg_word-background/text/icon_hand");
		handNode.opacity = 0;
		this._stop = true;

		//播放动画
		const state = this.playAni('finish', 0);
		
		//播放引导音频2
		this.playAudioByUrl(this.data.guideAudioUrl2, () => {

			if (this.isDestroy) {
				return;
			}
			

			state.stop();

			this.playAni('normal', 0);

			this.showPhotoBtn();
		});

		
	},

	_stop: null,
	_tween: null,
	handAni(){

		let handNode = cc.find("Canvas/content/bg_green/bg_word-background/text/icon_hand");

		handNode.opacity = 255;
		handNode.y = handNode.initY;
		const move = () => {
			this._tween = cc.tween(handNode)
			.to(0.5,{y: handNode.initY + 50})
			.to(0.5,{y: handNode.initY})
			.call(() =>{
	
				if(!this._stop){
					move()
				}
			})
			.start();
		}

		this._stop = false;

		move();
	},

	_stopAni:null,
	monitor(audioId, arr){

		if(this._stopAni){
			return;
		}

		this._stopAni =  false;

		let currentTime = cc.audioEngine.getCurrentTime(audioId);
		
		let len = arr.length;
	
		for(let i = len - 1; i >=0; -- i){

			let time = arr[i].time;

			time = Math.round(time * 1000) / 1000;

			currentTime = Math.round(currentTime * 1000) / 1000;
			
			if(time < currentTime ){
				
				//如果是最后一个匹配，则播放内容动画
				if(len == 1){
					this.contentAni();
				}
				else{
					this.textAni();
				}

				//移除匹配上的元素
				arr.splice(i, 1);
				
				break;
			}
			
		}

		requestAnimationFrame(()=>{
			
			this.monitor(audioId, arr);
		})
	},

	/**
	 * 文本动画
	 */
	_playText:null,
	textAni(){

		if(this._playText){
			return;
		}

		this._playText = true;

		this._cantouch = false;

		const twinkle =(node) => {
			cc.tween(node)
			.to(0.3,{scale: node.initScale * 1.5})
			.to(0.3,{scale: node.initScale})
			.call(() => {
				this._playText = false;
			})
			.start();
		};

		let textNode = cc.find("Canvas/content/bg_green/bg_word-background/text");

		let wordNodeArr = textNode.wordNodeArr;

		for (let i = 0; i < wordNodeArr.length; ++i) {
			let wordNode = wordNodeArr[i];

			//如果是首字母，则执行动画
			if(wordNode.isInitial){
				twinkle(wordNode);
			}
		}
		
	},


	/**
	 * 内容动画
	 */
	 contentAni(){

		let handNode = cc.find("Canvas/content/bg_green/bg_word-background/text/icon_hand");
		handNode.opacity = 0;

		const twinkle =(node) => {
			cc.tween(node)
				.to(0.5,{scale: node.initScale * 1.1})
				.to(0.5,{scale: node.initScale})
				.to(0.5,{scale: node.initScale * 1.1})
				.to(0.5,{scale: node.initScale})
				.call(()=>{
					this._cantouch = true;
				})
				.start();
		};

		let textNode = cc.find("Canvas/content/bg_green/bg_word-background/text");

		twinkle(textNode);
	},



	photoBtn: null,
	initPhotoBtn() {

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

		const photoBtn = this.getSprNode('btn_photo');
		photoBtn.active = false;
		canvas.addChild(photoBtn);
		photoBtn.scale = this._mapScaleMin;
		// photoBtn.x = 100;
		photoBtn.y = -canvas.height / 2 + photoBtn.height / 2 * photoBtn.scaleY;
		photoBtn.addComponent(cc.Button);
		photoBtn.on('click', () => {
			this.showPhotoTip();
		})

		this.photoBtn = photoBtn;
	},

	showPhotoBtn() {
		if (!this.photoBtn) {
			this.initPhotoBtn();
		}
		this.photoBtn.active = true;
	},

	hidePhotoBtn() {
		if (!this.photoBtn) {
			return;
		}
		this.photoBtn.active = false;
	},

	showPhotoTip() {

		this.maskNode.active = true;
		playAudio(this.audioOsmoTip.clip);
		this.playAni('begin', 0)
		this.playTipAni('normal', 1, () => {
			console.log('play ani end');

			this.playAni('normal', 0)


			this.photoBtnClick();

		})


	},

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

		if (!window || !window.courseware) {
			console.log('window.courseware not found')
			return;
		}


		// window.courseware.openRecognitionCamera = this.getPhotoData.bind(this);

		const openRecognitionCamera = window.courseware.openRecognitionCamera;
		if (!openRecognitionCamera) {
			console.log('openRecognitionCamera not found')
			return;
		}
		openRecognitionCamera((data) => {
			console.log('openRecognitionCamera data: ', data)

			this.timer_2 = setTimeout(() => {
				
				if ( typeof data == 'string' ) {
					data = JSON.parse(data);
				}
	
				const {result} = data;
				this.photoEnd(result);

				this.maskNode.active = false;
			}, 100);

		

		})

	},

	photoEnd(data) {

		// const result = data.result;
		// for (let i=0; i<result.length; i++) {
		// 	result[i].top *= 800;
		// 	result[i].bottom *= 800;
		// 	result[i].left *= 800;
		// 	result[i].right *= 800;
		// }



		this.sample.removeAllChildren();
		for (let i=0; i<this.dotArr.length; i++) {
			this.dotArr[i].parent = this.sample;
		}


		// const isRightArea = this.checkIsRightArea(data);
		// if (!isRightArea) {
		// 	// playAudio(this.audioTipArea.clip)
		// 	this.log('没有检测到此题的区域')
		// 	return;
		// }



		// this.log('检测到区域')

		

		// const answerData = this.getAnswerData(data);
		const answerData = this.getAnswerDataNew(data);



		this.showUserRight(answerData);


		const isFillAll = this.checkIsFillAll(answerData);
		if (!isFillAll) {

			// playAudio(this.audioTipFillWrong.clip)
			// console.log('这道题还有空没填哦')
			return;
		}

		// const isFillWrong = this.checkIsFillWrong(answerData);
		// if (!isFillWrong) {
		// 	playAudio(this.audioTipFillWrong.clip)

		// 	console.log('这道题有空填错了哦')
		// 	return;
		// }

		this.showPhotoSuccess();

		
	},

	showUserRight(answerData) {


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

		if (Object.keys(answerData).length == 0) {
			return;
		}


		const letterArr = this.data.letterArr//questionData.letter_arr;
		
		for (let i=0; i<letterArr.length; i++) {
			const key = i.toString();
			const letterData = letterArr[i];

			if (answerData[key]?.isFinishLetter || answerData[key]?.isWrongLetter) {

				if (letterData.is_right && answerData[key].isFinishLetter) {
					this.showLetter(i, null, true);
				} else if (!letterData.is_right  && answerData[key].isWrongLetter) {
					this.showLetter(i, null, true);
				}

			} else {

				const item = this.letterItemArr[i];
				item.hitCount = 0;

			}
		}
	},

	checkIsFillAll(answerData) {

		const letterArr = this.data.letterArr// questionData.letter_arr;
		for (let i=0; i<letterArr.length; i++) {
			const key = i.toString();
			const letterData = letterArr[i];

			const item = this.letterItemArr[i];
			if (!item.isShow) {
				console.log("第" + (i+1) + "题 不对")
				return false;

				// if (letterData.is_right && !answerData[key]) {
				// 	console.log("没有看到第" + (i+1) + "个空的答案哦")
				// 	return false;
				// }
			}


		
		}

		return true;

	},


	checkIsFillWrong(answerData) {

		const letterArr = this.data.letterArr // questionData.letter_arr;
		for (let i=0; i<letterArr.length; i++) {
			const key = i.toString();
			const letterData = letterArr[i];

			const item = this.letterItemArr[i];
			if (!item.isShow) {
				if (!letterData.is_right && answerData[key]) {
					console.log("第" + (i+1) + "个空填错了哦")
					return false;
				}
			}
		

		}

		return true;

	},

	getTopLeftLetter(text, block, topLabelData) {

		const titleLocation = topLabelData.word[0].location
		// const checkX = titleLocation.left + (titleLocation.right - titleLocation.left) / 3;

		const unit = titleLocation.bottom - titleLocation.top;


		// 12

		const checkY1 = -titleLocation.bottom;

		console.log('')

		const checkY2 = -titleLocation.bottom - ( unit * 4.08 );

		const checkX = titleLocation.right + ( unit * 8.33 );

		

		text = text.trim();

		let topLeftLetter;

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

		for(let j=0; j<block.length; j++) {

			const line = block[j].line;
			if (!line) {
				continue;
			}

			for (let i=0; i<line.length; i++) {

				const {word} = line[i];
				const location = word[0].location;
			
				let sentence = ''
				word.forEach(item => {
					sentence += item.content + ' ';
				});
	
				sentence.trim();
	
				line[i].sentence = sentence;
				console.log('sentence: ', sentence);
				if (sentence.indexOf(text) != -1 && sentence.length <= 4) {


					if (-location.top >= checkY1 || -location.top <= checkY2) {
						continue;
					}

					if (location.left >= checkX) {
						continue;
					}

					if (location.top == titleLocation.top) {
						continue;
					}

					line[i].tmpLen = this.getToZeroLen(location)
					if (!topLeftLetter) {
						topLeftLetter = line[i];
					} else {
						if (topLeftLetter.tmpLen > line[i].tmpLen) {
							topLeftLetter = line[i];
						}
					}
				}
			}
		}

		return topLeftLetter;
	},

	getToZeroLen(location) {
		const {top, left} = location;
		const len = Math.sqrt( Math.pow(left, 2) + Math.pow(top, 2) );
		return len;
	},



	getPhotoLabelData(textArr, block) {

		for(let j=0; j<block.length; j++) {

			const line = block[j].line;
			if (!line) {
				continue;
			}

			for (let i=0; i<line.length; i++) {

				const word = line[i].word;
				let sentence = ''
				word.forEach(item => {
					sentence += item.content + ' ';
				});
	
				sentence.trim();
				sentence = sentence.toLowerCase();
	
				line[i].sentence = sentence;

				if (this.checkIsInsert(textArr, sentence)) {
					return line[i];
				}
			}
		}

		return false;
	},

	checkIsInsert(textArr, sentence) {
		console.log('textArr: ', textArr);
		console.log('sentence: ', sentence);

		let index = -1;
		for (let i=0; i<textArr.length; i++) {
			index = sentence.indexOf(textArr[i], index);
			console.log('index: ', index);
			if (index == -1) {
				return false;
			}
		}

		return true;
	},

	getPhotoLabelData_(text, block) {

		text = text.trim();

		for(let j=0; j<block.length; j++) {

			const line = block[j].line;
			if (!line) {
				continue;
			}

			for (let i=0; i<line.length; i++) {

				const {word} = line[i];
				let sentence = ''
				word.forEach(item => {
					sentence += item.content + ' ';
				});
	
				sentence.trim();
	
				line[i].sentence = sentence;
				if (sentence.indexOf(text) != -1 ) {
					return line[i];
				}
			}
		}

		return false;
	},

	getPhotoWordArr(text, data, topLabelData) {

		const result = data.result;


		// const titleLocation = topLabelData.word[0].location;

		const wordArr = [];
		// const maxLen = 6;

		// text = text.trim()[0];


		for (let i=0; i<result.length; i++) {


			const wordData = result[i];
			if (-wordData.top >= -topLabelData.top) {
				continue;
			}

			if (wordData.classIdentifier == text) {
				wordArr.push(wordData)
			}
			
		}

		return wordArr;
	},

	checkCutWordData(wordArr) {


		console.log('wordArr: ', wordArr);

		let newWordArr = [];
		for(let i=0; i<wordArr.length; i++) {

			let wordObj = wordArr[i];

			wordObj.content = wordObj.content.trim();

			if (wordObj.content.length > 1) {

				const tmpArr = [];
				const w = wordObj.location.right - wordObj.location.left
				const subW = w / wordObj.content.length;
				for (let j=0; j<wordObj.content.length; j++) {

					const subWordObj = {};
					subWordObj.content = wordObj.content[j];
					subWordObj.location = {
						top: wordObj.location.top,
						bottom: wordObj.location.bottom,
						left: wordObj.location.left + subW * j,
						right: wordObj.location.left + subW * (j + 1)
					}

					tmpArr.push(subWordObj);
				}
				newWordArr = newWordArr.concat(tmpArr)


			} else {
				newWordArr.push(wordObj)
			}

		}

		console.log('newWordArr: ', newWordArr);
		return newWordArr;
	},


	checkIsRightArea(data) {

		return//
		let letter = questionData.letter || 'Aa';
		let checkLetter;
		if (letter == "Aa") {
			checkLetter = 'A2'
		} 

		const topTitleData = this.getIdentifierArr(data, 'originD')[0];
		if (!topTitleData) {
			return false;
		}
		const topLeftLetterData = this.getTopLeftLetterData(data, checkLetter, topTitleData);
		
		this.topTitleData = topTitleData;
		// this.bottomTitleData = bottomTitleData;
		this.topLeftLetterData = topLeftLetterData;
		
		console.log('topTitleData:', topTitleData);
		// console.log('bottomTitleData:', bottomTitleData);
		console.log('topLeftLetterData:', topLeftLetterData);

		return topTitleData && topLeftLetterData;




		// const block = data?.block
		// if (!block) {
		// 	return false;
		// }

		// const letter = this.data.letter || 'Aa';

		// const topLabelData = this.getPhotoLabelData(['or', 'cross', 't', 'out'], block);
		// if (!topLabelData) {
		// 	console.log('!topLabelData')
		// 	return false;
		// }
		// this.topLabelData = topLabelData;


		// let topLeftLetter = this.getTopLeftLetter(letter, block, topLabelData);
		// this.topLeftLetter = topLeftLetter;


		// console.log('topLabelData: ', topLabelData);
		// console.log('topLeftLetter: ', topLeftLetter);

		// return topLeftLetter;
	},


	getTopLeftLetterData(result, identifier, topTitleData) {
		
		const identifierArr = this.getIdentifierArr(result, identifier);

		identifierArr.forEach(item => {
			const len = Math.sqrt( Math.pow(item.left, 2) + Math.pow(item.top, 2) );
			item.minLen = len;
		})

		identifierArr.sort((a, b) => {
			return a.minLen - b.minLen
		})

		const topLeftLetter = identifierArr[0];
		if (!topLeftLetter) {
			return;
		}
		
		const unit = topTitleData.bottom - topTitleData.top;
		const targetY = -topTitleData.bottom - unit * 1.5;
		const targetX = topTitleData.left + (topTitleData.right - topTitleData.left) / 2;

		if (-topLeftLetter.top < targetY) {
			this.log(' < targetY')
			this.log(' titleY: ' + -topTitleData.bottom);
			this.log(' unit: ' + unit);
			this.log(' letter y: ' + -topLeftLetter.bottom)
			this.log(' targetY : ' + targetY)
			return;
		}
		if ( topLeftLetter.left > targetX) {
			this.log(' > targetX')

			return;
		}


		return topLeftLetter
	},

	getIdentifierArr(data, identifier) {

		const result = data.result;

		const identifierArr = [];
		for (let i=0; i<result.length; i++) {

			const data = result[i];
			const {classIdentifier} = data;

			if (classIdentifier == identifier) {
				identifierArr.push(data)
			}
		}
		return identifierArr;
	},


	getAnswerDataNew(data) {
		const dotArr = this.dotArr;

		const letterBig = this.data.letter.toUpperCase();
		const letterSmall = this.data.letter.toLowerCase();


		const answerData = {};

		const resultTextArr = data.result.text;
		for (let i=0; i<resultTextArr.length; i++) {

			const wordData = resultTextArr[i];

			if (wordData.content != 'X' && wordData.content != letterBig && wordData.content != letterSmall) {				
				continue;
			}

			let color = 'red';
			if (wordData.content == 'X') {
				color = 'yellow'
			}

			const colorRect =	this.getColorRectByPos(wordData.bbox, color)
			colorRect.data = wordData;
			// colorRect.opacity = 100;
			this.sample.addChild(colorRect);

		

			this.setOneAnswerDataNew(colorRect, dotArr, answerData);

			// if (wordData.classIdentifier == 'fork') {
			// 	colorRect.isWrongLetter = true;
			// }
	
		}

		return answerData;
	},

	setOneAnswerDataNew(colorRect, dotArr, answerData) {

		console.log(' in setOneAnswerDataNew')
		const rect = colorRect.ccRect;
		const x = rect.x + rect.width / 2;
		const y = rect.y +rect.height / 2;
		const checkPoint = cc.v2(x, y);

		const checkDot = this.getColorDot(x, y, 5);

		console.log(' checkPoint:' , checkPoint)


		this.sample.addChild(checkDot);


		for (let i=0; i<dotArr.length; i++) {



			const dotRect = dotArr[i];
			const checkRect = dotRect.ccRect;


			// this.sample.addChild(checkDot);

			if (checkRect.contains(checkPoint)) {

				console.log(' in Rect')


				const key = i.toString()
				if (!answerData[key]) {
					answerData[key] = {arr: []};
				}

				answerData[key].arr.push(colorRect);

				this.checkOneAnswerIsRight(answerData[key]);
				return;

			} else {

				console.log(' checkRect.x:' , checkRect.x)
				console.log(' checkRect.y:' , checkRect.y)
				console.log(' checkRect.width:' , checkRect.width)
				console.log(' checkRect.height:' , checkRect.height)

			}

			// // const {pos} = dotArr[i];
			// // if (rect.contains(pos)) {
			// if (rect.intersects(dotRect)) {
			// 	answerData[i.toString()] = colorRect;
			// 	return;
			// }

		}

	},

	checkOneAnswerIsRight(answer) {

		const letterBig = this.data.letter.toUpperCase();
		const letterSmall = this.data.letter.toLowerCase();

		const arr = answer.arr;
		let isHasBig = false;
		let isHasSmall = false;
		let isHasWrong = false;
		for (let i=0; i<arr.length; i++) {
			if (arr[i].data.content == letterSmall) {
				isHasSmall = true;
			} else if (arr[i].data.content == letterBig) {
				isHasBig = true;
			} else if (arr[i].data.content == 'X') {
				isHasWrong = true;
			}
		}

		if (isHasBig && isHasSmall) {
			answer.isFinishLetter = true;
		}
		if (isHasWrong) {
			answer.isWrongLetter = true;
		}
	},

	getAnswerData(data) {

		return;
		const letter = questionData.letter || 'Aa';
		let checkLetter;
		if (letter == "Aa") {
			checkLetter = 'A2'
		}


		const topTitleData = this.topTitleData;
		// const bottomTitleData = this.bottomTitleData;
		const topLeftLetterData = this.topLeftLetterData;
		
		const wordDataArr = this.getPhotoWordArr(checkLetter, data, topTitleData);


		const dotArr = this.setTestRectDot(topTitleData, topLeftLetterData, wordDataArr);


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

		const answerData = {};

		
		for (let i=0; i<data.result.length; i++) {

			const wordData = data.result[i];

			if (wordData.classIdentifier != 'fork' && wordData.classIdentifier != checkLetter) {				
				continue;
			}

			const rect = {
				x: wordData.left, 
				y: -wordData.top,
				width: Math.abs( wordData.left - wordData.right ), 
				height: Math.abs( wordData.top - wordData.bottom ), 
			}


			let color = null;
			if (wordData.classIdentifier == 'fork') {
				color = cc.Color.YELLOW
				color = 'yellow'
			}
			const colorRect = this.getColorRect(rect, color);
			this.debugLayer.addChild(colorRect);

			this.setOneAnswerData(colorRect, dotArr, answerData);

			if (wordData.classIdentifier == 'fork') {
				colorRect.isWrongLetter = true;
			}
	
		}

	



		const rectTop = {
			x: topTitleData.left, 
			y: -topTitleData.top,
			width: Math.abs( topTitleData.left - topTitleData.right ), 
			height: Math.abs( topTitleData.top - topTitleData.bottom ), 
		}

	
		const colorRect = this.getColorRect(rectTop, 'green');
		this.debugLayer.addChild(colorRect);

		return answerData;



	},

	setTestLabel(labelData) {
	
		if (!this.debugLayer.parent || !this.debugLayer.active) {
			return;
		}

		console.log('labelData: ', labelData)
		const location = labelData.word[0].location;
		const label = this.getLabel(labelData.sentence);
		label.anchorX = 0;
		// label.anchorY = 1;
		label.x = location.left;
		label.y = -location.top
		label.zIndex = 50;

	
		this.debugLayer.addChild(label);
	},

	setTestRectDot(topLabelData, topLeftLetter, wordDataArr) {

	
		// const letterLocation = topLeftLetter.word[0].location;
		// const titleLocation = topLabelData.word[0].location;
		const unitH = topLeftLetter.bottom - topLabelData.bottom;
		console.log('unitH: ', unitH)


		//49


	
		// const topLeftPos = topLeftLetter.location.top_left;

		
		const rectH = 0.469 * unitH//23   

		const rectW = 0.48 * unitH//41

		// const disW = 1.65 * unitH //101
		const disW = 1.13 * unitH //101

		const disH = 1.1 * unitH //49


		


		const baseX = topLeftLetter.right - rectW / 2;
		let baseY = -(topLeftLetter.top - rectH / 2 );
		// const baseX = 2.898 * unitH  // 142
		// let baseY = -( 5.612 * unitH ); // -275


		
		console.log('baseX: ', baseX);
		console.log('baseY: ', baseY);

		// wordDataArr.forEach(item => {
		// 	const pos = item.location.top_left;

		// 	item.cLen = Math.sqrt ( Math.pow(pos.x, 2) + Math.pow(pos.y, 2) );
		// })


		wordDataArr.forEach(item => {
			// const pos = item.location.top_left;
			const posX = item.left;
			const posY = item.top;
			item.cLen = Math.sqrt ( Math.pow(posX, 2) + Math.pow(posY, 2) );
		})

		wordDataArr = wordDataArr.sort((a, b) => {
			return a.cLen - b.cLen;
		})


		let col = 0;

		const dotArr = [];
		for (let i=0; i<6; i++) {
			const x = baseX + col * disW;
			const y = baseY;
			const dot = this.getColorDot(x, y, rectH);
			this.debugLayer.addChild(dot,5);
			dotArr.push(dot);
			col ++;

			if (i == 2) {
				baseY -= disH;
				col = 0;
			}
		}

		return dotArr;

	},

	setOneAnswerData(colorRect, dotArr, answerData) {

		// console.log(' in setOneAnswerData')
		// console.log('colorRect: ', colorRect)
		// console.log('dotArr: ', dotArr)
		// console.log('answerData: ', answerData)

		
		const rect = colorRect.ccRect;

		for (let i=0; i<dotArr.length; i++) {

			const {dotRect} = dotArr[i];
			// const {pos} = dotArr[i];
			// if (rect.contains(pos)) {
			if (rect.intersects(dotRect)) {
				answerData[i.toString()] = colorRect;
				return;
			}

		}

	},

	getLabel(text) {
		const labelNode = new cc.Node();
		const label = labelNode.addComponent(cc.Label);
		label.string = text;
		labelNode.color = cc.Color.BLACK;
		return labelNode;
	},

	getColorRect(rect, color=null) {

		if (!color) {
			color = 'red'
		}
		// const node = new cc.Node();
		// const colorRect = node.addComponent(cc.Graphics);
		// colorRect.fillColor = color;
		// node.opacity = 0.5;
		// colorRect.fillRect(rect.x, rect.y, rect.width, rect.height);

		// node.ccRect = new cc.Rect(rect.x, rect.y, rect.width, rect.height);

		const node = this.getSprNode(color);
		node.anchorX = 0;
		node.anchorY = 0;
		node.x = rect.x;
		node.y = rect.y;
		node.scaleX = rect.width / node.width;
		node.scaleY = rect.height / node.height;

		node.ccRect = new cc.Rect(rect.x, rect.y, rect.width, rect.height);



		return node;
	},

	getColorDot(x, y, r=100) {
		const node = new cc.Node();

		if (this.debugLayer.parent && this.debugLayer.active) {
			// const colorDot = node.addComponent(cc.Graphics);
			// colorDot.fillColor = cc.Color.BLUE;
			// colorDot.fillRect( - r/2, - r/ 2, r, r);

			const rect = {
				x:- r/2,
				y: - r/ 2, 
				width:r, 
				height:r
			}
			// const colorDot = this.getColorRect(rect,'blue');
			// colorDot.fillColor = cc.Color.BLUE;
			// colorDot.fillRect( - r/2, - r/ 2, r, r);

			const colorDot = this.getSprNode('blue');

			
			colorDot.anchorX = 0;
			colorDot.anchorY = 0;
			colorDot.x = rect.x;
			colorDot.y = rect.y;
			colorDot.scaleX = rect.width / colorDot.width;
			colorDot.scaleY = rect.height / colorDot.height;
			node.addChild(colorDot);



			// const rect1 = new cc.Rect(node.x -r/2, node.y -r/2, r, r);
			// const colorDot = this.getColorRect(rect1, 'green');

			// colorDot.dotRect = rect1;
			// return colorDot;
		}

		node.x = x;
		node.y = y;


		// node.opacity = 0.5;

		const rect = new cc.Rect(node.x -r/2, node.y -r/2, r, r);
		node.dotRect = rect;
		return node;
	},

	getColorRectByPos(posArr, color='red') {
		const topLeft = posArr[0];
		const bottomRight = posArr[2];

		const sample = this.sample;
		const x = topLeft.x1 * sample.width;
		const y = topLeft.y1 * sample.height;
		const width = (bottomRight.x3 - topLeft.x1) * sample.width;
		const height = (bottomRight.y3 - topLeft.y1) * sample.height;
		const rect = {x, y: -y - height, width, height};

		// console.log('rect ', rect);
		const colorRect = this.getColorRect(rect, color);
		colorRect.opacity = 100;
		return colorRect;
	},

	checkIsRightLetter(result) {
		const block = result?.data?.block
		if (!block) {
			return false;
		}
		return false;

		const letter = this.data.letter;
		const letterLabelData = this.getPhotoLabelData(letter, block);

		return letterLabelData;
	},

	checkIsRightPos(result) {
		const block = result?.data?.block
		if (!block) {
			return false;
		}

		return false;

		const iconLabelData = this.getPhotoLabelData('I like', block);
		const topLabelData = this.getPhotoLabelData('n and repeat', block);
		const bottomLabelData = this.getPhotoLabelData('n, point, and repeat', block);	
		if (!iconLabelData) {
			return false;
		}	

		const topY = topLabelData.location.top_left.y;
		const bottomY = bottomLabelData.location.top_left.y;
		const iconY = iconLabelData.location.top_left.y;
		if (bottomY <= iconY <= topY) {
			return true;
		}
	},

	showPhotoSuccess() {

		if (this.isSuccess) {
			return;
		}
		this.isSuccess = true;
		console.log(' in showPhotoSuccess')


		this.startFinishAnim();


		// playAudio(this.audioTipSuccess.clip)

		this.endTesting();
	},

	startFinishAnim() {

		if (!this.data.skeJsonData.url) {
			playAudioByUrl(this.data.end_audio_url, () => {

			})
			return;
		}

		getDragonboneByUrl(this.data.skeJsonData.url, this.data.texJsonData.url, this.data.texPngData.url, (dragonDisplay, animationNames) => {


			dragonDisplay.node.parent = this.canvas;
			dragonDisplay.playAnimation(animationNames[0], -1);

			console.log('animationNames: ', animationNames);
			this.finishAnim = dragonDisplay;

			const node = dragonDisplay.node;
			node.scale = 0;
			cc.tween(node)
				.to(1, {scale: this._mapScaleMin}, {easing: 'elasticOut'})
				.start();

			playAudioByUrl(this.data.end_audio_url, () => {
				
				if (this.isDestroy) {
					return;
				}
				
				this.endFinishAnim();
			})

		})
	},

	endFinishAnim() {
		const node = this.finishAnim.node;
		cc.tween(node)
			.to(0.5, {scale: 0}, {easing: 'cubicIn'})
			.call(() => {
				node.removeFromParent();
			})
			.start();
				
	},

	getPhotoData(cb) {

		const tmpData = {
			"code": 200000,
			"message": "success",
			"result": {
				"support_results": [
					[
						[
							0.26840803027153015,
							0.4454603778870769,
							0.3243527412414551,
							0.48535126868125317,
							"a",
							0.9710705876350403
						]
					],
					[
						[
							0.19613343477249146,
							0.5451562444204117,
							0.26026153564453125,
							0.6087154718850163,
							"A",
							0.9686374664306641
						]
					],
					[
						[
							0.6904760599136353,
							0.5627689965038378,
							0.7658419013023376,
							0.6231959133227336,
							"A",
							0.9588420391082764
						]
					],
					[
						[
							0.4453604519367218,
							0.5698346943281498,
							0.5403351783752441,
							0.6409365557041405,
							"/",
							0.9264321327209473
						]
					],
					[
						[
							0.24796423316001892,
							0.568715858261615,
							0.2894899845123291,
							0.6091811053485792,
							"a",
							0.9243924021720886
						]
					],
					[
						[
							0.21002043783664703,
							0.4221963078649212,
							0.26747649908065796,
							0.4850075650511936,
							"A",
							0.9232078194618225
						]
					],
					[
						[
							0.7336646914482117,
							0.5669091450228235,
							0.7900009155273438,
							0.6198147718342508,
							"a",
							0.8932965397834778
						]
					],
					[
						[
							0.7268149852752686,
							0.44534171270631656,
							0.7758703827857971,
							0.48654577296799145,
							"a",
							0.8362609148025513
						]
					],
					[
						[
							0.430702805519104,
							0.4165675209765612,
							0.5934100151062012,
							0.49322344702803744,
							"/",
							0.7828908562660217
						]
					],
					[
						[
							0.6833227276802063,
							0.42481147402055036,
							0.7369502782821655,
							0.4845800192029644,
							"A",
							0.6591488718986511
						]
					]
				],
				"text": [
					{
						"bbox": [
							{
								"x1": 0.26840803027153015,
								"y1": 0.4454603778870769
							},
							{
								"x2": 0.3243527412414551,
								"y2": 0.4454603778870769
							},
							{
								"x3": 0.3243527412414551,
								"y3": 0.48535126868125317
							},
							{
								"x4": 0.26840803027153015,
								"y4": 0.48535126868125317
							}
						],
						"content": "a",
						"score": 0.9710705876350403
					},
					{
						"bbox": [
							{
								"x1": 0.19613343477249146,
								"y1": 0.5451562444204117
							},
							{
								"x2": 0.26026153564453125,
								"y2": 0.5451562444204117
							},
							{
								"x3": 0.26026153564453125,
								"y3": 0.6087154718850163
							},
							{
								"x4": 0.19613343477249146,
								"y4": 0.6087154718850163
							}
						],
						"content": "A",
						"score": 0.9686374664306641
					},
					{
						"bbox": [
							{
								"x1": 0.6904760599136353,
								"y1": 0.5627689965038378
							},
							{
								"x2": 0.7658419013023376,
								"y2": 0.5627689965038378
							},
							{
								"x3": 0.7658419013023376,
								"y3": 0.6231959133227336
							},
							{
								"x4": 0.6904760599136353,
								"y4": 0.6231959133227336
							}
						],
						"content": "A",
						"score": 0.9588420391082764
					},
					{
						"bbox": [
							{
								"x1": 0.4453604519367218,
								"y1": 0.5698346943281498
							},
							{
								"x2": 0.5403351783752441,
								"y2": 0.5698346943281498
							},
							{
								"x3": 0.5403351783752441,
								"y3": 0.6409365557041405
							},
							{
								"x4": 0.4453604519367218,
								"y4": 0.6409365557041405
							}
						],
						"content": "/",
						"score": 0.9264321327209473
					},
					{
						"bbox": [
							{
								"x1": 0.24796423316001892,
								"y1": 0.568715858261615
							},
							{
								"x2": 0.2894899845123291,
								"y2": 0.568715858261615
							},
							{
								"x3": 0.2894899845123291,
								"y3": 0.6091811053485792
							},
							{
								"x4": 0.24796423316001892,
								"y4": 0.6091811053485792
							}
						],
						"content": "a",
						"score": 0.9243924021720886
					},
					{
						"bbox": [
							{
								"x1": 0.21002043783664703,
								"y1": 0.4221963078649212
							},
							{
								"x2": 0.26747649908065796,
								"y2": 0.4221963078649212
							},
							{
								"x3": 0.26747649908065796,
								"y3": 0.4850075650511936
							},
							{
								"x4": 0.21002043783664703,
								"y4": 0.4850075650511936
							}
						],
						"content": "A",
						"score": 0.9232078194618225
					},
					{
						"bbox": [
							{
								"x1": 0.7336646914482117,
								"y1": 0.5669091450228235
							},
							{
								"x2": 0.7900009155273438,
								"y2": 0.5669091450228235
							},
							{
								"x3": 0.7900009155273438,
								"y3": 0.6198147718342508
							},
							{
								"x4": 0.7336646914482117,
								"y4": 0.6198147718342508
							}
						],
						"content": "a",
						"score": 0.8932965397834778
					},
					{
						"bbox": [
							{
								"x1": 0.7268149852752686,
								"y1": 0.44534171270631656
							},
							{
								"x2": 0.7758703827857971,
								"y2": 0.44534171270631656
							},
							{
								"x3": 0.7758703827857971,
								"y3": 0.48654577296799145
							},
							{
								"x4": 0.7268149852752686,
								"y4": 0.48654577296799145
							}
						],
						"content": "a",
						"score": 0.8362609148025513
					},
					{
						"bbox": [
							{
								"x1": 0.430702805519104,
								"y1": 0.4165675209765612
							},
							{
								"x2": 0.5934100151062012,
								"y2": 0.4165675209765612
							},
							{
								"x3": 0.5934100151062012,
								"y3": 0.49322344702803744
							},
							{
								"x4": 0.430702805519104,
								"y4": 0.49322344702803744
							}
						],
						"content": "/",
						"score": 0.7828908562660217
					},
					{
						"bbox": [
							{
								"x1": 0.6833227276802063,
								"y1": 0.42481147402055036
							},
							{
								"x2": 0.7369502782821655,
								"y2": 0.42481147402055036
							},
							{
								"x3": 0.7369502782821655,
								"y3": 0.4845800192029644
							},
							{
								"x4": 0.6833227276802063,
								"y4": 0.4845800192029644
							}
						],
						"content": "A",
						"score": 0.6591488718986511
					}
				]
			}
		}

		cb(tmpData);
	},


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


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

	getSprNodeByUrl(url, cb) {
		const node = new cc.Node();
		const spr = node.addComponent(cc.Sprite);
		this.getSpriteFrimeByUrl(url, (sf) => {
			spr.spriteFrame = sf;
			if (cb) {
				cb(node);
			}
		})
	},

	_audioId: null,
	playAudioByUrl(audio_url, cb = null, loadcb=null, loop = false) {

		if (this._audioId) {
			cc.audioEngine.pause(this._audioId);
		}

		let audioId;

		if (audio_url) {
			cc.assetManager.loadRemote(audio_url, (err, audioClip) => {
				
				audioId = cc.audioEngine.play(audioClip, loop, 0.8);
				this._audioId = audioId;
				
				if (cb) {
					cc.audioEngine.setFinishCallback(audioId, () => {
						cb();
					});
				}

				if(loadcb){
					loadcb(audioId);
				}

			});
		}
	},

	onDestroy() {
		console.log(' in onDestroy OP_08')

		
		this.isDestroy = true;
		clearInterval(this.timer_1);
		clearInterval(this.timer_2);

	}
	// ------------------------------------------

});
