import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener, ApplicationRef } from '@angular/core';

import {
  MySprite,
  Label,
  moveItem,
  rotateItem,
  removeItemFromArr,
  ShapeRect, scaleItem, tweenChange, showPopParticle, hideItem, showItem, LineRect, shake, RichText, ShapeRectNew, showShapeParticle, delayCall, randomSortByArr, MyVideo, getMinScale, ShapeCircle, formatTime, ScrollView,

} from './Unit';
import { res, resAudio } from './resources';

import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

import * as _ from 'lodash';
import TWEEN from '@tweenjs/tween.js';

import { loadFonts } from './Util'
import { faTshirt } from '@fortawesome/free-solid-svg-icons';
import { DomSanitizer } from '@angular/platform-browser';





@Component({
  selector: 'app-play',
  templateUrl: './play.component.html',
  styleUrls: ['./play.component.css']
})
export class PlayComponent implements OnInit, OnDestroy {
  // 数据
  _data;

  @Input()
  set data(data) {
    this._data = data;
  }
  get data() {
    return this._data;
  }

  @Input()
  sid;

  @ViewChild('canvas', { static: true }) canvas: ElementRef;
  @ViewChild('wrap', { static: true }) wrap: ElementRef;
  @ViewChild('video') set content(content: ElementRef) {
    if (content) {
      this.initVideo(content);
    }
  }

  @ViewChild('iframeContent', {static: true }) iframeContent: ElementRef;
  

  canvasScale = 2;

  canvasWidth = 2388;
  canvasHeight = 1688;

  canvasBaseW = 2388;
  canvasBaseH = 1688;


  ctx;
  fps = 0;
  frametime = 0;  // 上一帧动画的时间，   两帧时间差


  mx;
  my; // 点击坐标



  // 资源
  rawImages = new Map(res);
  rawAudios = new Map(resAudio);

  images = new Map();

  animationId: any;
  winResizeEventStream = new Subject();


  audioObj = {};
  renderArr;
  mapScale = 1;
  mapScaleMax = 1;

  canvasLeft;
  canvasTop;


  canTouch = true;


  KEY = 'JM_6';

  // -----
  picArr;
  titleLabel;
  light;
  particleLayer;
  shadowArr;
  answerTarget;
  answerCurrent;
  bgRect;
  starBgArr;
  clickedSuccessArr;


  pageLabel;
  leftBtn;
  rightBtn;
  bgLayer;
  curPageIndex;

  hotZoneArr;

  picIndex = 0;


