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

import {
  getAngleByPos,
  MySprite,
  getPosByAngle,
  Label,
  MyAnimation,
  moveItem,
  randomSortByArr,
  scaleItem,
  rotateItem,
  tweenChange,
  hideItem,
  showItem,
  BitMapLabel,
  ColorSpr,
  removeItemFromArr,
  ShapeRect,
  alphaItem,
  circleMove,
  ShapeCircle,
  delayCall,
  RichText,
  getMinScale,
  getPosDistance, jelly, showPopParticle, shake, Cow, formatTime
} 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 {del} from 'selenium-webdriver/http';
import {text} from "@angular/core/src/render3";




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

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

  @Input()
  sid;

  @ViewChild('canvas') canvas: ElementRef;
  @ViewChild('wrap') wrap: ElementRef;
  canvasWidth = 1280;
  canvasHeight = 720;

  canvasBaseW = 1280;
  canvasBaseH = 720;

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


  mx;
  my; // 点击坐标



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

  // 声音

  bgAudio = new Audio();
  successAudio = new Audio();
  wrongAudio = new Audio();
  rightAudio = new Audio();
  titleAudio = new Audio();


  images = new Map();

  animationId: any;
  winResizeEventStream = new Subject();


  audioObj = {};
  renderArr;
  mapScale = 1;

  canvasLeft;
  canvasTop;


  canTouch = true;


  KEY = 'dfzx_zx_image';

  // -----
  picArr;
  itemArrA;
  itemArrB;
  curItem;
  linkIdArr;
  petalTime;
  optionArr;
  cowScale;
  grassArr;
  curGrass;
  downFlag = true;
  cowArr;
  timeLabel;
  clockUpdateFlag;
  clock1Bg;
  btnRestar;
  restartBtn;
  clock2Bg;
  curCow;

  pageLabel;
  leftBtn;
  rightBtn;
  curPicBg;
  bgLayer;
  curPageIndex;
  curAudio;



  itemBgArr;
  ballArr;
  lightIndex = 0;
  grouoLightIndex = 0;
  curLight;
  goBtn;
  wheel;
  arrow;
  lightDelayTime = 0;
  questionBg;
  answerLabelArr;
  questionLabel;
  questionLabel2;
  questionPicRect;
  textBgArr;
  picBgArr;
  answerPicArr;
  idArr;
  answerTypeArr = ['A', 'B', 'C', 'D'];
  answerTitleArr;
  lightDelayId;
  rightFlag;
  ballGroupArr;
  animaStopRun;
  animaNewStopRun;


  hotZoneArr;
  picRect;
  closeBtn;
  itemBg;
  curSong;



  oldFrameColorId;
  curCard;
  bottomCard;


  picW = 370;
  picH = 260;
  mask;
  ball;
  stick;
  robot;



  pageW = 840;
  page1;
  page2;
  arm1;
  arm2;
  centerPageArr;
  pageOffX = 100;
  curPic;



  roleArr;
  picIndex = 0;
  curData;
  bgTop;
  topImg;
  curWordArr;
  wordMoveFlag;
  maxScore;
  bottomY;
  leftScore;
  rightScore;
  leftScoreLabel;
  rightScoreLabel;
  addScoreNum = 20;
  leftWin;
  rightWin;
  startPageArr = [];



  bgArr;
  rightArr;

  title;


  startBtn;
  starArr;

  wand;

  light;
  replayBtn;
  endPageArr;
  gameEndFlag;
  showPetalFlag;
  bg;




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

  }


  ngOnInit() {


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

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

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

      this.initDefaultData();



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

    }, this.KEY);


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





  initDefaultData() {


    let picArr = this.data.contentObj.picArr;
    // console.log('picArr: ', picArr);
    if (!picArr || picArr.length == 0) {


      const picArr = [];
      for (let i = 0; i < 2; i++) {
        picArr.push({
          'pic_url': 'assets/play/default/pic.jpg',
          'audio_url': 'assets/play/default/audio.mp3'
        });
      }

      this.data.contentObj.picArr = picArr;

    }


  }

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

  initData() {

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

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


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

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

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






    this.canTouch = true;

    this.curPageIndex = 0;

    // this.downFlag = false;

    this.endPageArr = [];

    // this.clockUpdateFlag = false;

    if (!this.data.contentObj.picArr) {
      this.data.contentObj.picArr = [];
    }
    this.picArr = this.data.contentObj.picArr;

    // this.optionArr = this.data.contentObj.optionArr;
    // this.optionArr = randomSortByArr(this.optionArr);

    this.curGrass = null;
    this.curCow = null;

    // this.picArr = randomSortByArr(this.picArr);
    //
    // // this.picArr = randomSortByArr(this.picArr);
    this.picIndex = 0;



  }





  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'), 0.3);
    // addOneAudio('angry', this.rawAudios.get('angry'), 1);
    // 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);
          }
      };


      let arr = this.data.contentObj.picArr;
      if (arr) {

        for (let i = 0; i < arr.length; i++) {
          addPicUrl( arr[i].pic_url);
        }
      }


    }


    // this.initFontImg();



    // 预加载资源

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

      window['air'].hideAirClassLoading(this.KEY, this.data);

      this.init();
      this.update();
    });

  }

  initFontImg() {



    // const fontbaseUrlW = 'assets/mechanical/letter/';
    // const fontDataW = {};
    //
    // let num = 97;
    // for (let i = 0; i < 26; i++) {
    //
    //   const key = String.fromCharCode(num + i);  // 'a'
    //   const url = fontbaseUrlW + key + '.png';
    //
    //   this.rawImages.set(url, url);
    //   fontDataW[key] = url;
    // }
    //
    //
    // this.fontDataW = fontDataW;
  }

  setfontData() {

    // for (let key in this.fontDataW) {
    //   this.fontDataW[key] = this.images.get(this.fontDataW[key]);
    // }
  }








  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;


    // console.log('this.ctx.canvas w: ', this.ctx.canvas.width);
    // console.log('this.ctx.canvas h: ', this.ctx.canvas.height);
  }


  initView() {

    this.initBg();
    this.initPic();
    this.initBottomRight();


    this.refreshPageLabel();
    // this.initClock();

    // this.initCow();

    // this.initItem();

    // this.initGrass();

    // this.showClock2();

  }

  initBottomRight() {

    const px = this.canvasWidth - 100 * this.mapScale;
    const py = this.canvasHeight - 50 * this.mapScale;
    const offX = 40 * this.mapScale;



    const leftBtn = new MySprite();
    leftBtn.init(this.images.get('btn_left'));
    leftBtn.setScaleXY(this.mapScale);
    leftBtn.x = px - offX;
    leftBtn.y = py;

    const rightBtn = new MySprite();
    rightBtn.init(this.images.get('btn_right'));
    rightBtn.setScaleXY(this.mapScale);
    rightBtn.x = px + offX;
    rightBtn.y = py;

    this.renderArr.push(leftBtn);
    this.renderArr.push(rightBtn);

    const textBg = new MySprite();
    textBg.init(this.images.get('text_bg'));
    textBg.setScaleXY(this.mapScale);
    textBg.x = px;
    textBg.y = py - 65 * this.mapScale;
    this.renderArr.push(textBg);




    const label = new Label();
    label.text = '0 / 0';
    label.fontName = 'BRLNSDB';
    label.fontSize = 24;
    label.fontColor = '#ffffff';
    label.textAlign = 'center';
    label.setMaxSize( textBg.width * textBg.scaleX * 0.9 );
    textBg.addChild(label);


    this.leftBtn = leftBtn;
    this.rightBtn = rightBtn;
    this.pageLabel = label;

    if (this.picArr.length <= 1) {
      this.leftBtn.visible = false;
      this.rightBtn.visible = false;
      textBg.visible = false;
    }
  }


  refreshPageLabel() {

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

    this.showAudio();
  }

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

      this.curAudio = audio;
    }
  }


  initCow() {

    this.cowArr = [];

    const edgeW = 50 * this.mapScale;
    let itemW = 377 * this.mapScale * 0.9;
    let disW = (this.canvasWidth - edgeW * 2 - itemW * 3) / 2;
    let offX = this.canvasWidth / 2 - (itemW + disW) / 2 * (this.picArr.length - 1);

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

    if (this.picArr.length >= 4) {
      const itemRate = 10;
      const disWRate = 1;
      const tmp = (this.canvasWidth - edgeW * 2) / (itemRate * this.picArr.length + disWRate * (this.picArr.length - 1));

      itemW = itemRate * tmp;
      disW = disWRate * tmp;
      offX = edgeW + itemW / 2;
    }

    this.cowScale = itemW / 377;

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

      const data = this.picArr[i];

      const cow = new Cow();
      cow.init();
      cow.setScaleXY(itemW / 377);
      cow.x = offX + i * (itemW + disW);
      cow.y = this.canvasHeight / 2 + 140 * this.mapScale - itemW / 2;
      cow.width = 377;
      cow.height = 377;
      cow['id'] = i;
      cow['baseX'] = cow.x;
      cow['baseY'] = cow.y;
      cow['data'] = data;

      cow['offX'] = -70 * cow.scaleX;
      cow['offY'] = 70 * cow.scaleY;


      const url = this.rawAudios.get('cow_start');
      const audio = new Audio();
      audio.src = url.toString();
      audio.load();
      audio.volume = 0.2;
      cow['audio'] = audio;


      let item;
      if (data.pic_url) {
        item = new MySprite();
        item.init(this.images.get(data.pic_url));
        item.setScaleXY(getMinScale(item, 130));

      } else {
        item = new Label();
        item.text = data.text;
        item.fontName = 'BRLNSDB';
        item.fontSize = 72;
        item.fontColor = '#fe5e22';
        item.textAlign = 'center';
        item.setMaxSize(160);
      }
      cow.setBubble(this.images.get('bubble_small'), this.images.get('bubble_big'), item);

      for (let j = 0; j < 12; j++) {
        const key = 'idle_' + (j + 1);
        cow.addIdleFrame(this.images.get(key));
      }

      for (let j = 0; j < 12; j++) {
        const key = 'eat_' + (j + 1);
        cow.addEatFrame(this.images.get(key));
      }

      for (let j = 0; j < 6; j++) {
        const key = 'angry_' + (j + 1);
        cow.addAngryFrame(this.images.get(key));
      }

      for (let j = 0; j < 4; j++) {
        const key = 'happy_' + (j + 1);
        cow.addHappyFrame(this.images.get(key));
      }

      for (let j = 0; j < 6; j++) {
        const key = 'like_' + (j + 1);
        cow.addLikeFrame(this.images.get(key));
      }


      cow.setStyle('idle');

      this.renderArr.push(cow);
      this.cowArr.push(cow);
      cow.delayPerUnit = 0.15;
      cow.loop = true;
      // cow.play();


      cow.y = -cow.height * cow.scaleY;
      setTimeout(() => {

        moveItem(cow, cow['baseX'], cow['baseY'], 1.2, () => {
          cow.idle();
        }, TWEEN.Easing.Bounce.Out);

        setTimeout(() => {
          cow['audio'].play();
        }, 440);

      }, Math.random() * 0.5 * 1000);
    }

    setTimeout(() => {
      this.initGrass();
    }, (0.3 + 1.2) * 1000);

  }

  initPic() {



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

      const data = this.picArr[i];

      const pic = new MySprite();
      pic.init(this.images.get(data.pic_url));
      // pic.x = this.canvasWidth / 2;
      // pic.y = this.canvasHeight / 2;

      const maxW = this.canvasWidth * 0.9;
      const maxH = this.canvasHeight * 0.9;
      const sx = maxW / pic.width;
      const sy = maxH / pic.height;
      const s = Math.min(sx, sy);
      pic.setScaleXY(s);
      // pic.setRadius(50 * this.mapScale);


      const picBg = new ShapeRect();
      picBg.setSize(pic.width * pic.scaleX, pic.height * pic.scaleY);
      picBg.x = this.canvasWidth / 2 + this.canvasWidth * i;
      picBg.y = this.canvasHeight / 2;
      picBg.init();
      picBg.fillColor = '#ffffff';
      // picBg.setRadius(50 * this.mapScale);
      picBg.setShadow(0, 10, 20, 'rgba(0,0,0,0.3)');
      // picBg.alpha = 0;
      // this.renderArr.push(picBg);
      // this.renderArr.push(picShadow);

      picBg.addChild(pic);

      this.bgLayer.addChild(picBg);
    }






  }



  initGrass() {

    this.grassArr = [];

    // this.optionArr = this.optionArr.concat(this.optionArr);

    const rect = new ShapeRect();
    rect.setSize(this.canvasWidth, this.canvasHeight / 3);
    rect.alpha = 0.3;
    rect.y = this.canvasHeight - rect.height;
    // this.renderArr.push(rect);

    const scale = this.cowScale;

    const grassW = 231 * scale;
    const grassH = 148 * scale * 0.8;

    const num = this.optionArr.length;
    const disW = 0 * this.mapScale;
    const maxRowNum = Math.floor(this.canvasWidth / (grassW + disW));
    let offX = this.canvasWidth / 2 - (num - 1) * (grassW + disW) / 2 - grassW / 4;
    if (num > maxRowNum) {
      offX = this.canvasWidth / 2 - (maxRowNum - 1) * (grassW + disW) / 2 - grassW / 4;
    }
    let offY = this.canvasHeight - grassH / 2;

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

    for (let i = 0; i < this.optionArr.length; i++) {
      const data = this.optionArr[i];
      // console.log('option data: ', data);

      const grass = new MySprite(this.ctx);
      grass.init(this.images.get('grass'));
      grass.setScaleXY(scale);
      grass['type'] = data.type;
      grass['data'] = data;


      const light = new MySprite();
      light.init(this.images.get('grass_light'));
      light.visible = false;
      grass.addChild(light);
      grass['light'] = light;

      const url = this.rawAudios.get('grass');
      const audio = new Audio();
      audio.src = url.toString();
      audio.load();
      audio.volume = 0.2;
      grass['audio'] = audio;




      if (data.pic_url) {

        // const w = 150;
        // const h = 50;
        const w = 80;
        const h = 80;

        const pic = new MySprite();
        pic.init(this.images.get(data.pic_url));
        pic.setScaleXY(getMinScale(pic, w));
        pic.x = 15;
        pic.y = -3;

        // const pic = new ShapeRect();
        // pic.alpha = 0.3;
        // pic.setSize(w, h);
        // // pic.x = -w / 2 + 6;
        // // pic.y = -h / 2 - 3.5;
        // pic.x = -w / 2 + 15;
        // pic.y = -h / 2 - 3;
        grass.addChild(pic);
      } else {

        const label = new Label();
        label.text =  data.text;
        label.fontName = 'BRLNSDB';
        label.fontColor = '#ffffff';
        label.fontSize = 48;
        label.textAlign = 'center';
        label.setMaxSize(140);
        label.x = 6;
        label.y = -2.5;
        grass.addChild(label);
      }


      const tmpNum = Math.floor(i / maxRowNum);
      grass.x = offX + (i % maxRowNum) * (grassW + disW) + tmpNum % 2 * grassW / 2;
      grass.y = offY - (tmpNum) * grassH;
      grass['baseX'] = grass.x;
      grass['baseY'] = grass.y;



      this.grassArr.push(grass);
      this.renderArr.push(grass);

      grass['baseS'] = grass.scaleX;
      grass.setScaleXY(0);
      setTimeout(() => {

        scaleItem(grass, grass['baseS'], 1 + Math.random() * 0.5, null, TWEEN.Easing.Elastic.Out);

        grass['audio'].play();
      }, 500 * Math.random());

      setTimeout(() => {
        this.canTouch = true;
        this.showTime();
      }, 1300);
    }




  }


  showTime() {

    this.timeLabel.date = new Date();
    this.clockUpdateFlag = true;
  }




  initItem() {


    const picArr = this.picArr;

    let itemW, edgeW, disW, disH, offX, offY;

    if (picArr.length <= 6) {

      itemW = 215 * this.mapScale;
      edgeW = 10 * this.mapScale;
      disW = (this.canvasWidth - itemW * 6 - edgeW * 2) / 5;
      disH = 300 * this.mapScale;

      offX = this.canvasWidth / 2 - (picArr.length - 1) * (itemW + disW) / 2;
      offY = this.canvasHeight / 2 - disH / 2 + 70 * this.mapScale;
    } else {


      // itemW = 215 * this.mapScale;
      const rate = 10; // 距离与图片比例 10：1
      edgeW = 10 * this.mapScale;
      itemW = (this.canvasWidth - edgeW / 2) / (picArr.length * rate + picArr.length + 1) * rate;
      disW = itemW / rate;
      disH = 300 * this.mapScale;

      offX = this.canvasWidth / 2 - (picArr.length - 1) * (itemW + disW) / 2;
      offY = this.canvasHeight / 2 - disH / 2 + 70 * this.mapScale;
    }

    const tmpS = itemW / 215;
    const rectW = 157 * tmpS;



    let dataArrA = [];
    let dataArrB = [];
    for (let i = 0; i < picArr.length; i ++) {
      const picData = picArr[i];

      let tmpData = {};
      tmpData['id'] = i;
      tmpData['text'] = picData.a_text;
      tmpData['pic_url'] = picData.a_pic_url;
      tmpData['audio_url'] = picData.a_audio_url;
      dataArrA.push(tmpData);

      tmpData = {};
      tmpData['id'] = i;
      tmpData['text'] = picData.b_text;
      tmpData['pic_url'] = picData.b_pic_url;
      tmpData['audio_url'] = picData.b_audio_url;
      dataArrB.push(tmpData);
    }

    dataArrA = randomSortByArr(dataArrA);
    dataArrB = randomSortByArr(dataArrB);

    // this.itemArrA = itemArrA;
    // this.itemArrB = itemArrB;



    this.itemArrA = [];
    this.itemArrB = [];
    for (let i = 0; i < picArr.length; i ++) {


      const dataA = dataArrA[i];

      let itemBg = new MySprite();
      itemBg.init(this.images.get('item_bg'));
      itemBg.setScaleXY(itemW / itemBg.width);
      itemBg.x = offX + i * (itemW + disW);
      itemBg.y = offY;

      let bgRect = new ShapeRect();
      // bgRect.setSize(rectW, rectW);
      bgRect.setSize(157, 157);
      bgRect.init();
      // bgRect.x = itemBg.x;
      // bgRect.y = itemBg.y;
      bgRect.fillColor = '#ffffff';
      itemBg.addChild(bgRect, -1);
      // this.renderArr.push(bgRect);

      if (dataA.pic_url) {
        let pic = new MySprite();
        pic.init(this.images.get(dataA.pic_url));
        pic.setScaleXY(getMinScale(pic, bgRect.width - 2));
        bgRect.addChild(pic);
      } else {
        const label = new Label();
        label.text = dataA.text;
        label.fontName = 'BRLNSDB';
        label.textAlign = 'center';
        label.fontSize = 64;
        label.setMaxSize(bgRect.width - 20);

        bgRect.addChild(label);
      }

      let dot = new MySprite();
      dot.init(this.images.get('dot'));
      dot.y = itemBg.height / 2 - 25;
      dot.visible = false;
      itemBg.addChild(dot);

      itemBg['dot'] = dot;
      itemBg['type'] = 'A';
      itemBg['data'] = dataA;
      this.renderArr.push(itemBg);
      this.itemArrA.push(itemBg);




      const dataB = dataArrB[i];
      itemBg = new MySprite();
      itemBg.init(this.images.get('item_bg'));
      itemBg.setScaleXY(itemW / itemBg.width);
      itemBg.x = offX + i * (itemW + disW);
      itemBg.y = offY + disH;


      bgRect = new ShapeRect();
      // bgRect.setSize(rectW, rectW);
      bgRect.setSize(157, 157);
      bgRect.init();
      // bgRect.x = itemBg.x;
      // bgRect.y = itemBg.y;
      bgRect.fillColor = '#ffffff';
      itemBg.addChild(bgRect, -1);
      // this.renderArr.push(bgRect);

      if (dataB.pic_url) {
        let pic = new MySprite();
        pic.init(this.images.get(dataB.pic_url));
        pic.setScaleXY(getMinScale(pic, bgRect.width - 2));
        bgRect.addChild(pic);
      } else {
        const label = new Label();
        label.text = dataB.text;
        label.fontName = 'BRLNSDB';
        label.textAlign = 'center';
        label.fontSize = 64;
        label.setMaxSize(bgRect.width - 20);

        bgRect.addChild(label);
      }

      dot = new MySprite();
      dot.init(this.images.get('dot'));
      dot.y = -itemBg.height / 2 + 25;
      dot.visible = false;
      itemBg.addChild(dot);

      itemBg['dot'] = dot;
      itemBg['type'] = 'B';
      itemBg['data'] = dataB;
      this.renderArr.push(itemBg);
      this.itemArrB.push(itemBg);
    }
  }

  showStartAnima() {

    const go = new MySprite(this.ctx);
    go.init(this.images.get('go'));
    go.setScaleXY(this.mapScale);
    go.x = this.canvasWidth + go.width * go.scaleX;
    go.y = this.canvasHeight - go.height / 2 * go.scaleY - 30 * this.mapScale;
    this.renderArr.push(go);
    this.goBtn = go;

    const targetX = this.canvasWidth - go.width / 2 * go.scaleX - 30 * this.mapScale;
    moveItem(go, targetX, go.y, 0.7, () => {

    }, TWEEN.Easing.Cubic.Out);

    this.playAudio('enter');

  }


  initLightAnima() {


    clearTimeout(this.lightDelayId);

    if (this.animaStopRun) {
      return;
    }


    const delayTime = this.lightDelayTime;


    // delayCall(delayTime, () => {

    this.lightDelayId = setTimeout(() => {

      if (this.animaStopRun) {
        return;
      }

      if (this.curLight) {
        hideItem(this.curLight, 0.02, null, TWEEN.Easing.Cubic.Out);
      }

      this.curLight = this.ballArr[this.lightIndex].light;

      showItem(this.curLight, 0.02, () => {
        this.initLightAnima();
      }, TWEEN.Easing.Cubic.Out);

      this.lightIndex--;
      if (this.lightIndex < 0) {
        this.lightIndex = this.ballArr.length - 1;
      }
      // });
    }, delayTime * 1000);
  }

  initLightAnimaNew() {

    // console.log(' in initLightAnimaNew');

    clearTimeout(this.lightDelayId);

    if (this.animaNewStopRun) {
      return;
    }


    const delayTime = this.lightDelayTime;
    // delayCall(delayTime, () => {

    this.lightDelayId = setTimeout(() => {
      // if (this.curLight) {
      //   hideItem(this.curLight, 0.02, null, TWEEN.Easing.Cubic.Out);
      // }
      //

      if (this.animaNewStopRun) {
        return;
      }

      this.lightDelayTime = 1;

      for (let i = 0; i < this.ballGroupArr.length; i++) {
        if (i != this.grouoLightIndex) {
          const arr = this.ballGroupArr[i].arr;
          for (let j = 0; j < arr.length; j++) {
            hideItem(arr[j], 0.02);
          }
        }
      }

      // this.curLight = this.ballArr[this.lightIndex].light;

      const lightArr = this.ballGroupArr[this.grouoLightIndex].arr;
      for (let i = 0; i < lightArr.length; i++) {

        if (i == lightArr.length - 1) {
          showItem(lightArr[i], 0.02, () => {
            this.initLightAnimaNew();
          }, TWEEN.Easing.Cubic.Out);
        } else {
          showItem(lightArr[i], 0.02, () => {
          }, TWEEN.Easing.Cubic.Out);
        }
      }

      // showItem(this.curLight, 0.02, () => {
      //   this.initLightAnima();
      // }, TWEEN.Easing.Cubic.Out);


      this.grouoLightIndex--;
      if (this.grouoLightIndex < 0) {
        this.grouoLightIndex = this.ballGroupArr.length - 1;
      }

      // this.lightIndex--;
      // if (this.lightIndex < 0) {
      //   this.lightIndex = this.ballArr.length - 1;
      // }
      // });
    }, delayTime * 1000);



  }




  initQuestionWindow() {

    const mask = new ShapeRect(this.ctx);
    mask.setSize(this.canvasWidth, this.canvasHeight);
    mask.fillColor = '#000000';
    mask.alpha = 0.7;
    mask.visible = false;

    this.mask = mask;



    const bg = new MySprite(this.ctx);
    bg.init(this.images.get('question_bg'));
    bg.setScaleXY(this.mapScale);
    bg.x = this.canvasWidth / 2;
    bg.y = this.canvasHeight / 2;
    mask.addChild(bg);
    this.questionBg = bg;


    const w = 1020;
    const h = 230;
    const w2 = 740;

    const labelRect1 = new ShapeRect(this.ctx);
    labelRect1.setSize(w2, h);
    labelRect1.alpha = 0;
    labelRect1.x = -bg.width / 2 + 75;
    labelRect1.y = -bg.height / 2 + 60;
    bg.addChild(labelRect1);

    const richText = new RichText(this.ctx);
    richText.text = '';
    richText.disH = 0;
    richText.fontName = 'RoundedBold';
    richText.width = w2;
    richText.x = labelRect1.x; // + labelRect1.width / 2;
    richText.y = labelRect1.y + labelRect1.height / 2 - richText.fontSize / 2;
    richText.fontSize = 48;
    bg.addChild(richText);
    this.questionLabel = richText;

    const picRect = new ShapeRect(this.ctx);
    picRect.setSize(h, h);
    picRect.alpha = 0;
    picRect.x = labelRect1.x + w - picRect.width;
    picRect.y = labelRect1.y;
    bg.addChild(picRect);
    this.questionPicRect = picRect;

    // const labelRect2 = new ShapeRect(this.ctx);
    // labelRect2.setSize(w, h);
    // labelRect2.alpha = 0.3;
    // labelRect2.x = labelRect1.x;
    // labelRect2.y = labelRect1.y;
    // bg.addChild(labelRect2);

    const richText2 = new RichText(this.ctx);
    richText2.text = '';
    richText2.disH = 0;
    richText2.fontName = 'RoundedBold';
    richText2.width = w;
    richText2.x = labelRect1.x; // + labelRect1.width / 2;
    richText2.y = labelRect1.y + labelRect1.height / 2 - richText.fontSize / 2;
    richText2.fontSize = 48;
    bg.addChild(richText2);
    this.questionLabel2 = richText2;


    const textBgH = 81;
    const disH = 5;
    const offX = labelRect1.x;
    const offY = labelRect1.y + labelRect1.height + textBgH / 2 + 15;

    this.textBgArr = [];
    this.answerLabelArr = [];
    const keyArr = ['a', 'b', 'c', 'd'];
    for (let i = 0; i < 4; i++) {
      const key = 'text_bg_' + keyArr[i];
      const textBg = new MySprite(this.ctx);
      textBg.init(this.images.get(key));
      textBg.x = offX + textBg.width / 2;
      textBg.y = offY + i * (textBgH + disH);
      bg.addChild(textBg, 2);
      this.textBgArr.push(textBg);

      const label = new Label(this.ctx);
      label.fontName = 'RoundedBold';
      label.text = 'aaaaaaaa';
      label.fontColor = '#000000';
      // label.textAlign = 'center';
      label.fontSize = 50;
      label.setMaxSize(textBg.width - 230);
      label.refreshSize();
      label.x = -textBg.width / 2 + 90;
      textBg.addChild(label);

      const rightBg = new MySprite(this.ctx);
      rightBg.init(this.images.get('text_right'));
      rightBg.x = textBg.x;
      rightBg.y = textBg.y;
      bg.addChild(rightBg, 1);
      rightBg.visible = false;
      textBg['rightBg'] = rightBg;

      const wrongBg = new MySprite(this.ctx);
      wrongBg.init(this.images.get('text_wrong'));
      wrongBg.x = textBg.x;
      wrongBg.y = textBg.y;
      bg.addChild(wrongBg, 1);
      wrongBg.visible = false;
      textBg['wrongBg'] = wrongBg;

      this.answerLabelArr.push(label);

    }


    this.picBgArr = [];
    this.answerTitleArr = [];
    const picBgW = 236;
    const disW = (w - picBgW * 4) / 3;
    for (let i = 0; i < 4; i ++) {
      const key = 'pic_bg_' + keyArr[i];
      const picBg = new MySprite(this.ctx);
      picBg.init(this.images.get(key));
      picBg.x = offX + picBg.width / 2 + i * (picBgW + disW);
      picBg.y = offY + picBg.height / 2 - textBgH / 2;
      bg.addChild(picBg);
      this.picBgArr.push(picBg);


      const rightBg = new MySprite(this.ctx);
      rightBg.init(this.images.get('pic_right'));
      rightBg.x = picBg.x;
      rightBg.y = picBg.y;
      bg.addChild(rightBg, 1);
      rightBg.visible = false;
      picBg['rightBg'] = rightBg;

      const wrongBg = new MySprite(this.ctx);
      wrongBg.init(this.images.get('pic_wrong'));
      wrongBg.x = picBg.x;
      wrongBg.y = picBg.y;
      bg.addChild(wrongBg, 1);
      wrongBg.visible = false;
      picBg['wrongBg'] = wrongBg;


      const textKey = 'text_' + keyArr[i];
      const title = new MySprite(this.ctx);
      title.init(this.images.get(textKey));
      title.x = picBg.x;
      title.y = picBg.y - picBg.height / 2 + 39;
      bg.addChild(title);
      this.answerTitleArr.push(title);

    }


    this.hideArr(this.textBgArr);



    const closeBtn = new MySprite(this.ctx);
    closeBtn.init(this.images.get('close_btn'));
    bg.addChild(closeBtn);
    closeBtn.x = bg.width / 2 - 25;
    closeBtn.y = -bg.height / 2 + 50;
    this.closeBtn = closeBtn;



  }


  initItemView() {

  }



  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;

    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;
      this.hotZoneArr.push(hotZone);
      // hotZone['audio'] = this.audioObj[data.audio_url];
      // this.imgArr.push(img);
    }


    //
    //
    // const hotZoneItemArr = this.data.contentObj.hotZoneItemArr;
    // if (!hotZoneItemArr) {
    //   return;
    // }
    //
    // if (!this.bg) {
    //   return;
    // }
    //
    // const bgRect = this.bg.getBoundingBox();
    // const bgItem = this.data.contentObj.bgItem;
    //
    // const rate = bgRect.width / bgItem.rect.width;
    //
    //
    // for (let i = 0; i < hotZoneItemArr.length; i++) {
    //
    //   const tmpData = hotZoneItemArr[i];
    //   const shapeRect = new ShapeRect(this.ctx);
    //   shapeRect.anchorX = 0;
    //   shapeRect.anchorY = 0;
    //   shapeRect.setSize(tmpData.rect.width, tmpData.rect.height);
    //   shapeRect.setScaleXY(this.bg.scaleX);
    //   shapeRect.x = (bgItem.rect.x - bgRect.x + tmpData.rect.x ) / rate;
    //   shapeRect.y = (bgItem.rect.y - bgRect.y + tmpData.rect.y ) / rate;
    //
    //   // shapeRect.x = tmpData.rect.x - this.bg.width / 2;
    //   // shapeRect.y = tmpData.rect.y - this.bg.height / 2;
    //   // this.bg.addChild(shapeRect);
    //
    //   this.renderArr.push(shapeRect);
    // }


  }



  getHotZoneItem(data) {
    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['data'] = data;

    this.renderArr.push(item);

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


    return item;
  }





  getFrameColor() {
    let arr = ['1', '2', '3'];
    if (this.oldFrameColorId) {
      removeItemFromArr(arr, this.oldFrameColorId);
    }

    arr = randomSortByArr(arr);
    const colorId = arr[0];
    this.oldFrameColorId = colorId;
    return 'frame_' + colorId;
  }

  addPic(card) {



    const curData = this.picArr[this.picIndex];

    const w = 340;
    const h = 340;
    const pic = new MySprite(this.ctx);
    pic.init(this.images.get(curData.pic_url));
    const sx = w / pic.width;
    const sy = h / pic.height;
    const s = Math.min(sx, sy);
    pic.setScaleXY(s);

    pic.x = 5;
    card.addChild(pic);

    card.data = curData;


    this.picIndex ++;
    if (this.picIndex >= this.picArr.length) {
      this.picIndex = 0;
    }
  }


  initRobot() {
    const robot = new MySprite(this.ctx);
    robot.init(this.images.get('robot'));
    robot.setScaleXY(this.mapScale);
    robot.x = this.canvasWidth / 2 - 50 * this.mapScale;
    robot.y = this.canvasHeight / 2 + 50 * this.mapScale;
    this.renderArr.push(robot);
    this.robot = robot;

    const stick = new MySprite(this.ctx);
    stick.init(this.images.get('stick'));
    stick.anchorY = 0.95;
    stick.x = robot.width / 2 + stick.width / 2 - 5;
    stick.y = -25;
    robot.addChild(stick);
    this.stick = stick;

    const ball = new MySprite(this.ctx);
    ball.init(this.images.get('ball'));
    ball.x = stick.x;
    ball.y = stick.y - stick.height;
    robot.addChild(ball);
    this.ball = ball;


    const mask = new MySprite(this.ctx);
    mask.init(this.images.get('mask'));
    mask.x = 31;
    mask.y = 2;
    robot.addChild(mask);
    this.mask = mask;

    // const w = 800;
    // const h = 260;
    // const rect = new ShapeRect(this.ctx);
    // rect.setSize(w, h);
    // rect.anchorX = 0.5;
    // rect.anchorY = 0.5;
    // mask.addChild(rect);



  }





  initBg() {

    this.bgArr = [];

    const bg = new MySprite();
    bg.init(this.images.get('bg'));
    bg.x = this.canvasWidth / 2;
    bg.y = this.canvasHeight / 2;
    const sx = this.canvasWidth / bg.width;
    const sy = this.canvasHeight / bg.height;
    const s = Math.max(sx, sy);
    bg.setScaleXY(s);
    this.renderArr.push(bg);


    this.bgLayer = new MySprite();
    this.renderArr.push(this.bgLayer);

  }

  initClock() {



    const clock1Bg = new MySprite();
    clock1Bg.init(this.images.get('clock_1_bg'));
    clock1Bg.setScaleXY(this.mapScale);
    clock1Bg.x = this.canvasWidth / 2;
    clock1Bg.y = clock1Bg.height / 2 * clock1Bg.scaleY;
    this.clock1Bg = clock1Bg;
    clock1Bg['baseX'] = clock1Bg.x;
    clock1Bg['baseY'] = clock1Bg.y;
    this.renderArr.push(clock1Bg);


    const clock1 = new MySprite();
    clock1.init(this.images.get('clock_1'));
    clock1.x = - clock1Bg.width / 4;
    clock1.y = -5;
    clock1Bg.addChild(clock1);

    const label = new Label();
    label.text = '00:00';
    label.fontColor = '#73ce24';
    label.fontSize = 32;
    label.fontName = 'BRLNSDB';
    // label.textAlign = 'center';
    label.x = -20;
    label.y = -9;
    label.setMaxSize(100);
    clock1Bg.addChild(label);
    label['data'] =
    this.timeLabel = label;



    clock1Bg.y = -clock1Bg.height / 2 * clock1Bg.scaleY;
    moveItem(clock1Bg, clock1Bg.x, clock1Bg.height / 2 * clock1Bg.scaleY, 0.5, () => {
      this.initCow();
    }, TWEEN.Easing.Cubic.Out);


  }



  cowLeave() {

    this.playAudio('happy');
    for (let i = 0; i < this.cowArr.length; i++) {
      const cow = this.cowArr[i];
      cow.happy();

      let px = cow.x - this.canvasWidth / 3 * 2;
      if (cow.x > this.canvasWidth / 2) {
        px = cow.x + this.canvasWidth / 3 * 2;
        cow.scaleX *= -1;
      };
      moveItem(cow, px, cow.y, 2, () => {

      }, TWEEN.Easing.Sinusoidal.In);
    }

    setTimeout(() => {
      this.showClock2();
    }, 2000);

    this.hideClock1();
  }

  hideClock1() {

    const clock1Bg = this.clock1Bg;
    moveItem(clock1Bg, clock1Bg.x, -clock1Bg.height / 2 * clock1Bg.scaleY, 1, () => {
      // this.showClock2();
    }, TWEEN.Easing.Cubic.In);

  }

  showClock2() {

    const clock2Bg = new MySprite();
    clock2Bg.init(this.images.get('clock_2_bg'));
    clock2Bg.setScaleXY(this.mapScale);
    clock2Bg.x = this.canvasWidth / 2;
    clock2Bg.y = -clock2Bg.height / 2 * clock2Bg.scaleY;
    this.renderArr.push(clock2Bg);

    const clock2 = new MySprite();
    clock2.init(this.images.get('clock_2'));
    clock2.setScaleXY(this.mapScale);
    clock2.x = -clock2Bg.width / 4;
    clock2.y = 130;
    clock2Bg.addChild(clock2);

    const label = new Label();
    label.text = this.timeLabel.text;
    label.fontName = 'BRLNSDB';
    label.fontSize = 64;
    label.fontColor = '#ff8300';
    label.x = -40;
    label.y = clock2.y;
    clock2Bg.addChild(label);

    this.clock2Bg = clock2Bg;



    const move1 = () => {
      moveItem(clock2Bg, clock2Bg.x, (clock2Bg.height / 2 - 160) * clock2Bg.scaleY, 1.7, () => {
        // move2();
      }, TWEEN.Easing.Elastic.Out);
    };

    // const move2 = () => {
    //   moveItem(clock2Bg, clock2Bg.x, (clock2Bg.height / 2 - 50) * clock2Bg.scaleY , 0.5, () => {
    //
    //   }, TWEEN.Easing.Cubic.In);
    // };

    move1();


    setTimeout(() => {
      this.showRestartBtn();
    }, 300);
  }


  showRestartBtn() {

    const btn = new MySprite();
    btn.init(this.images.get('btn_restart'));
    btn.setScaleXY(this.mapScale);
    btn.x = this.canvasWidth + btn.width / 2 * btn.scaleX;
    btn.y = this.canvasHeight - btn.height / 2 * btn.scaleY;
    this.renderArr.push(btn);

    btn.visible = true;
    moveItem(btn, this.canvasWidth - (btn.width / 2 + 50) * btn.scaleX, btn.y, 0.5, () => {
      this.canTouch = true
    }, TWEEN.Easing.Cubic.Out);

    this.restartBtn = btn;
  }








  initStartPage() {

    this.starArr = [];

    const maskLayer = new ShapeRect(this.ctx);
    maskLayer.init(this.images.get(''));
    maskLayer.setSize(this.canvasWidth, this.canvasHeight);
    maskLayer.x = this.canvasWidth / 2;
    maskLayer.y = this.canvasHeight / 2;
    maskLayer.fillColor = '#000000';
    maskLayer.alpha = 0.8;
    this.startPageArr.push(maskLayer);

    const startBtn = new MySprite(this.ctx);
    startBtn.init(this.images.get('start_btn'));
    startBtn.x = this.canvasWidth / 2;
    startBtn.y = this.canvasHeight / 5 * 3;
    startBtn.setScaleXY(this.mapScale);
    this.startPageArr.push(startBtn);
    this.startBtn = startBtn;
  }


  initEndPage() {


    const maskLayer = new ShapeRect(this.ctx);
    maskLayer.init(this.images.get(''));
    maskLayer.setSize(this.canvasWidth, this.canvasHeight);
    maskLayer.x = this.canvasWidth / 2;
    maskLayer.y = this.canvasHeight / 2;
    maskLayer.fillColor = '#000000';
    maskLayer.alpha = 0.8;
    this.endPageArr.push(maskLayer);

    const leftWin = new MySprite(this.ctx);
    leftWin.init(this.images.get('left_win'));
    leftWin.x = this.canvasWidth / 2;
    leftWin.y = this.canvasHeight / 2.5;
    leftWin.setScaleXY(this.mapScale);
    this.endPageArr.push(leftWin);


    const rightWin = new MySprite(this.ctx);
    rightWin.init(this.images.get('right_win'));
    rightWin.x = this.canvasWidth / 2;
    rightWin.y = this.canvasHeight / 2.5;
    rightWin.setScaleXY(this.mapScale);
    this.endPageArr.push(rightWin);

    this.leftWin = leftWin;
    this.rightWin = rightWin;

    // const light = new MySprite(this.ctx);
    // light.init(this.images.get('light_png'));
    // light.x = this.canvasWidth / 2;
    // light.y = this.canvasHeight / 5 * 2;
    // light.setScaleXY(this.mapScale);
    // this.endPageArr.push(light);
    // this.light = light;
    //
    // const hand = new MySprite(this.ctx);
    // hand.init(this.images.get('hand_png'));
    // hand.x = this.canvasWidth / 2;
    // hand.y = light.y;
    // hand.setScaleXY(this.mapScale);
    // this.endPageArr.push(hand);
    // this.hand = hand;

    const replayBtn = new MySprite(this.ctx);
    replayBtn.init(this.images.get('replay_btn'));
    replayBtn.x = this.canvasWidth / 2;
    replayBtn.y = this.canvasHeight / 5 * 3.5;
    replayBtn.setScaleXY(this.mapScale);
    this.endPageArr.push(replayBtn);
    this.replayBtn = replayBtn;


    this.hideArr(this.endPageArr);

    // const lightAction = () => {
    //   light.rotation = 0;
    //   rotateItem(light, 360, 10, () => {
    //     lightAction();
    //   });
    // };
    //
    // lightAction();

  }


  initScore() {


    const addLabelShadow = (label) => {

      const labelShadow = new Label(this.ctx);
      labelShadow.init();
      labelShadow.text = label.text;
      labelShadow.fontSize = label.fontSize;
      labelShadow.fontName = label.fontName;
      labelShadow.fontColor = '#e4688f';
      labelShadow.textAlign = 'center';
      labelShadow.y = 3;
      labelShadow.setShadow(0, 2, 2, 'rgba(154, 23, 58, 0.5)');
      label.addChild(labelShadow, -1);
      label.shadowLabel = labelShadow;

    };

    const labelLeft = new Label(this.ctx);
    labelLeft.init();
    labelLeft.text = '0';
    labelLeft.fontSize = 60;
    labelLeft.fontName = 'BRLNSDB';
    labelLeft.fontColor = '#fef9ff';
    labelLeft.textAlign = 'center';

    labelLeft.x = - this.bgTop.width / 4;
    labelLeft.y = this.bgTop.height / 5;

    labelLeft.refreshSize();

    addLabelShadow(labelLeft);

    this.bgTop.addChild(labelLeft);
    this.leftScoreLabel = labelLeft;




    const labelRight = new Label(this.ctx);
    labelRight.init();
    labelRight.text = '0';
    labelRight.fontSize = 60;
    labelRight.fontName = 'BRLNSDB';
    labelRight.fontColor = '#fef9ff';
    labelRight.textAlign = 'center';

    labelRight.x = this.bgTop.width / 4;
    labelRight.y = this.bgTop.height / 5;

    labelRight.refreshSize();

    addLabelShadow(labelRight);

    this.bgTop.addChild(labelRight);

    this.rightScoreLabel = labelRight;


    // console.log('label.width: ', label.width);
  }







  showEndPage() {

    this.showArr(this.endPageArr);
    this.canTouch = true;
    this.gameEndFlag = true;

    this.showEndPatal();

    this.successAudio.play();

    if (this.leftScore >= this.maxScore) {
      this.rightWin.visible = false;
    } else {
      this.leftWin.visible = false;
    }
  }


  showEndPatal() {

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

  }



  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();
    }, 200);

    // this.petalTime +=  5;
  }


  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 = 2 + Math.random() * 5;
    petal['time'] = randomT;

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

    return petal;
  }


  gameEnd() {
    // this.showEndPage();
    this.cowLeave();
    this.clockUpdateFlag = false;

    console.log('gameEnd');

    // this.canTouch = true;
    this.petalTime = 0;

    // this.playAudio('finish');

    this.showEndPatal();

    // setTimeout(() => {
    //   this.showPetalFlag = false;
    // }, 5000);
  }




  mapDown(event) {


    if (!this.canTouch) {
      return;
    }


    if (this.checkClickTarget(this.leftBtn)) {
      this.lastPageClick();
      return;
    }

    if (this.checkClickTarget(this.rightBtn)) {
      this.nextPageClick();
      return;
    }


  }





  mapMove(event) {

  }


  mapUp(event) {


  }



  nextPageClick() {
    console.log(' in leftBtnClick');

    if (this.curPageIndex >= this.picArr.length - 1) {
      return;
    }

    this.curPageIndex ++;

    this.changePageByIndex();
  }

  lastPageClick() {

    console.log(' in rightBtnClick');


    if (this.curPageIndex <= 0) {
      return;
    }

    this.curPageIndex --;

    this.changePageByIndex();

  }


  changePageByIndex() {

    console.log(' in changePageByIndex');
    this.canTouch = false;

    if (this.curAudio) {
      this.curAudio.pause();
      this.curAudio.currentTime = 0;
    }
    // this.changePlayBtnStyle(this.BTN_TYPE_PLAY);

    moveItem(this.bgLayer, -this.curPageIndex * this.canvasWidth, 0, 1, () => {
      this.canTouch = true;
      this.refreshPageLabel();
      // this.resetCurData();
    }, TWEEN.Easing.Cubic.Out);


    this.playAudio('click', true);
  }



  checkOnCow() {


    const arr = [];
    for (let i = 0; i < this.cowArr.length; i++) {
      if (this.checkPointInRect(this.mx, this.my, this.cowArr[i].getBoundingBox())) {
        arr.push({
          dis: getPosDistance(this.mx, this.my, this.cowArr[i].x, this.cowArr[i].y),
          item: this.cowArr[i]
        });
      }
    }

    if (arr[0]) {
      this.checkCowEat(arr[0].item);
    } else {
      this.grassResetPos();
    }

    // if (arr.length > 0) {
    //
    //   arr.sort((a, b) => {
    //     return b.dis - a.dis;
    //   });
    // }

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


  grassResetPos() {
    if (this.curGrass) {

      this.canTouch = false;

      moveItem(this.curGrass, this.curGrass.baseX, this.curGrass.baseY, 0.3, () => {
        this.canTouch = true;
      }, TWEEN.Easing.Cubic.Out);

      // this.curGrass.x = this.curGrass.baseX;
      // this.curGrass.y = this.curGrass.baseY;
    }
  }

  checkCowEat(cow) {

    console.log('eat');
    if (Number(this.curGrass.type) == Number(cow.id)) {

      this.playAudio('eat', true);
      cow.eat();

      removeItemFromArr(this.grassArr, this.curGrass);
      removeItemFromArr(this.renderArr, this.curGrass);

      this.checkGameEnd();

      this.curGrass = null;

    } else {

      this.playAudio('angry');
      cow.angry();

      this.grassResetPos();
    }
  }


  checkCowEatClick(cow) {

    console.log(' in checkCowEatClick');
    this.curCow = cow;


    if (Number(this.curGrass.type) == Number(cow.id)) {
      cow.like();
    } else {

      this.playAudio('angry');
      cow.angry();
    }

    this.canTouch = false;
    moveItem(this.curGrass, cow.x + cow.offX, cow.y + cow.offY, 0.3, () => {

      this.canTouch = true;

      if (Number(this.curGrass.type) == Number(cow.id)) {

        this.playAudio('eat', true);

        cow.eat();
        removeItemFromArr(this.grassArr, this.curGrass);
        removeItemFromArr(this.renderArr, this.curGrass);
        this.checkGameEnd();

        this.curGrass = null;

      } else {

        this.grassResetPos();

      }

    }, TWEEN.Easing.Cubic.Out);


  }


  clickGrass(grass) {

    console.log('in click grass data', grass.data);

    grass.light.visible = true;

    this.curGrass = grass;

    if (grass.data.audio_url) {
      this.playAudio(grass.data.audio_url);
    } else {
      this.playAudio('grass');
    }

    removeItemFromArr(this.renderArr, grass);
    this.renderArr.push(grass);
  }


  checkGameEnd() {

    if (this.grassArr.length > 0) {
      return;
    }

    this.canTouch = false;

    setTimeout(() => {

      this.gameEnd();

    }, 2000);
  }


  clickRestart() {

    const clock2Bg = this.clock2Bg;

    const move1 = () => {

      moveItem(clock2Bg, clock2Bg.x, clock2Bg.height / 3 * 2 / 2 * clock2Bg.scaleY, 0.4, () => {
        move2();
      }, TWEEN.Easing.Quadratic.InOut);

    };


    const move2 = () => {
      moveItem(clock2Bg, clock2Bg.x, -clock2Bg.height / 2 * clock2Bg.scaleY, 0.8, () => {

        this.restartBtn.visible = false;

        this.init();
      }, TWEEN.Easing.Quadratic.InOut);
    };

    move1();


    moveItem(this.restartBtn, this.canvasWidth + this.restartBtn.width / 2 * this.restartBtn.scaleX,
      this.restartBtn.y, 0.6, () => {

      }, TWEEN.Easing.Quadratic.Out);


    this.showPetalFlag = false;

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

      hideItem(this.endPageArr[i], 0.8);

    }
  }








  updateClock() {

    if (!this.clockUpdateFlag) {
      return;
    }

    const curDate = new Date();
    const oldDate = this.timeLabel.date;
    curDate.setTime(curDate.getTime() - oldDate.getTime());

    const time = formatTime('mm:ss', curDate);
    this.timeLabel.text = time;
  }


  update() {


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


    TWEEN.update();


    // this.updateWordArr();

    // this.updateArr(this.bgArr);
    this.updateArr(this.renderArr);
    // this.updateArr(this.endPageArr);

    // this.updateClock();



  }


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

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





  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.canvasLeft;
      this.my = event.touches[0].pageY - this.canvasTop;
    };

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



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



      // if (this.IsPC()) {
      //
      //   this.canvas.nativeElement.addEventListener('mousedown', (event) => {
      //
      //     setMxMyByMouse(event);
      //     this.mapDown(event);
      //   });
      //
      //   this.canvas.nativeElement.addEventListener('mousemove', (event) => {
      //
      //     setMxMyByMouse(event);
      //     this.mapMove(event);
      //   });
      //
      //   this.canvas.nativeElement.addEventListener('mouseup', (event) => {
      //
      //     setMxMyByMouse(event);
      //     this.mapUp(event);
      //   });
      //
      //
      //   const setMxMyByMouse = (event) => {
      //
      //     this.mx = event.offsetX;
      //     this.my = event.offsetY;
      //   };
      //
      //
      //
      // } else {
      //
      //   this.canvas.nativeElement.addEventListener('touchstart', (event) => {
      //
      //     setMxMyByTouch(event);
      //     this.mapDown(event);
      //   });
      //
      //   this.canvas.nativeElement.addEventListener('touchmove', (event) => {
      //     setMxMyByTouch(event);
      //     this.mapMove(event);
      //   });
      //
      //   this.canvas.nativeElement.addEventListener('touchend', (event) => {
      //     setMxMyByTouch(event);
      //     this.mapUp(event);
      //   });
      //
      //   this.canvas.nativeElement.addEventListener('touchcancel', (event) => {
      //     setMxMyByTouch(event);
      //     this.mapUp(event);
      //   });
      //
      //
      //   const setMxMyByTouch = (event) => {
      //
      //     // console.log('in setMxMyByTouch', event);
      //     if (event.touches.length <= 0) {
      //       return;
      //     }
      //
      //     if (this.canvasLeft == null) {
      //       setParentOffset();
      //     }
      //
      //     this.mx = event.touches[0].pageX - this.canvasLeft;
      //     this.my = event.touches[0].pageY - this.canvasTop;
      //   };
      //
      //
      //   const setParentOffset = () => {
      //
      //     const rect = this.canvas.nativeElement.getBoundingClientRect();
      //     this.canvasLeft = rect.left;
      //     this.canvasTop = rect.top;
      //   };
      // }



  }


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

    const audio = this.audioObj[key];
    if (audio) {
      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();
      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();

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

}