  bgArr;
  endPageArr;
  gameEndFlag;
  showPetalFlag;
  bg;
  topArr;



  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.winResizeEventStream.next();

  }


  constructor(private sanitizer: DomSanitizer, private appRef: ApplicationRef) {

  }

  isTeacher = false;

  async ngOnInit() {

    // new VConsole();



    await loadFonts('DroidSansFallback', 'DroidSansFallback.ttf');
    await loadFonts('Aileron-Black', 'Aileron-Black.ttf');
    await loadFonts('Aileron-Bold', 'Aileron-Bold.ttf');

    const getData = (<any>window).courseware.getData;
    getData((data, aspect) => {


      if (window['air']?.airClassInfo?.user?.classRole == 'tea') {
        this.isTeacher = true;
      }
			if (aspect) {
        console.log('aspect : ', aspect);
				this.initPageData(aspect);
      }

      if (data && typeof data == 'object') {
        this.data = { contentObj: data };
      } else {

        this.initDefaultData();
      }

      console.log('data:', data);
      if (!this.data) {
        this.data.contentObj = {};
      }




      this.initAudio();
      this.initImg();
      this.initListener();

    }, this.KEY);


  }


	// 用于存储公共数据 当翻页时清空 
	pageData;
	initPageData(aspect) {
		const pageDataStr = aspect?.page_aspect?.pagedata;
		if (!pageDataStr) {
			this.pageData = {};
		} else {
			this.pageData = JSON.parse(pageDataStr);
		}
		console.log('this.pageData: ', this.pageData);
	}

	setPageData(key, value, isSend=true) {

		if (this.pageData) {

			console.log('this.pageData: ', this.pageData);
			this.pageData[key] = value;
			if (isSend) {
				this.sendPageData();
			}
		}
	}

	getPageData(key) {
		if (this.pageData && this.pageData[key] != null) {
			return this.pageData[key];
		}
	}

	sendPageData() {

		const data = this.pageData;

		if (window && window['courseware']) {
			let storePageAspect = window['courseware'].storePageAspect;
			if (storePageAspect) {
				storePageAspect(data);
			}
		}
	}



  initDefaultData() {

    const data = {"lrcData":{"video_url":"http://staging-teach.cdn.ireadabc.com/2ef06de470293f307b60513e1275b27a.mp4","lyrics":[{"time":0.368544,"data":"Almost three quarters of the Earth is water.","newLine":false},{"time":3.131326000000002,"data":"Many fish and sea animals live in the streams.","newLine":false},{"time":6.292489,"data":"rivers,","newLine":false},{"time":7.3854190000000015,"data":"lakes,","newLine":false},{"time":8.297289999999993,"data":"seas and oceans on the Earth.","newLine":true},{"time":10.855582999999994,"data":"Whales, dolphins and sharks are sea animals.","newLine":false},{"time":14.877477999999993,"data":"Dolphins are one of the most intelligent animals. ","newLine":false},{"time":18.005333999999994,"data":"Sharks are one of the most dangerous animals.","newLine":true},{"time":21.157874999999994,"data":"In the oceans,","newLine":false},{"time":22.43337299999999,"data":"you can find starfish and sea horses.","newLine":false},{"time":25.46556199999999,"data":"They are interesting and beautiful sea animals.","newLine":true},{"time":28.833978999999992,"data":"People also get food from the oceans.","newLine":false},{"time":31.535384999999998,"data":"The seafood we eat is from the oceans.","newLine":false},{"time":34.669667000000025,"data":"Fishermen use nets to catch fish and prawns in the deep sea.","newLine":true},{"time":39.18995600000002,"data":"The oceans are important to all animals on the Earth.","newLine":false},{"time":42.74353400000003,"data":"We must keep them clean.","newLine":false},{"time":44.54977700000004,"data":"We must stop polluting them.","newLine":false},{"time":47.10425000000003,"data":"","newLine":false}]},"title":"Please read the passage with the subtitle","bg_url":"http://staging-teach.cdn.ireadabc.com/1aaccbaa8f3a32df099f3308feac49e7.png"}
    this.data = { contentObj: data };
    

  }

  ngOnDestroy() {
    window['curCtx'] = null;
    window.cancelAnimationFrame(this.animationId);
    this.gameEndFlag = true;
  }

  sentenceArr = [];
  submitCount = 0;
  safeDefaultUrl;
  video_url = '';
  recordCount;
  isRecordEnd;
  recordResultArr;
  recordStartTime;
  initData() {
    

    this.canvasWidth = this.wrap.nativeElement.clientWidth * this.canvasScale;
    this.canvasHeight = this.wrap.nativeElement.clientHeight * this.canvasScale;

    this.canvas.nativeElement.width = this.wrap.nativeElement.clientWidth * this.canvasScale;
    this.canvas.nativeElement.height = this.wrap.nativeElement.clientHeight * this.canvasScale;


    const sx = this.canvasWidth / this.canvasBaseW;
    const sy = this.canvasHeight / this.canvasBaseH;
    const s = Math.min(sx, sy);
    this.mapScale = s;
    
    console.log('this.mapScale: ', this.mapScale);

    this.mapScaleMax = Math.max(sx, sy);

    // this.mapScale = this.canvasWidth / this.canvasBaseW;
    // this.mapScale = this.canvasHeight / this.canvasBaseH;
    this.renderArr = [];
    this.topArr = [];

    console.log(' in initData', this.data);




    this.recordStartTime = null;

    this.canTouch = true;

    this.recordCount = 0;
    this.isRecordEnd = false;
    this.recordResultArr = [];

    this.video_url = this.data.contentObj.lrcData.video_url;

    // this.submitCount = 0;
    // this.replaceSentenceText();

    // this.safeDefaultUrl = this.sanitizer.bypassSecurityTrustResourceUrl(''); 



  }

  replaceSentenceText() {
    const arr = this.data.contentObj.sentenceArr;
    if (!arr) {
      console.error('没有数据')
      return;
    }

    this.sentenceArr = JSON.parse(JSON.stringify(arr));
    for (let i=0; i<this.sentenceArr.length; i++) {
      const text = this.sentenceArr[i].text;
      this.sentenceArr[i].text = text.replace(/_/, "____________________")
    }
  }



  initAudio() {

    const contentObj = this.data.contentObj;
    if (!contentObj) { return; }



    // const addAudio = (key) => {
    //   const audioUrl = contentObj[key];
    //   if (audioUrl) {
    //     const audio = new Audio();
    //     audio.src = audioUrl;
    //     audio.load();
    //     this.audioObj[key] = audio;
    //   }
    // }
    //
    // for (let i = 0; i < 4; i ++) {
    //   const key = i + '_audio_url';
    //   addAudio(key);
    // }
    //
    // addAudio('audio_url');
    //


    const addUrlToAudioObj = (audioUrl) => {

      if (audioUrl) {

        // console.log('audioUrl:', audioUrl);
        const audio = new Audio();
        audio.src = audioUrl;
        audio.load();
        this.audioObj[audioUrl] = audio;
      }
    };


    // let arr = contentObj.picArr;

    // if (arr) {
    //   // console.log('arr: ', arr);
    //   for (let i = 0; i < arr.length; i++) {
    //     addUrlToAudioObj(arr[i].audio_url);
    //   }
    // }







    const audioObj = this.audioObj;
    const addOneAudio = (key, url, vlomue = 1, loop = false, callback = null) => {

      const audio = new Audio();
      audio.src = url;
      audio.load();
      audio.loop = loop;
      audio.volume = vlomue;

      audioObj[key] = audio;

      if (callback) {
        audio.onended = () => {
          callback();
        };
      }
    };


    addOneAudio('click', this.rawAudios.get('click'), 1);
    addOneAudio('more', this.rawAudios.get('more'), 0.8);
    addOneAudio('submit', this.rawAudios.get('submit'), 0.8);
  
    // addOneAudio('cow_start', this.rawAudios.get('cow_start'), 1);
    // addOneAudio('eat', this.rawAudios.get('eat'), 1);
    // addOneAudio('grass', this.rawAudios.get('grass'), 1);
    // addOneAudio('happy', this.rawAudios.get('happy'), 1);
    // addOneAudio('right', this.rawAudios.get('right'), 1);
    // addOneAudio('wrong', this.rawAudios.get('wrong'), 1);



    //
    // const titleUrl = this.data.contentObj.title_audio_url;
    // if (titleUrl) {
    //
    //   this.titleAudio.src = titleUrl;
    //   this.titleAudio.load();
    // }



    // this.bgAudio.src = 'assets/bat-mail/music/bg.mp3';
    // this.bgAudio.load();
    // this.bgAudio.loop = true;
    // this.bgAudio.volume = 0.5;
    //
    // this.wrongAudio.src = 'assets/common/music/wrong.mp3';
    // this.wrongAudio.load();
    //
    // this.rightAudio.src = 'assets/common/music/right.mp3';
    // this.rightAudio.load();
    //
    // this.successAudio.src = 'assets/magic-hat/music/finish.mp3';
    // this.successAudio.load();
    //
    // this.successAudio.onended = () => {
    //   // this.showSuccessAudio();
    // };


  }

  initImg() {

    const contentObj = this.data.contentObj;
    if (contentObj) {


      const addPicUrl = (url) => {
        if (url) {
          this.rawImages.set(url, url);
        }
      };



      addPicUrl(contentObj.bg_url);
    }


    // this.initFontImg();


    

    // 预加载资源
 


    this.loadResources().then(() => {
      // this.setfontData();

      this.loadEnd(_=>{});
      this.addServerListener();
      window['air'].hideAirClassLoading(this.KEY, this.data);


    });

  }

  loadEnd(cb) {
    this.init();
    this.update();

    cb()
  }

  addServerListener() {
    console.log(' in addServerListener');

		const c = window['courseware'];
		if (!c) {
			console.log(' window.courseware not exist !!!!!!!!')

			return;
		}

    const air = window['air']
		if (!air) {
			console.log(' window air err !!!!!!!!')
			return;
		}

		air.onCourseInScreen = (next) => {
			//各种逻辑
			// this.showTemplateStartAnima();
      console.log('in onCourseInScreen')
			this.loadEnd(() => {
				next();
			});
		}


		c.onEvent('game_start', (data, next) => {
			this.gameStart();
      if (next) {
        next();
      }
		});
  }


	sendServerEvent(key, data) {

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

  gameStart() {
    console.log(' in gameStart ');
    if (this.isTeacher) {
      this.sendBtn.visible = false;
      this.sendBtn.shadow.visible = false;

      this.maskPic.visible = true;
    } else {

      this.maskPic.visible = false;
    }
  }







  init() {

    this.initData();
    this.initCtx();

    this.initView();

    


  }

  initCtx() {

    this.ctx = this.canvas.nativeElement.getContext('2d');
    this.canvas.nativeElement.width = this.canvasWidth;
    this.canvas.nativeElement.height = this.canvasHeight;

    window['curCtx'] = this.ctx;


  }


  initView() {

    this.initBg();

    this.initVideo();

    this.initSpeedPanel();

    this.initBottomBtn();

    this.initMaskPic();
   

    this.relink();
    

    // this.gameStart();
    // this.submitBtnClick();

  }



  panel;

  initBg() {


    console.log('this.data: ', this.data);

    const bg = new MySprite();
    bg.init(this.images.get("bg"));

    bg.x = this.canvasWidth / 2;
    bg.y = this.canvasHeight / 2;
    const scaleX = this.canvasWidth / bg.width;
    const scaleY = this.canvasHeight / bg.height;
    bg.setScaleXY(Math.max(scaleX, scaleY));

    this.renderArr.push(bg);


    const label = new Label();
    label.fontSize = 76 * this.mapScale;
    label.fontName = 'Aileron-Bold';
    label.textAlign = 'left';
    label.setMaxSize(this.canvasWidth * 0.9);
    label.x = this.canvasWidth / 10;
    label.y = 110 * this.mapScale;
    label.fontColor = '#3e9b31';
    label.text = this.data.contentObj.title || '';
    this.titleLabel = label;
    this.renderArr.push(label);


  }

  curVideo;
  video;
  initVideo(videoContent=null) {


    if (this.video) {
      return;
    }
    
    if (videoContent) {
      this.video = videoContent;
    } else {
      if (!this.video) {
        return;
      }
      videoContent = this.video;
    }

  

    const videoMaxW = 1640 * this.mapScale;
    const videoMaxH = 960 * this.mapScale;
    const videoOffY = -150 * this.mapScale;

    const videoEdge = new MySprite();
    videoEdge.init(this.images.get("video_edge"));
    // videoEdge.setScaleXY(this.mapScale);
    videoEdge.x = this.canvasWidth / 2;
    videoEdge.y = this.canvasHeight / 2 + videoOffY;
    this.renderArr.push(videoEdge);


    const video = new MyVideo();
    // this.video_url = this.data.contentObj.lrcData.video_url;

    const initVideoAndBtn = () => {
      console.log('in initSize');
      video.initVideoElement(videoContent.nativeElement);
      video.setScaleXY(getMinScale(video, videoMaxW, videoMaxH));
      video.scaleX = videoMaxW / video.width;
      video.scaleY = videoMaxH / video.height;
      video.x = -video.width / 2 * video.scaleX + this.canvasWidth / 2;
      video.y = -video.height / 2 * video.scaleY + this.canvasHeight / 2 + videoOffY;
      
      videoEdge.scaleX = (video.width + 30) * video.scaleX / videoEdge.width;
      videoEdge.scaleY = (video.height + 30) * video.scaleY / videoEdge.height;

      // videoEdge.addChild(video);
      video.element.removeEventListener('canplaythrough', initVideoAndBtn);

      // video.element.playbackRate = 2;

      // video.element.onended = () => {

      //   video.element.currentTime = 0;
      //   this.recordBtn.isRecord = true;
      //   this.recordBtnClick();
      // }
      


      this.renderArr.push(video);
      this.curVideo = video;
      this.initTimeLine();
      this.speedLabelClick(2);

      video.element.currentTime = this.dotArr[0].data.time;
      // this.updateVideoStrip();
      // this.updateVideoTime();
    };

    // initVideoAndBtn();

    videoContent.nativeElement.src = this.video_url;
    videoContent.nativeElement.load();
    videoContent.nativeElement.addEventListener('canplaythrough', initVideoAndBtn);

 
  }

  speedLabelArr = [];
  initSpeedPanel() {

    this.speedLabelArr = [];

    const panel = new MySprite();
    panel.init(this.images.get("speed_panel"));
    panel.setScaleXY(this.mapScale);
    panel.x = this.canvasWidth / 2 + 1000 * this.mapScale;
    panel.y = this.canvasHeight / 2 - 150 * this.mapScale;

    let baseY = -panel.height / 2 + 10;
    const disH = 65;

    
    const setPanelLabel = (text, speed, isSpeed=true)=> {
      const label = new Label();
      label.text = text;
      label.fontName = 'DroidSansFallback'
      label.fontColor = '#b17d5a'
      label.textAlign = 'center'
      label.fontSize = 28;
      label.y = baseY + disH;
      panel.addChild(label);
      baseY += disH; 
      
      label['speed'] = speed;

      if (isSpeed) {
        this.speedLabelArr.push(label);

        label.refreshSize();

        const rect = new ShapeRectNew();
        rect.setSize(150, label.height * 2, 0);
        rect.x = -rect.width / 2;
        rect.alpha = 0;
        rect.y = -rect.height / 2;
        label.addChild(rect);
        label['touchRect'] = rect;
      }
      return label;
    }

    const title = setPanelLabel('倍速', 0, false);
    title.fontSize = 36;
    baseY += 20;

    setPanelLabel('0.5x', 0.5);
    setPanelLabel('0.75x', 0.72);
    setPanelLabel('1x', 1);
    setPanelLabel('1.25x', 1.25);
    setPanelLabel('1.5x', 1.5);

    this.renderArr.push(panel);

  }


  timeLine;
  pieceArr;
  dotArr;
  dotIndex;
  curDot;
  initTimeLine() {

    console.log(' in initTimeLine')

    const lineW = 1880 * this.mapScale;
    const lineH = 17 * this.mapScale;
    const duration = this.curVideo.element.duration;

    const lineBg = new ShapeRectNew();
    lineBg.setSize(lineW, lineH, 8 * this.mapScale);
    lineBg.fillColor = '#ebe0c0'
    lineBg.x = this.canvasWidth / 2 - lineBg.width / 2 * lineBg.scaleX;
    lineBg.y = this.canvasHeight / 2 + 450 * this.mapScale; 
    this.renderArr.push(lineBg);

    const timeLineStrip = new ShapeRectNew();
    timeLineStrip.setSize(lineBg.height, lineBg.height, 8 * this.mapScale);
    timeLineStrip.fillColor = '#358f2b';
    lineBg.addChild(timeLineStrip);

    const redStrip = new ShapeRectNew();
    redStrip.setSize(lineBg.height, lineBg.height, 8 * this.mapScale);
    redStrip.fillColor = '#961f44';
    lineBg.addChild(redStrip);

    const curTimeLabel = new Label();
    curTimeLabel.fontSize = 36;
    curTimeLabel.fontName = 'DroidSansFallback';
    curTimeLabel.textAlign = 'center';
    curTimeLabel.text = '00:00';
    curTimeLabel.x = -60;
    curTimeLabel.y = lineH / 2;
    curTimeLabel.fontColor = '#b17d5a';
    lineBg.addChild(curTimeLabel);


    const totalTimeLabel = new Label();
    totalTimeLabel.fontSize = 36;
    totalTimeLabel.fontName = 'DroidSansFallback';
    totalTimeLabel.textAlign = 'center';
    totalTimeLabel.text = formatTime('mm:ss', new Date(duration * 1000));
    totalTimeLabel.x = lineBg.width + 60;
    totalTimeLabel.y = lineH / 2;
    totalTimeLabel.fontColor = '#b17d5a';
    lineBg.addChild(totalTimeLabel);

    const lyrics = this.data.contentObj?.lrcData?.lyrics;
    if (!lyrics) {
      console.error(' wc 没打点');
      return;
    }
    
    const dotLine = 10;

    const addLineDot = (rate)=> {
      const dot = new ShapeCircle();
      dot.setRadius(dotLine / 2);
      lineBg.addChild(dot);
      dot.x = rate * lineBg.width;
      dot.y = lineH / 2;
      dot.setScaleXY(this.mapScale)
      dot.fillColor = '#007ba7'
      return dot;
    }


    const dotArr = [];
    for (let i=0; i<lyrics.length; i++) {
      const pieceData = lyrics[i];
      const rate = Math.round(pieceData.time / duration * 10000) / 10000;
      const dot = addLineDot(rate);
      dot['data'] = pieceData;
      dotArr.push(dot);
    }

    this.dotArr = dotArr;
    this.dotIndex = 1;
    this.curDot = dotArr[this.dotIndex];

    lineBg['curTimeLabel'] = curTimeLabel;
    lineBg['strip'] = timeLineStrip;
    lineBg['redStrip'] = redStrip;
    // lineBg['dotArr'] = dotArr;
    // lineBg['dotIndex'] = 0;

    this.timeLine = lineBg;
    
  }

  bottomY = 650;
  initBottomBtn() {

    if (this.isTeacher) {
      this.initSendBtn();
      return;
    }

    this.initRecordBtn();
    this.initSubmitBtn();
    this.initCancelBtn();
  }

  recordBtn;
  initRecordBtn() {

    const recordBtn = this.getMySprite('record_btn')
    this.recordBtn = recordBtn;

    recordBtn.x = this.canvasWidth / 2;
    recordBtn.y = this.canvasHeight / 2 + this.bottomY * this.mapScale;

    const btnShadow = this.getMySprite("record_btn_shadow");
    btnShadow.x = recordBtn.x;
    btnShadow.y = recordBtn.y + 50 * this.mapScale;
    // recordBtn.addChild(btnShadow, -1);

    const circle = this.getMySprite('circle');
    circle.visible = false;
    circle.x = recordBtn.x;
    circle.y = recordBtn.y;
    recordBtn['circle'] = circle

    recordBtn['shadow'] = btnShadow;
    this.topArr.push(btnShadow);
    this.topArr.push(circle);
    this.topArr.push(recordBtn);

    if (!this.circleTween) {
      this.addRecordBtnAnim();
    }
    this.addRecordTip();


  }

  addRecordTip() {
    const recordTip = new MySprite();
    recordTip.init(this.images.get("record_tip"));
    this.recordBtn.addChild(recordTip, 2);
    recordTip.y = -this.recordBtn.height + 80; 
    recordTip.anchorY = 1;
    this.recordBtn.tip = recordTip;
  }

  circleTween;
  addRecordBtnAnim() {

    const circle = this.recordBtn.circle;
    circle.setScaleXY(this.mapScale);

    this.circleTween = tweenChange(circle, {scaleX: 1.5 * this.mapScale}, 1, () => {

    }, TWEEN.Easing.Cubic.Out, () => {
      circle.scaleY = circle.scaleX;
    })

    circle.alpha = 1;
    this.circleTween = tweenChange(circle, {alpha: 0}, 1, () => {
      // delayCall(0.1, () => {
        this.addRecordBtnAnim();
      // })
    }, TWEEN.Easing.Cubic.Out)
  }

  submitBtn;
  submitBtnOff;
  initSubmitBtn() {

    const submitBtn = this.getMySprite('submit_btn')
    this.submitBtn = submitBtn;
    submitBtn.x = this.canvasWidth / 2 + 800 * this.mapScale;
    submitBtn.y = this.canvasHeight / 2 + this.bottomY * this.mapScale;

    const btnShadow = this.getMySprite("submit_btn_shadow");
    btnShadow.x = submitBtn.x;
    btnShadow.y = submitBtn.y + 20 * this.mapScale;
    submitBtn.addChild(btnShadow, -1);



    submitBtn['shadow'] = btnShadow;
    this.renderArr.push(btnShadow);
    this.renderArr.push(submitBtn);

    const submitBtnOff = this.getMySprite('submit_btn_off')
    this.submitBtnOff = submitBtnOff;
    submitBtnOff.x = submitBtn.x;
    submitBtnOff.y = submitBtn.y + 15 * this.mapScale;
    this.renderArr.push(submitBtnOff);

    submitBtn.visible = false;
    submitBtn['shadow'].visible = false;
  }

  sendBtn;
  initSendBtn() {
    
    const sendBtn = this.getMySprite('send_btn')
    this.sendBtn = sendBtn;
    sendBtn.x = this.canvasWidth / 2 + 800 * this.mapScale;
    sendBtn.y = this.canvasHeight / 2 + this.bottomY * this.mapScale;

    const btnShadow = this.getMySprite("submit_btn_shadow");
    btnShadow.x = sendBtn.x;
    btnShadow.y = sendBtn.y + 20 * this.mapScale;


    sendBtn['shadow'] = btnShadow;
    this.renderArr.push(btnShadow);
    this.renderArr.push(sendBtn);
  }

  cancelBtn;
  initCancelBtn() {
    const cancelBtn = this.getMySprite('cancel_btn')
    this.cancelBtn = cancelBtn;

    cancelBtn.x = this.canvasWidth / 2 - 800 * this.mapScale;
    cancelBtn.y = this.canvasHeight / 2 + this.bottomY * this.mapScale;

    const btnShadow = this.getMySprite("cancel_btn_shadow");
    btnShadow.x = cancelBtn.x;
    btnShadow.y = cancelBtn.y + 20 * this.mapScale;

    cancelBtn.addChild(btnShadow, -1);

    cancelBtn['shadow'] = btnShadow;
    this.renderArr.push(btnShadow);
    this.topArr.push(cancelBtn);
    this.cancelBtn.visible = false;
    this.cancelBtn.shadow.visible = false;
    this.addCancelTip();
  }

  addCancelTip() {
    const cancelTip = this.getMySprite('cancel_tip', false);
    this.cancelBtn.addChild(cancelTip);
    cancelTip.x = 120;
    cancelTip.y = -230;
    this.cancelBtn.tip = cancelTip;
  }


  getMySprite(resName, isSetScale = true) {
    const spr = new MySprite();
    spr.init(this.images.get(resName))
    if (isSetScale) {
      spr.setScaleXY(this.mapScale);
    }
    return spr;
  }


  recordBtnClick() {
    if (this.recordBtn.isRecord) {
      this.recordStop();
    } else {

      if (this.isRecordEnd) {
        this.saveRecord();
        this.initRedStripPos();
      }
      this.recordStart();
    }
    this.recordBtn.tip.visible = false;
  }

  recordStop() {
    this.recordBtn.init(this.images.get('record_btn'))
    this.recordBtn.circle.visible = false;
    this.recordBtn.isRecord = false;
    this.pauseVideo();
    
    this.serverRecordStop();
  }

  recordStart() {

    if (!this.curVideo) {
      return;
    }

    let targetText = '';
    const lastDot = this.dotArr[this.dotIndex - 1];
    if (lastDot) {
      targetText = lastDot.data.data;
    }

    this.recordBtn.init(this.images.get('record_btn_on'))
    this.recordBtn.circle.visible = true;
    this.recordBtn.isRecord = true;
    this.playVideo();

    this.serverRecordStart(targetText);

    if (!this.recordStartTime) {
      this.recordStartTime = new Date().getTime();
    }
  }

  saveRecord() {
    this.dotIndex ++;
    this.curDot = this.dotArr[this.dotIndex];

    this.cancelBtn.visible = false;
    this.cancelBtn.shadow.visible = false;
    this.recordCount = 0;

    const rate = this.curVideo.element.currentTime / this.curVideo.element.duration;
    this.setUpdateTimeLineStrip(rate);

    if (this.curRecordResult) {
      this.recordResultArr.push(this.curRecordResult);
    }
    
  }

  initRedStripPos() {
    const redStrip = this.timeLine.redStrip;
    redStrip.x = 0;
    const lastDot = this.dotArr[this.dotIndex - 1];
    if (lastDot) {
      redStrip.x = lastDot.x;
    }
    // redStrip.x -= redStrip.height / 2;
    redStrip.width = redStrip.height;
  }


  playVideo() {
    this.curVideo.element.play();
  }

  pauseVideo() {
    this.curVideo.element.pause();
  }

  playSpeed = 1;
  speedLabelClick(index) {

    this.hideAllSpeedLabel();
    const label = this.speedLabelArr[index];
    label.fontColor = '#2f9228'
    this.playSpeed = label.speed;
    this.curVideo.element.playbackRate = this.playSpeed;
  }

  hideAllSpeedLabel() {
    for (let i=0; i<this.speedLabelArr.length; i++) {
      this.speedLabelArr[i].fontColor = '#b17d5a'
    }
  }

  showSubmitBtn() {
    this.submitBtn.visible = true;
    this.submitBtn.shadow.visible = true;
    this.submitBtnOff.visible = false;
  }

  hideSubmitBtn() {
    this.submitBtn.visible = false;
    this.submitBtn.shadow.visible = false;
    this.submitBtnOff.visible = true;
  }


  cancelBtnClick() {
    this.cancelBtn.visible = false;
    this.cancelBtn.shadow.visible = false;
    this.cancelBtn.tip.visible = false;
    this.videoRollBack();
    this.isRecordEnd = false;

    this.recordBtn.visible = true;
    this.recordBtn.shadow.visible = true;
    this.hideSubmitBtn();
  }

  videoRollBack() {

    let rollBackTime = this.getLastDotTime();

    this.curVideo.element.currentTime = rollBackTime;
    this.updateVideoStrip();
    this.updateVideoTime();
  }



  maskPic;
  initMaskPic() {
    const bgUrl = this.data.contentObj.bg_url;  
    console.log('bgUrl', bgUrl);
    
    const maskPic = this.getMySprite(bgUrl);
    maskPic.scaleX = this.canvasWidth / maskPic.width;
    maskPic.scaleY = this.canvasHeight / maskPic.height;
    maskPic.x = this.canvasWidth / 2;
    maskPic.y = this.canvasHeight / 2;

    if (this.isTeacher) {
      maskPic.visible = false;
    }

    this.maskPic = maskPic;
  }

  




  relink() {

    const progress = this.getPageData('progress');

    if (this.isTeacher) {
      if (progress != null) {
        this.gameStart();
        return;
      }
      return;
    }


    if (progress == '1') {

      // const resultData = this.getPageData('resultData')
      // if (resultData) {
      //   this.initResultView(resultData);
      //   return;
      // }

      this.gameStart();
      return;
    }

    // if (progress == '2' || progress == '3') {
    //   const submitCount = this.getPageData('submitCount')
    //   this.submitCount = submitCount;
    //   this.checkShowSubTemplateOne();
    //   return;
    // }
 

  

   
  }


  setRectRight(data) {
    for (let i=0; i<this.sentenceEmptyArr.length; i++) {
      if (data[i]) {
        this.sentenceEmptyArr[i].isRight = true;
      }
    }
  }

  resultLayer;
  resultPanel;
  moreBtn;
  totalScoreLabel;
  scrollView;
  initResultView(data = null) {

    console.log( ' in initResultView 1')

    console.log('this.recordResultArr: ', this.recordResultArr);





    const resultLayer = new MySprite()
    // resultLayer.x = this.canvasWidth / 2;
    // resultLayer.y = this.canvasHeight / 2;
    this.resultLayer = resultLayer;
    // this.resultLayer.visible = false;


    const bg = new ShapeRectNew();
    bg.setSize(this.canvasWidth, this.canvasHeight, 0);
    bg.fillColor = '#3e9b31';
    resultLayer.addChild(bg);


    const resultTop = this.getMySprite('result_top', false);
    resultLayer.addChild(resultTop)
    resultTop.scaleX = this.canvasWidth / resultTop.width;
    resultTop.scaleY = this.mapScale;
    resultTop.x = this.canvasWidth / 2;
    resultTop.anchorY = 0;



    const labelScore = new Label();
    labelScore.fontSize = 80;
    labelScore.fontName = 'Aileron-Black';
    labelScore.textAlign = 'center';
    labelScore.text = '--'//totalScore.toString();
    labelScore.y = 25;
    labelScore.fontColor = '#ffffff';

    this.totalScoreLabel = labelScore;

    this.setSubScore();




    let id = '1';


    // const scoreArr = [];
    // for (let i=0; i<this.recordResultArr.length; i++) {
    //   const tmpData = this.recordResultArr[i].result;
    //   scoreArr.push(tmpData.overall);
    // }
    // const totalScore = this.getScoreByArr(scoreArr);

    const totalScore = Number(this.totalScoreLabel.text) ;

    if (totalScore > 90) {
      id = '1'
    } else if (totalScore > 75) {
      id = '2'
    } else {
      id = '3';
    }


    const medal = this.getMySprite('medal_' + id, false);
    medal.x = this.canvasWidth / 2;
    medal.y = resultTop.height / 2 * resultTop.scaleY - 180 * this.mapScale;
    medal.setScaleXY(this.mapScale);
    resultLayer.addChild(medal)



    
    medal.addChild(labelScore, 3);

    console.log( ' in initResultView 2')


    this.setMadelTitle(id, medal)

    console.log( ' in initResultView 3')

 

    console.log( ' in initResultView 4')


    this.setResultSentence();

    console.log( ' in initResultView 5')

    


    // if (data) {
    //   this.setRectRight(data);
    // } else {
    //   const resultData = this.getResultData();
    //   this.sendResult(resultData);
    //   this.setPageData('resultData', resultData);
    // }


    // const resultLayer = new MySprite()
    // resultLayer.x = this.canvasWidth / 2;
    // resultLayer.y = this.canvasHeight / 2;
    

    // const bg = new MySprite();
    // bg.init(this.images.get("result_bg"))
    // bg.x = 0
    // bg.y = 0;
    // bg.setScaleXY(this.mapScaleMax);
    // resultLayer.addChild(bg);

    // const bgItem = new MySprite();
    // bgItem.init(this.images.get("result_bg_item"));
    // bg.addChild(bgItem);

    // const panelOffY = -50 * this.mapScale;
    // const panel = new MySprite();
    // panel.init(this.images.get("result_panel"));
    // panel.setScaleXY(this.mapScale);
    // panel.y = panelOffY;
    // resultLayer.addChild(panel, 1);

    // const panelItem = new MySprite();
    // panelItem.init(this.images.get("result_panel_item"));
    // panelItem.y = -600;
    // panel.addChild(panelItem);

    // const itemLabel = new RichText();
    // itemLabel.fontSize = 52;
    // // itemLabel.y = 5;
    // itemLabel.width = panelItem.width;
    // itemLabel.fontColor = '#ffffff'
    // itemLabel.fontName = 'Aileron-Black';
    // itemLabel.text = 'Check'
    // itemLabel.y = 10;
    // itemLabel.textAlign = 'center';
    // panelItem.addChild(itemLabel, 5);

    // const panelShadow = new MySprite();
    // panelShadow.init(this.images.get("result_panel_shadow"));
    // // panelShadow.setScaleXY(this.mapScale);
    // panelShadow.y = ( panel.height / 2 - 20 );
    // panel.addChild(panelShadow);

    // const btn = new MySprite();
    // btn.init(this.images.get("big_btn"));
    // btn.setScaleXY(this.mapScale);
    // btn.y = panel.y + ( panel.height / 2 + 120 ) * panel.scaleY;
    // resultLayer.addChild(btn, 2);
    // this.moreBtn = btn;

    // const btnShadow = new MySprite();
    // btnShadow.init(this.images.get("big_btn_shadow"));
    // btnShadow.setScaleXY(this.mapScale);
    // btnShadow.y = btn.y + 30 * this.mapScale;
    // resultLayer.addChild(btnShadow);


    // const btnLabel = new Label();
    // btnLabel.fontSize = 64;
    // btnLabel.fontName = 'Aileron-Black';
    // btnLabel.textAlign = 'center';
    // btnLabel.text = '更多练习';
    // btnLabel.y = 5;
    // btnLabel.fontColor = '#ffffff';
    // btn.addChild(btnLabel, 3);

    

    // this.topArr.push(resultLayer);
    
    // this.resultPanel = panel;
    // this.resultLayer = resultLayer;



    // this.initResultSentence();

  }

  setResultSentence() {

    console.log('this.recordResultArr', this.recordResultArr);

    const scrollView = new ScrollView();

    // scrollView.setContentSize(300, 300);
    scrollView.setShowSize(this.canvasWidth, this.canvasHeight / 2);
    scrollView.setBgColor('#3e9b31');
    // scrollView.x = this.canvasWidth / 2;
    scrollView.y = this.canvasHeight / 2;
    this.scrollView = scrollView;

    this.resultLayer.addChild(scrollView);
    // this.renderArr.push(scrollView);
    


    let totalDetailArr = [];
    for (let i=0; i<this.recordResultArr.length; i++) {
      totalDetailArr = totalDetailArr.concat(this.recordResultArr[i].result.details);
    }
    
    console.log('totalDetailArr: ', totalDetailArr);
    console.log('totalDetailArr json: ', JSON.stringify( totalDetailArr ));

    // const data =  {"eof":1,"params":{"app":{"deviceId":"2397b6694a3c258a1fe2a5c1063e7757"},"audio":{"audioType":"wav","channel":1,"sampleBytes":2,"sampleRate":16000},"coreProvideType":"native","enableContonative":0,"enableRetry":1,"request":{"attachAudioUrl":1,"coreType":"en.sent.score","precision":1,"rank":100,"refText":"The stream was quite shallow so we were able to walk across it.","request_id":"0a6c9004e84211ebac7427b66529a03d","syldet":1,"symbol":1},"soundIntensityEnable":1},"refText":"The stream was quite shallow so we were able to walk across it.","request_id":"0a6c9004e84211ebac7427b66529a03d","result":{"accuracy":0,"delaytime":40,"details":[{"char":"The","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"stream","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"was","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"quite","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"shallow","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"so","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"we","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"were","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"able","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"to","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"walk","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"across","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":0,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0},{"char":"it.","dp_type":1,"dur":0,"end":0,"fluency":0,"liaisonref":0,"liaisonscore":0,"score":0,"senseref":1,"sensescore":0,"start":0,"stressref":0,"stressscore":0,"toneref":0,"tonescore":0}],"fluency":{"overall":0,"pause":0,"speed":0},"forceout":0,"info":{"clip":0,"snr":"8.136699999999999","tipId":0,"volume":92},"integrity":0,"overall":0,"precision":1,"pretime":133,"pron":0,"rank":100,"res":"eng.snt.offline.1.0","rhythm":{"overall":50,"sense":100,"stress":0,"tone":0},"statics":[{"char":"dh","count":1,"score":0},{"char":"ax","count":3,"score":0},{"char":"s","count":3,"score":0},{"char":"dr","count":1,"score":0},{"char":"iy","count":2,"score":0},{"char":"m","count":1,"score":0},{"char":"w","count":5,"score":0},{"char":"oo","count":1,"score":0},{"char":"z","count":1,"score":0},{"char":"k","count":3,"score":0},{"char":"ay","count":1,"score":0},{"char":"t","count":3,"score":0},{"char":"sh","count":1,"score":0},{"char":"ae","count":1,"score":0},{"char":"l","count":2,"score":0},{"char":"ow","count":2,"score":0},{"char":"er","count":1,"score":0},{"char":"ey","count":1,"score":0},{"char":"b","count":1,"score":0},{"char":"ao","count":1,"score":0},{"char":"r","count":1,"score":0},{"char":"aa","count":1,"score":0},{"char":"ih","count":1,"score":0}],"systime":601,"version":"0.0.80.2019.11.22.18:20:08","wavetime":3960},"version":"2.0.7"};
    // totalDetailArr = data.result.details;
  
   
    const disH = 25 * this.mapScale;
    const setOneLabel = (text) => {
      const label = new RichText();
      label.fontSize = 48 * this.mapScale;
      label.width = this.canvasWidth * 0.9;
      label.fontColor = '#ffffff'
      label.fontName = 'DroidSansFallback';
      label.text = text;
      label.disH = disH;
      label.x = this.canvasWidth * 0.1 / 2;

      scrollView.addItem(label, 2);
      // this.resultLayer.addChild(label, 20);


      label.y = baseY; 
      baseY += label.getAreaHeight() + disH;
      sentenceArr.push(label);

      resultLabelText = '';

      return label;
    }

    let resultLabelText = '';

    const sentenceArr = [];
    let lyrics = this.data.contentObj?.lrcData?.lyrics;

    // lyrics = lyrics.concat(lyrics);

    let baseY = 48 * this.mapScale; //this.canvasHeight / 2;
    for (let i=0; i<lyrics.length; i++) {
      resultLabelText += lyrics[i].data + ' ';
      if (lyrics[i].newLine ) {
        resultLabelText += '\n ';
        // setOneLabel(resultLabelText);
      }
    }


    const resultLabel = setOneLabel(resultLabelText);

    resultLabel.isShowWordBg = true;
    resultLabel.update();

    scrollView.content.height = baseY;
    scrollView.refreshScrollBar();

    const details = totalDetailArr // data.result.details;
    let index = 0;
    for (let i=0; i<details.length; i++) {

      const wordData = details[i];
      const text = wordData.char;
      const score = wordData.score;



      const rectData = resultLabel.getSubTextRect(text, index)
      if (rectData) {

        const rect = rectData.rect;
        index = rectData.index + 1;

        const edgeW = 5 * this.mapScale;
        const edgeH = 10 * this.mapScale;
        const colorRect = new ShapeRectNew();
        colorRect.setSize(rect.width + edgeW * 2, rect.height + edgeH * 2, 10 * this.mapScale);
        colorRect.x = resultLabel.x + rect.x - rect.width - edgeW;
        colorRect.y = resultLabel.y + rect.y - rect.height / 2 - edgeH * 0.7;
        scrollView.addItem(colorRect);


        if (score > 90) {
          colorRect.fillColor = '#007b3e'
        } else if (score < 75) {
          colorRect.fillColor = '#d71818'
        } else {
          colorRect.alpha = 0;
        }
  
      }
  
      // const index = cound
    }



  }

  getScoreByArr (arr) {

    console.log('getScoreByArr arr: ', arr)
    let tmpScore = 0;
    for (let i=0; i<arr.length; i++) {
      tmpScore += arr[i];
    }
    return Math.round( tmpScore / arr.length );
  }

  setSubScore() {

    console.log( ' in setSubScore 1')
    const scoreBg = new ShapeRectNew();
    scoreBg.setSize(1911, 130, 65);
    scoreBg.setScaleXY(this.mapScale);
    scoreBg.fillColor = '#3e9b31'
    scoreBg.x = this.canvasWidth / 2 - scoreBg.width / 2 * scoreBg.scaleX;
    scoreBg.y = 470 * this.mapScale;
    this.resultLayer.addChild(scoreBg);

    console.log( ' in setSubScore 2')


    const pronArr = [];
    const fluencyArr = []; //流利度
    const accuracyArr = []; // 准确度
    for (let i=0; i<this.recordResultArr.length; i++) {
      const tmpData = this.recordResultArr[i]?.result;
      if (tmpData) {

        console.log( ' index '+i+' tmpData: ', tmpData)

        pronArr.push(tmpData.pron || 0);
        fluencyArr.push(tmpData?.fluency?.overall || 0);
        accuracyArr.push(tmpData.accuracy || 0);


      }
   
    }

   
    console.log('pronArr: ', pronArr)
    console.log('fluencyArr: ', fluencyArr)
    console.log('accuracyArr: ', accuracyArr)


    const labelOffX = 550;
    const title1 = this.getLabelByOption(36, 'DroidSansFallback', '#cedebc')
    title1.text = '音准度';
    title1.x = scoreBg.width / 2 - labelOffX;
    title1.y = scoreBg.height / 2 - 20;
    scoreBg.addChild(title1);

    const titleScore1 = this.getLabelByOption(36, 'Aileron-Black')
    titleScore1.text = this.getScoreByArr(pronArr).toString();
    titleScore1.x = title1.x;
    titleScore1.y = title1.y + 50;
    scoreBg.addChild(titleScore1);

    const title2 = this.getLabelByOption(36, 'DroidSansFallback', '#cedebc')
    title2.text = '流利度';
    title2.x = scoreBg.width / 2;
    title2.y = scoreBg.height / 2 - 20;
    scoreBg.addChild(title2);

    const titleScore2 = this.getLabelByOption(36, 'Aileron-Black')
    titleScore2.text = this.getFluencyByArr(fluencyArr).toString();
    titleScore2.x = title2.x;
    titleScore2.y = title2.y + 50;
    scoreBg.addChild(titleScore2);

    const title3 = this.getLabelByOption(36, 'DroidSansFallback', '#cedebc')
    title3.text = '准确度';
    title3.x = scoreBg.width / 2 + labelOffX;
    title3.y = scoreBg.height / 2 - 20;
    scoreBg.addChild(title3);

    const titleScore3 = this.getLabelByOption(36, 'Aileron-Black')
    titleScore3.text = this.getScoreByArr(accuracyArr).toString();
    titleScore3.x = title3.x;
    titleScore3.y = title3.y + 50;
    scoreBg.addChild(titleScore3);


    this.totalScoreLabel.text = Math.round( (Number(titleScore1.text) + Number(titleScore2.text) + Number(titleScore3.text)) / 3 ).toString();
    this.totalScoreLabel.pron = Number( titleScore1.text );
    this.totalScoreLabel.fluency = Number( titleScore2.text );
    this.totalScoreLabel.accuracy = Number( titleScore3.text );
  }

  getFluencyByArr(arr: Array<number>) {
    console.log('getScoreByArr arr: ', arr)

    let allScore = arr.reduce((score, number) => score + number, 0);

    let aiScore = allScore / arr.length;

    let offsetScore = 30;

    return Math.round(aiScore * offsetScore / 100 + (100 - offsetScore));
  }

  getLabelByOption(fontSize, fontName, fontColor='#ffffff', textAlign='center') {
    const label = new Label();
    label.fontSize = fontSize;
    label.fontName = fontName;
    label.fontColor = fontColor;
    label.textAlign = 'center';
    return label;
  }


  sendAnswer() {
    const c = window['courseware'];
    if (!c) {
      return;
    }

    const time = this.recordEndTime - this.recordStartTime;
    const result = this.recordResultArr
    const totalScore = Number(this.totalScoreLabel.text);

    const {pron, fluency, accuracy} = this.totalScoreLabel;

    const data = {time, result, totalScore, pron, fluency, accuracy};
    
    console.log('send answer: ', data );
    c.sendAnswer(data);
  }
  


  setMadelTitle(id, medal) {

    let titleText;
    let fontColor;
    switch(id) {
      case '1':
        titleText = 'Excellent!'
        fontColor = '#cc296b'
        break;
      case '2':
        titleText = 'great!'
        fontColor = '#2890bc'
        break;
      case '3':
        titleText = 'Nice try!'
        fontColor = '#b17d5a'
        break;
    }

    const labelTitle = new Label();
    labelTitle.fontSize = 64;
    labelTitle.fontName = 'Aileron-Black';
    labelTitle.textAlign = 'center';
    labelTitle.text = titleText;
    labelTitle.y = 205;
    labelTitle.fontColor = fontColor
    medal.addChild(labelTitle, 3);



  }


  getResultData() {
    const dataArr = [];
    for (let i=0; i<this.sentenceEmptyArr.length; i++) {
      dataArr.push(this.sentenceEmptyArr[i].isRight == true);
    }
    return dataArr;
  }


  initResultSentence() {

    let baseY = -500;
    for (let i=0; i<this.sentenceArr.length; i++) {
      const richText = new RichText();
      richText.disH = 5;
      richText.x = -this.panel.width / 2 * 0.9
      richText.y = baseY + 80;
   
      richText.fontSize = 48;
      richText.width = this.panel.width * 0.9;
      richText.fontColor = '#ffffff'
      richText.fontName = 'DroidSansFallback';
      richText.text = this.sentenceArr[i].text ;

      this.resultPanel.addChild(richText, 1)

      const rect = richText.getSubTextRect('____________________');
      rect.width += 8;
      rect.height += 16;
      const colorRect = new ShapeRectNew();
      colorRect.setSize(rect.width, rect.height, 10);
     
      colorRect.fillColor = '#007b3e'
      const offX = 9;
      colorRect.x = rect.x + offX;
      colorRect.y = -rect.height / 2;
      // colorRect.alpha = 0.5;
      richText.addChild(colorRect);


      baseY = richText.y + richText.getAreaHeight();
      if (!this.sentenceEmptyArr[i].isRight) {
        colorRect.fillColor = '#d71818'

        const infoBg = new MySprite();
        infoBg.init(this.images.get("info_bg"));
        infoBg.y = baseY + 50;
        this.resultPanel.addChild(infoBg);
        baseY += 130;

        const infoIcon = new MySprite();
        infoIcon.init(this.images.get("info_icon"));
        infoIcon.x = -infoBg.width / 2 + 100;
        infoBg.addChild(infoIcon);

        const infoLabel = new RichText();
        infoLabel.x = infoIcon.x + 50;
        infoLabel.fontSize = 48;
        infoLabel.y = 5;
        infoLabel.width = infoBg.width;
        infoLabel.fontColor = '#ffe9b1'
        infoLabel.fontName = 'Aileron-Black';
        infoLabel.text = this.sentenceArr[i].answer;
        infoBg.addChild(infoLabel);

      } else {
        const labelAnswer = this.getFillLabel();
        labelAnswer.fontSize = 48;
        labelAnswer.fontColor = '#ffffff'
        labelAnswer.fontName = 'Aileron-Black';
        labelAnswer.text = this.sentenceArr[i].answer;
        labelAnswer.setScaleXY(1);
        labelAnswer.textAlign = 'center';

        labelAnswer.refreshSize();
        labelAnswer.x = colorRect.width / 2;
        labelAnswer.y = colorRect.height / 2;

        colorRect.addChild(labelAnswer);
      }


      if (i != this.sentenceArr.length - 1) {
        const line = new MySprite();
        line.init(this.images.get("line"));
        line.x = 0;
        line.y = baseY + 30;
        this.resultPanel.addChild(line);

        baseY = line.y
      }


    }
  }



  btnArr = [];
  initBtn() {

    this.topArr = [];

    const btnArr = [];
    let arr =  JSON.parse(JSON.stringify(this.sentenceArr)) ;
    arr = randomSortByArr(arr);
    if (!arr) {
      return;
    }
    const disW = 500 * this.mapScale;
    const baseX = this.canvasWidth / 2 - (arr.length - 1) * disW / 2
    const baseY = this.canvasHeight / 2 - 380 * this.mapScale;
    for (let i=0; i<arr.length; i++) {

      const btn = new MySprite();
      btn.init(this.images.get("btn"))
      btn.x = baseX + disW * i;
      btn.y = baseY;
      btn['baseX'] = btn.x;
      btn['baseY'] = btn.y;
      btn.setScaleXY(this.mapScale);

      const btnBg = new MySprite();
      btnBg.init(this.images.get("btn_bg"))
      btnBg.x = btn.x;
      btnBg.y = btn.y;
      btnBg.setScaleXY(this.mapScale);

      this.renderArr.push(btnBg);
      this.topArr.push(btn);

      this.addBtnLabel(btn, arr[i].answer);

      btnArr.push(btn);
    }
 
    this.btnArr = btnArr;


    if (this.isTeacher) {
      this.initSentBtn();
      return;
    }


    const submitBtn = new MySprite();
    submitBtn.init(this.images.get("submit"));
    submitBtn.setScaleXY(this.mapScale);
    submitBtn.x = this.canvasWidth / 2 + 650 * this.mapScale;
    submitBtn.y = this.canvasHeight / 2 + 650 * this.mapScale;



    const submitShadow = new MySprite();
    submitShadow.init(this.images.get("submit_shadow"));
    submitShadow.setScaleXY(this.mapScale);
    submitShadow.x = submitBtn.x;
    submitShadow.y = submitBtn.y + 20 * this.mapScale;



    const submitOff = new MySprite();
    submitOff.init(this.images.get("submit_off"));
    submitOff.setScaleXY(this.mapScale);
    submitOff.x = submitBtn.x;
    submitOff.y = submitBtn.y + 5 * this.mapScale;


    submitBtn['baseY'] = submitBtn.y;
    submitBtn['offBtn'] = submitOff;
    submitBtn['shadowSpr'] = submitShadow;
    submitShadow['baseY'] = submitShadow.y;
    
    this.renderArr.push(submitShadow);
    this.renderArr.push(submitBtn);
    this.renderArr.push(submitOff);

    this.submitBtn = submitBtn;

    this.submitOff();
  }

  sentBtn;
  initSentBtn() {

    const panel = this.panel;

    const btn = new MySprite();
    btn.init(this.images.get("big_btn"));
    btn.setScaleXY(this.mapScale);
    btn.x = this.canvasWidth / 2;
    btn.y = panel.y + ( panel.height / 2 - 120 ) * panel.scaleY;
    this.sentBtn = btn;

    const btnShadow = new MySprite();
    btnShadow.init(this.images.get("big_btn_shadow"));
    btnShadow.setScaleXY(this.mapScale);
    btnShadow.x = btn.x;
    btnShadow.y = btn.y + 20 * this.mapScale;
    this.sentBtn.shadowSpr = btnShadow;

    const btnLabel = new Label();
    btnLabel.fontSize = 64;
    btnLabel.fontName = 'Aileron-Black';
    btnLabel.textAlign = 'center';
    btnLabel.text = 'Send';
    btnLabel.y = 5;
    btnLabel.fontColor = '#ffffff';
    btn.addChild(btnLabel, 3);

    this.renderArr.push(btnShadow);
    this.renderArr.push(btn);
  }


  submitOff() {
    this.submitBtn.offBtn.visible = true;

    this.submitBtn.visible = false;
    this.submitBtn.shadowSpr.visible = false;
  }

  submitOn() {

    // this.submitBtn.y = this.submitBtn.baseY;
    // this.submitBtn.scale = this.mapScale;

    // this.submitBtn.shadowSpr.alpha = 1;
    // this.submitBtn.shadowSpr.y = this.submitBtn.shadowSpr.baseY;
    

    this.submitBtn.visible = true;
    this.submitBtn.shadowSpr.visible = true;

    this.submitBtn.offBtn.visible = false;
  }


  addBtnLabel(btn, text) {
    console.log('text:  ', text);

    const label = new Label();
    label.fontSize = 64;
    label.fontName = 'Aileron-Black';
    label.textAlign = 'center';
    label.text = text;
    // label.x = this.canvasWidth / 2;
    label.y = -2;
    label.fontColor = '#f1e4c2';
    btn.addChild(label);
    btn.text = text;
    return label;
  }

  sentenceEmptyArr;
  initSentence() {
    
    this.sentenceEmptyArr = [];
    
    const arr = this.sentenceArr;
    if (!arr) {
      return;
    }
    const baseX = this.canvasWidth / 2 -990 * this.mapScale;
    let curY = this.canvasHeight / 2 - 110 * this.mapScale;
    const disH = 70 * this.mapScale;
    for (let i=0; i<arr.length; i++) {
      const richText = this.getSentenceLabel();
      richText.x = baseX;
      richText.y = curY;
      richText.text = arr[i].text;

      const rect = richText.getSubTextRect('____________________');
      const colorRect = new ShapeRectNew();
      rect.height += 30;
      colorRect.setSize(rect.width, rect.height, 1);
     
      colorRect.fillColor = '#ff0000'
      const offX = 13;
      colorRect.x = rect.x + offX;
      colorRect.y = -rect.height / 2;
      console.log('rect.height: ', rect.height);
      colorRect.alpha = 0;

  

      richText.addChild(colorRect);
      this.sentenceEmptyArr.push(colorRect);

      curY += richText.getAreaHeight() * this.mapScale + disH;

      richText['data'] = arr[i];
      this.renderArr.push(richText);

    }
    

  }

  getFillLabel() {
    const label = new Label();
 
    label.fontSize = 56;
    label.fontColor = '#000000'
    label.fontName = 'Aileron-Bold';
    label.setScaleXY(this.mapScale);
    
    return label;
  }

  getSentenceLabel() {

    const richText = new RichText();
    richText.disH = 0;
 
    richText.fontSize = 56;
    richText.width = 2000 / this.mapScale
    richText.fontColor = '#000000'
    richText.fontName = 'DroidSansFallback';
    richText.setScaleXY(this.mapScale);
    
    return richText;

  }

  changeBtnOff() {

    for (let i=0; i<this.btnArr.length; i++) {
      if (this.btnArr[i].visible) {
        this.btnArr[i].init(this.images.get('btn_off'));
        this.btnArr[i].isOff = true;
      }
    }
    
  }

  changeBtnOn() {

    for (let i=0; i<this.btnArr.length; i++) {
      if (this.btnArr[i].visible) {
        this.btnArr[i].init(this.images.get('btn'));
        this.btnArr[i].isOff = false;
      }
    }
    
  }





  _initTitle() {

    const label = new Label();
    label.fontSize = 42 * this.mapScale;
    label.fontName = 'BRLNSDB';
    label.textAlign = 'center';
    label.setMaxSize(this.canvasWidth * 0.9);
    label.x = this.canvasWidth / 2;
    label.y = (this.bgRect.y - this.bgRect.height / 2 * this.bgRect.scaleY) / 2;
    label.fontColor = '#fff143';
    label.setShadow(0, 5, 5, 'rgba(0,0,0,0.3)');
    this.titleLabel = label;
    this.renderArr.push(label);

    const disH = 5 * this.mapScale;


    const starBg = new MySprite();
    starBg.init(this.images.get('top_star_bg'));
    starBg.setScaleXY(this.mapScale);

    const disW = starBg.width / 3 * starBg.scaleX;

    const num = this.picArr.length;
    const itemW = starBg.width * starBg.scaleX;
    const totalW = (starBg.width) * starBg.scaleX * num + disW * (num - 1);
    const offX = this.canvasWidth / 2 - totalW / 2 + itemW / 2;

    this.starBgArr = [];
    for (let i = 0; i < num; i++) {
      const starBg = new MySprite();
      starBg.init(this.images.get('top_star_bg'));
      starBg.setScaleXY(this.mapScale);
      starBg.x = offX + (itemW + disW) * i;
      starBg.y = label.y - starBg.height / 2 * starBg.scaleY - disH / 2;

      this.renderArr.push(starBg);


      const star = new MySprite();
      star.init(this.images.get('top_star'));
      star.visible = false;
      starBg['star'] = star;
      starBg.addChild(star);

      this.starBgArr.push(starBg);
    }



    label.y += label.height / 2 * label.scaleY + disH / 2;


    // const textBg = new MySprite();
    // textBg.init(this.images.get('text_bg'));
    // textBg.setScaleXY(this.mapScale);
    // textBg.x = label.x;
    // textBg.y = label.y - textBg.height / 2 * textBg.scaleY - disH / 2;
    // this.renderArr.push(textBg);
    //
    // label.y += label.height / 2 * label.scaleY + disH / 2;
    //
    //
    // const pageLabel = new Label();
    // pageLabel.text = '0 / 0';
    // pageLabel.fontName = 'BRLNSDB';
    // pageLabel.fontColor = '#ffffff';
    // pageLabel.textAlign = 'center';
    // pageLabel.fontSize = 24;
    // textBg.addChild(pageLabel);
    //
    // this.pageLabel = pageLabel;

    this.refreshTitleLabel();
    this.refreshPageLabel();
  }


  refreshTitleLabel(animaFlag = false) {
    const data = this.picArr[this.curPageIndex];

    if (animaFlag) {

      hideItem(this.titleLabel, 0.2, () => {
        this.titleLabel.text = data.text;
        showItem(this.titleLabel, 0.3);

        this.playAudio('tip', true);

      });
    } else {
      this.titleLabel.text = data.text;

    }
  }


  refreshPageLabel() {

    // const label = this.pageLabel;
    // label.text = (this.curPageIndex + 1) + ' / ' + this.picArr.length;

    for (let i = 0; i < this.curPageIndex; i++) {

      const starBg = this.starBgArr[i];
      if (starBg) {
        const star = starBg.star;
        if (!star.visible) {

          star.visible = true;
          star.setScaleXY(3);
          star.alpha = 0;

          tweenChange(star, { scaleX: 1, scaleY: 1, alpha: 1 }, 1, () => {

          }, TWEEN.Easing.Exponential.In);

        }

      }

    }
  }

  showAudio() {
    const data = this.picArr[this.curPageIndex];
    const audio = this.audioObj[data.audio_url];
    if (audio) {
      audio.play();
    }
  }



  curRecordResult;
  curTestText;
  serverRecordStart(text) {

    this.curTestText = text;

    const c = window['courseware'];
    if (!c) {
      console.error('not found window.courseware')
      return;
    }

    this.curRecordResult = null;

    if (this.curTestText) {
      c.startTest(text);
    }
    
  }

  serverRecordStop() {
    
    const c = window['courseware'];
    if (!c) {
      console.error('not found window.courseware')
      return;
    }

    if (this.curTestText) {
      c.stopTest((data) => {
        if (data) {
          this.curRecordResult = JSON.parse( data );
        }
      });
    }
  
  }




















  curMoveItem = null;
  downFlag = false;
  mapDown(event) {


    if (!this.canTouch) {
      return;
    }

    if (this.maskPic && this.maskPic.visible) {
      return;
    }

    this.downFlag = true;


    if (this.isTeacher) {
      if (this.sendBtn && this.sendBtn.visible) {
        if (this.checkClickTarget(this.sendBtn)) {
          this.sendServerEvent('game_start', {});
          this.setPageData('progress', '1');
          // this.playAudio('submit', true);
        }
      } 

      return;
    }
    


    if (this.scrollView && this.checkClickTarget(this.scrollView)) {

      this.scrollView.onTouchStart(this.mx, this.my);
      return;
    }


    if (this.resultLayer) {
      return;
    }

    if (this.checkClickTarget(this.recordBtn)) {
      if (!this.recordBtn.isRecord && this.recordBtn.visible) {
        this.recordBtnClick();
      }
      return;
    }

    if (this.checkClickTarget(this.cancelBtn)) {
      if (this.cancelBtn.visible) {
        this.cancelBtnClick();
      }
      return;
    }

    if (this.checkClickTarget(this.submitBtn)) {
      if (this.submitBtn.visible) {
        this.submitBtnClick();
      }
      return;
    }



    
    for (let i = 0; i < this.speedLabelArr.length; i++) {
      const touchRect = this.speedLabelArr[i].touchRect;
      if (this.checkClickTarget(touchRect)) {
        this.speedLabelClick(i);
        return;
      }
    }
   



  }




  mapMove(event) {
    if (event) {
      event.preventDefault() 
    }
    if (this.scrollView ) {
      this.scrollView.onTouchMove(this.mx, this.my);
    }

  }


  mapUp(event) {
    if (this.scrollView ) {
      this.scrollView.onTouchEnd(this.mx, this.my);
    }
  }


  moreBtnClick() {
    this.setPageData('progress', '2', false);
    this.setPageData('submitCount', this.submitCount);
    this.checkShowSubTemplateOne();
    this.isUpdateStop = true;
  }

  checkShowSubTemplateOne() {

    // this.showSubTemplate(0);

    console.log(' in checkShowSubTemplateOne')
    const progress = this.getPageData('progress');

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

    if (progress == '2') {
      if (this.submitCount == 1) {
        this.showSubTemplate(1);
        this.sendSubTempIsShowMore(1, true);
      } else {
        this.showSubTemplate(0);
        this.sendSubTempIsShowMore(0, true);
      }

      return;
    }

    if (progress == '3') {

      let index;
      if (this.submitCount == 1) {
        index = 0;
        this.hideSubTemplate(1);
      } else {
        index = 1;
        this.hideSubTemplate(0);

      }

      this.showSubTemplate(index);
      this.sendSubTempIsShowMore(index, false);

    }

  }

  sendSubTempIsShowMore(index, isShowMore) {
    const divArr = this.iframeContent.nativeElement.children;
    const iframecont = divArr[index].children[0];
    const data =  { msg: 'success', isShowMore};
    iframecont.contentWindow.postMessage({ action: 'is_show_more', data: JSON.stringify(data) }, '*');
    console.log(' post msg is_show_more ')
  }


  btnDown(btn) {
    this.curMoveItem = btn;
  }

  emptyRectDown(emptyRect) {
    if (emptyRect.label) {
      this.curMoveItem = emptyRect.label;
      return;
    }
  }

  recordEndTime;
  submitBtnClick() {
    // this.saveRecord();

    this.hideSubmitBtn();

    if (this.curRecordResult) {
      this.recordResultArr.push(this.curRecordResult);
    }

    // console.log('this.recordResultArr = ' + JSON.stringify(this.recordResultArr));


    this.recordEndTime = new Date().getTime();
    this.initResultView();
    this.sendAnswer();
    
    // this.resultLayer.visible = true;
    

  }

  sendResult(data) {




    // const sendResult = (<any>window).courseware.sendResult;
    // sendResult(data);

  }




  checkAnswer() {

    let isAllRight = true;
    for (let i=0; i<this.sentenceEmptyArr.length; i++) {

      const rightData = this.sentenceArr[i];
      console.log('rightData: ', rightData);

      const answer = this.sentenceEmptyArr[i].label.text;

      console.log('answer: ', answer)
      if (rightData.answer != answer) {
        this.removeRectText( this.sentenceEmptyArr[i] );
        isAllRight = false;
      } else {
        this.showSentenceRight(this.sentenceEmptyArr[i]);
      }
    }


    return isAllRight;
   
  }

  removeRectText(emptyRect) {

    this.showBtnByText(emptyRect.label.text);

    removeItemFromArr(this.renderArr, emptyRect.label);
    emptyRect.label = null;
  }

  showSentenceRight( emptyRect ) {

    if (!emptyRect.isRight) {
      emptyRect.isRight = true;
      const pos = {x: emptyRect.width / 2, y: emptyRect.height / 2};
      this.showRightParticle(emptyRect, pos)
    }
  
  }

  showRightParticle(emptyRect, point ) {
    const shapeW = 25 // * this.mapScale;
    const shapeH = 25 // * this.mapScale;
    showShapeParticle( 'rect', shapeW, shapeH, point, emptyRect, 20, 50, 180, 0.4);
  }


  showBtnByText(text) {
    for (let i=0; i<this.btnArr.length; i++) {
      if (this.btnArr[i].text == text) {
        this.btnArr[i].visible = true;
        return;
      }
    }
  }

 
  checkOnTarget() {

     
    for (let i = 0; i < this.sentenceEmptyArr.length; i++) {
      if (this.checkClickTarget(this.sentenceEmptyArr[i])) {

        this.playAudio('click', true);

        if (this.sentenceEmptyArr[i].isRight) {
          this.moveItemBack();
          return;
        }

        const tmpText = this.sentenceEmptyArr[i].label ? this.sentenceEmptyArr[i].label.text : '';

        const btnIndex = this.btnArr.indexOf(this.curMoveItem);
        const isBtn = btnIndex != -1;
      
        console.log('isBtn: ', isBtn);
        if (isBtn && tmpText != '') {
          this.moveItemBack();
          return;
        }

        this.fillText(this.sentenceEmptyArr[i], this.curMoveItem.text);

        if (this.curMoveItem.fillRect) {
          this.curMoveItem.text = tmpText;
          this.moveItemBack();
        }
    
        if (isBtn) {
          this.removeBtn(this.curMoveItem);
        }

        this.checkShowSubmit();
        return;
      }
    }

    this.moveItemBack();
  }

  removeBtn(btn) {

    this.moveItemBack();
    btn.visible = false;
    // removeItemFromArr(this.btnArr, btn);
    // removeItemFromArr(this.topArr, btn);
  }

  fillText(emptyRect, text) {

    const data = emptyRect.parent.data;

    if (!emptyRect.label) {
      emptyRect.label = this.getFillLabel();
      this.renderArr.push(emptyRect.label);
    }
    const label = emptyRect.label
    label.text = text;
    // label.width = emptyRect.width / this.mapScale;
    // label.setScaleXY(1);
    label.refreshSize();
    label.anchorY = 0.5;

    label.y = emptyRect.parent.y //- label.height * label.scaleY ;
    label.x = emptyRect.parent.x + ( emptyRect.x + emptyRect.width / 2 - label.width / 2 ) * this.mapScale

    // const w1 = emptyRect.width / this.mapScale;
    // const w2 = label.width;
    // label.width = w1// w2 < w1 ? w1: w2;
    

    label['moveOffX'] = -label.width / 2 * label.scaleX;
    label['moveOffY'] = 0// -label.height / 2 * label.scaleY;
    label['baseX'] = label.x;
    label['baseY'] = label.y;
    emptyRect.label = label;
    label.fillRect = emptyRect;
    console.log('label: ', label.width);

  }


  checkShowSubmit() {
    for (let i=0; i<this.btnArr.length; i++) {
      if (this.btnArr[i].visible) {
        return;
      }
    }

    this.submitBtn.visible = true;
    this.submitBtn.shadowSpr.visible = true;
    this.submitBtn.offBtn.visible = false;
  }



  moveItemBack() {
    this.curMoveItem.x = this.curMoveItem['baseX'];
    this.curMoveItem.y = this.curMoveItem['baseY'];
  }






  templateArr = [];
  initIframe() {

    this.templateArr = this.data.contentObj.templateArr;

    console.log('arr: ', this.templateArr);

    const c = window['courseware'];
    if (!c) {
      console.error('not found window.courseware')
      return;
    }



    const addPlayUrl = (name, index) => {

      c.getTemplateUrl(name, (data) => {
        console.log('name~: ', name)

        const urlData = JSON.parse(data)
        console.log('data~~:' , data)
        console.log('urlData~~:' , urlData)
        console.log('i~~:' , index)
        this.templateArr[index].playUrl = this.sanitizer.bypassSecurityTrustResourceUrl(urlData.play_url + `?key=${index+1}`);
        this.appRef.tick();
        
        index ++;
        if (index < this.templateArr.length) {
          const {name, last_version, play_url} = this.templateArr[index].template;
          addPlayUrl(name, index);
        }
      })
    }

    const {name, last_version, play_url} = this.templateArr[0].template;
    addPlayUrl(name, 0);

    // for (let i=0; i<this.templateArr.length; i++) {

    //   const {name, last_version, play_url} = this.templateArr[i].template;

    //   const index = i;
    //   c.getTemplateUrl(name, (data) => {
    //     console.log('name~: ', name)

    //     const urlData = JSON.parse(data)
    //     console.log('data~~:' , data)
    //     console.log('urlData~~:' , urlData)
    //     console.log('i~~:' , index)
    //     this.templateArr[index].playUrl = this.sanitizer.bypassSecurityTrustResourceUrl(urlData.play_url + `?key=${index+1}`);
        
    //   })

      // const playUrl = `https://staging-teach.cdn.ireadabc.com/h5template/${name}/v${last_version}/${play_url}?key=${i+1}`
      // this.templateArr[i].playUrl = this.sanitizer.bypassSecurityTrustResourceUrl(playUrl); 
      // console.log('playUrl: ', playUrl);
    // }
 
    // this.showSubTemplate(0);

    // setTimeout(() => {
    // this.showSubTemplate(1);
      
    // }, 5000);
  }

  showSubTemplate(index) {

    if (this.isTeacher) {
      return;
    }

    console.log('showSubTemplate _ ', index);
    const arr = this.templateArr;
    console.log('arr: ', arr);

    for (let i=0; i<arr.length; i++) {
      arr[i].leftOff = '100vw';
    }
    arr[index].leftOff = '0vw';
    this.appRef.tick();

  }


  hideSubTemplate(index) {

    this.templateArr[index].isHide = true;
    this.appRef.tick();

  }


  iframeArr;
  initWindowListener() {

    const iframeArr = this.iframeArr;

    // setTimeout(() => {

      console.log("iframeContent: ", this.iframeContent);
      let divArr = this.iframeContent.nativeElement.children;
      console.log('divArr: ', divArr);
      for (let i=0; i<divArr.length; i++) {
        const iframe = divArr[i].children[0];
        console.log('iframe: ', iframe);
        iframeArr.push(iframe)
      }
  
      console.log('iframeArr: ', iframeArr);
    // }, 1);
   

    window.addEventListener('message', (e) => {


      let msgData = e.data;
   

      if (msgData.action === "getData") {


        console.log('msgData.urlParams: ', msgData);
        const key = this.getQueryVariable(msgData.urlParams, 'key');
        if (!key) {
          return;
        }

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


        const index = key - 1;
        const divArr = this.iframeContent.nativeElement.children;
        const iframecont = divArr[index].children[0];

        // const iframecont = iframeArr[key-1]
        const saveData = this.templateArr[index].data;


        console.log("getData e: ", e);

        

        const data = { msg: 'success', data:  JSON.stringify(saveData)};

        iframecont.contentWindow.postMessage({ action: 'getData', data: JSON.stringify(data) }, '*');

        // const data2 =  { msg: 'success', data:  JSON.stringify({'isShowMore': false})};
        // iframecont.contentWindow.postMessage({ action: 'is_show_more', data: JSON.stringify(data2) }, '*');
        
        // setTimeout(() => {
        //   _this.frameLoaded = true;
        // }, 300);
      }
  
      if (msgData.action === "temp_send_result") {

        this.setPageData('progress', '3');
        console.log('in temp_send_result __ msgData: ', msgData);
      }

      if (msgData.action === "temp_show_more") {

        console.log(' in temp_show_more');
        this.checkShowSubTemplateOne();
      }

      


    });
  }


  getQueryVariable(url, variable) {
    var query = url.substring(1);
    var vars = query.split("&");
    for (var i=0;i<vars.length;i++) {
      var pair = vars[i].split("=");
      if(pair[0] == variable){return pair[1];}
    }
    return(false);
  }


  checkOnStopDot() {
    const videoCurTime = this.curVideo.element.currentTime;

    let stopTime = this.curVideo.element.duration;
    if (this.curDot) {
      stopTime = this.curDot.data.time;
    }

    if (videoCurTime >= stopTime) {

      this.curVideo.element.currentTime = stopTime;
      this.recordEnd();
  
    }
  }

  recordEnd() {
    this.recordStop();
    this.isRecordEnd = true;
    // this.showSubmitBtn();
    if (this.recordCount < 1) {
      this.cancelBtn.visible = true;
      this.cancelBtn.shadow.visible = true;
    } 
    this.recordCount ++;

    if (!this.curDot) {
      this.recordBtn.visible = false;
      this.recordBtn.shadow.visible = false;
      this.showSubmitBtn();
    }
  }


  setUpdateRedStrip(rate) {
    const redStrip = this.timeLine.redStrip;
    let len = this.timeLine.width * rate;
    if (len < redStrip.height) {
      len = redStrip.height;
    }

    redStrip.width = len //+ redStrip.height;
  }

  setUpdateTimeLineStrip(rate) {

    const strip = this.timeLine.strip;
    let len = this.timeLine.width * rate;
    if (len < strip.height) {
      len = strip.height;
    }
    if (len > this.timeLine.width) {
      len = this.timeLine.width;
    }
    strip.width = len; 
  }
  


  getLastDotTime() {

    let time = 0;
    const lastDot = this.dotArr[this.dotIndex - 1];
    if (lastDot) {
      time = lastDot.data.time;
    }
    return time;
  }
  
  updateVideoStrip() {
    // const rate = this.curVideo.element.currentTime / this.curVideo.element.duration;
    // this.setUpdateTimeLineStrip(rate);

    const lastDotTime = this.getLastDotTime();
    const redRate = (this.curVideo.element.currentTime - lastDotTime) / this.curVideo.element.duration;
    this.setUpdateRedStrip(redRate);
  }

  updateVideoTime() {
    const label = this.timeLine.curTimeLabel;
    const time = this.curVideo.element.currentTime;
    label.text = formatTime('mm:ss', new Date(time * 1000))
  }

  updateVideo() {

    if (this.isTeacher) {
      return;
    }

    if (!this.curVideo) {
      return;
    }
    if (!this.recordBtn.isRecord) {
      return;
    }
    this.updateVideoStrip();
    this.updateVideoTime();
    this.checkOnStopDot();
  }


  isUpdateStop = false;
  update() {

    if (this.isUpdateStop) {
      return;
    }
    this.animationId = window.requestAnimationFrame(this.update.bind(this));
    // 清除画布内容
    this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

    TWEEN.update();



    this.updateArr(this.renderArr);
    this.updateArr(this.topArr);
    this.updateVideo();
  
    this.updateItem(this.resultLayer)
    this.updateItem(this.maskPic)

  }










  updateItem(item) {
    if (item) {
      item.update();
    }
  }

  updateArr(arr) {
    if (!arr) {
      return;
    }
    for (let i = 0; i < arr.length; i++) {
      arr[i].update(this);
    }
  }


  maskBg;
  initHotZone() {


    let curBgRect;
    if (this.bg) {
      curBgRect = this.bg.getBoundingBox();
    }

    let oldBgRect = this.data.contentObj.bgItem.rect;
    if (!oldBgRect) {
      oldBgRect = curBgRect;
    }

    const rate = curBgRect.width / oldBgRect.width;


    // this.imgArr = [];
    // const arr = this.data.contentObj.imgItemArr;
    this.hotZoneArr = [];
    const arr = this.data.contentObj.hotZoneItemArr;
    if (!arr) return;

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

    const maskBg = new ShapeRect();
    maskBg.setSize(this.canvasWidth, this.canvasHeight);
    // maskBg.x = curBgRect.x;
    // maskBg.y = curBgRect.y;
    maskBg.fillColor = "#000000"
    this.maskBg = maskBg;
    this.renderArr.push(maskBg);

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

      const data = JSON.parse(JSON.stringify(arr[i]));
      // const img = {pic_url: data.pic_url};

      data.rect.x *= rate;
      data.rect.y *= rate;
      data.rect.width *= rate;
      data.rect.height *= rate;

      data.rect.x += curBgRect.x;
      data.rect.y += curBgRect.y;



      const hotZone = this.getHotZoneItem(data);


      // hotZone.alpha = 0.5;
      // this.hotZoneArr.push(hotZone);

    }

  }


  openBtn;
  getHotZoneItem(data) {

    console.log(' item data: ', data);
    const saveRect = data.rect;

    if (data.gIdx == '0') {

      //遮照
      const pic = new MySprite();
      pic.init(this.images.get(data.pic_url));
      pic.scaleX = saveRect.width / pic.width;
      pic.scaleY = saveRect.height / pic.height;
      pic.x = saveRect.x + saveRect.width / 2;
      pic.y = saveRect.y + saveRect.height / 2;
      pic['data'] = data;

      this.maskBg.setMaskType("destination-out");
      this.maskBg.addMaskSpr(pic);

      return pic;

    } else {

      //open按钮

      const openBtn = new MySprite();
      openBtn.init(this.images.get("open"))

      openBtn.x = saveRect.x + saveRect.width / 2;
      openBtn.y = saveRect.y + saveRect.height / 2;
      openBtn['data'] = data;

      openBtn.setScaleXY(this.mapScale);
      this.openBtn = openBtn;
      this.renderArr.push(openBtn);
    }


    // const saveRect = data.rect;
    // const item = new ShapeRect(this.ctx);
    // item.setSize(saveRect.width, saveRect.height);
    // item.x = saveRect.x;
    // item.y = saveRect.y;
    // item.fillColor = '#ff0000';
    // item['data'] = data;

    //  this.renderArr.push(item);

    // return item;
  }


  showEndPetal() {
    this.endPageArr = [];
    this.showPetalFlag = true;
    this.addPetal();
  }

  stopEndPetal() {
    this.endPageArr = [];
    this.showPetalFlag = false;
  }

  addPetal() {

    if (!this.showPetalFlag) {
      return;
    }

    const petal = this.getPetal();
    this.endPageArr.push(petal);

    moveItem(petal, petal.x, this.canvasHeight + petal.height * petal.scaleY, petal['time'], () => {
      removeItemFromArr(this.endPageArr, petal);
    });

    rotateItem(petal, petal['tr'], petal['time']);

    setTimeout(() => {
      this.addPetal();
    }, 100);

  }


  getPetal() {

    const petal = new MySprite(this.ctx);

    const id = Math.ceil(Math.random() * 3);
    petal.init(this.images.get('petal_' + id));

    const randomS = (Math.random() * 0.4 + 0.6) * this.mapScale;
    petal.setScaleXY(randomS);

    const randomR = Math.random() * 360;
    petal.rotation = randomR;

    const randomX = Math.random() * this.canvasWidth;
    petal.x = randomX;
    petal.y = -petal.height / 2 * petal.scaleY;

    const randomT = 0.5 + Math.random() * 2.5;
    petal['time'] = randomT;

    let randomTR = 360 * Math.random(); // - 180;
    if (Math.random() < 0.5) { randomTR *= -1; }
    petal['tr'] = randomTR;

    return petal;
  }





  initListener() {

    this.winResizeEventStream
      .pipe(debounceTime(500))
      .subscribe(data => {
        this.renderAfterResize();
      });


    // ---------------------------------------------
    const setParentOffset = () => {
      const rect = this.canvas.nativeElement.getBoundingClientRect();
      this.canvasLeft = rect.left;
      this.canvasTop = rect.top;
    };
    const setMxMyByTouch = (event) => {
      if (event.touches.length <= 0) {
        return;
      }
      if (this.canvasLeft == null) {
        setParentOffset();
      }
      this.mx = event.touches[0].pageX * this.canvasScale  - this.canvasLeft;
      this.my = event.touches[0].pageY * this.canvasScale - this.canvasTop;
    };

    const setMxMyByMouse = (event) => {
      this.mx = event.offsetX * this.canvasScale;
      this.my = event.offsetY * this.canvasScale;
    };
    // ---------------------------------------------


    let firstTouch = true;

    const touchDownFunc = (e) => {
      if (firstTouch) {
        firstTouch = false;
        removeMouseListener();
      }
      console.log('touch down');
      setMxMyByTouch(e);
      this.mapDown(e);
    };
    const touchMoveFunc = (e) => {
      setMxMyByTouch(e);
      this.mapMove(e);
    };
    const touchUpFunc = (e) => {
      setMxMyByTouch(e);
      this.mapUp(e);
    };

    const mouseDownFunc = (e) => {
      if (firstTouch) {
        firstTouch = false;
        removeTouchListener();
      }
      console.log('mouse down');
      setMxMyByMouse(e);
      this.mapDown(e);
    };
    const mouseMoveFunc = (e) => {
      setMxMyByMouse(e);
      this.mapMove(e);
    };
    const mouseUpFunc = (e) => {
      setMxMyByMouse(e);
      this.mapUp(e);
    };


    const element = this.canvas.nativeElement;

    const addTouchListener = () => {
      element.addEventListener('touchstart', touchDownFunc);
      element.addEventListener('touchmove', touchMoveFunc);
      element.addEventListener('touchend', touchUpFunc);
      element.addEventListener('touchcancel', touchUpFunc);
    };
    const removeTouchListener = () => {
      element.removeEventListener('touchstart', touchDownFunc);
      element.removeEventListener('touchmove', touchMoveFunc);
      element.removeEventListener('touchend', touchUpFunc);
      element.removeEventListener('touchcancel', touchUpFunc);
    };

    const addMouseListener = () => {
      element.addEventListener('mousedown', mouseDownFunc);
      element.addEventListener('mousemove', mouseMoveFunc);
      element.addEventListener('mouseup', mouseUpFunc);
    };
    const removeMouseListener = () => {
      element.removeEventListener('mousedown', mouseDownFunc);
      element.removeEventListener('mousemove', mouseMoveFunc);
      element.removeEventListener('mouseup', mouseUpFunc);
    };

    addMouseListener();
    addTouchListener();

    element.addEventListener('mousewheel', (event) => {
      setMxMyByMouse(event);
      if (event.deltaY > 0) {
        this.wheelDown(event);
      } else {
        this.wheelUp(event);
      }
    });
  }


  wheelUp(event: any) {
    if (this.scrollView) {
      this.scrollView.onWheelUp(event.deltaY);
    }
  }


  wheelDown(event: any) {
    if (this.scrollView) {
      this.scrollView.onWheelDown(event.deltaY);
    }
  }


  playAudio(key, now = false, callback = null) {

    const audio = this.audioObj[key];
    if (audio) {

      const audioNew = new Audio();
      audioNew.src = audio.src;
      audioNew.load();
      audioNew.play();

      // if (now) {
      //   audio.pause();
      //   audio.currentTime = 0;
      // }

      // if (callback) {
      //   audio.onended = () => {
      //     callback();
      //   };
      // }
      // audio.play();
    }
  }




  showArr(arr) {
    if (!arr) {
      return;
    }
    for (let i = 0; i < arr.length; i++) {
      arr[i].visible = true;
    }
  }

  hideArr(arr) {
    if (!arr) {
      return;
    }
    for (let i = 0; i < arr.length; i++) {
      arr[i].visible = false;
    }
  }



  IsPC() {

    if (window['ELECTRON']) {
      return false; // 封装客户端标记
    }


    if (document.body.ontouchmove !== undefined && document.body.ontouchmove !== undefined) {
      return false;
    } else {
      return true;
    }

  }


  loadResources() {
    const pr = [];
    this.rawImages.forEach((value, key) => {// 预加载图片

      const p = this.preload(value)
        .then(img => {
          this.images.set(key, img);
        })
        .catch(err => console.log(err));

      pr.push(p);
    });

    this.rawAudios.forEach((value, key) => {// 预加载图片

      const a = this.preloadAudio(value)
        .then(() => {
          // this.images.set(key, img);
        })
        .catch(err => console.log(err));

      pr.push(a);
    });
    return Promise.all(pr);
  }

  preload(url) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      // img.crossOrigin = "anonymous";
      img.onload = () => resolve(img);
      img.onerror = reject;
      img.src = url;
    });
  }

  preloadAudio(url) {
    return new Promise((resolve, reject) => {
      const audio = new Audio();
      resolve({})
      audio.oncanplay = (a) => {
        //resolve();
      };
      audio.onerror = () => {
        reject();
      };
      audio.src = url;
      audio.load();
    });
  }


  renderAfterResize() {
    this.canvasWidth = this.wrap.nativeElement.clientWidth;
    this.canvasHeight = this.wrap.nativeElement.clientHeight;
    this.init();
  }



  checkClickTarget(target) {

    const rect = target.getBoundingBox();

    // rect.x /= 2;
    // rect.y /= 2;
    // rect.width /= 2;
    // rect.height /= 2;

    if (this.checkPointInRect(this.mx, this.my, rect)) {
      return true;
    }
    return false;
  }

  getWorlRect(target) {

    let rect = target.getBoundingBox();

    if (target.parent) {

      const pRect = this.getWorlRect(target.parent);
      rect.x += pRect.x;
      rect.y += pRect.y;
    }
    return rect;
  }

  checkPointInRect(x, y, rect) {

    if (x >= rect.x && x <= rect.x + rect.width) {
      if (y >= rect.y && y <= rect.y + rect.height) {
        return true;
      }
    }
    return false;
  }

  getPosByAngle(angle, len) {

    const radian = angle * Math.PI / 180;
    const x = Math.sin(radian) * len;
    const y = Math.cos(radian) * len;

    return { x, y };

  }

  getPosDistance(sx, sy, ex, ey) {

    const _x = ex - sx;
    const _y = ey - sy;
    const len = Math.sqrt(Math.pow(_x, 2) + Math.pow(_y, 2));
    return len;
  }

  onSelectStart(event) {
    var srcElmt = event.srcElement;
    console.log('汪汪汪');
    if (srcElmt && (srcElmt.tagName != 'INPUT' || srcElmt.tagName != 'TEXTAREA')) {
      return false;
    }
  }
}
