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, bezierMove, shake
} from './Unit';
import res 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';


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

  // 声音

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

  closeAnimaAudio = new Audio();
  openAnimaAudio = new Audio();
  handAnimaAudio = new Audio();
  showBtnAudio = new Audio();
  clickAudio = new Audio();


  images = new Map();

  animationId: any;
  winResizeEventStream = new Subject();


  audioObj = {};
  renderArr;
  mapScale = 1;

  canvasLeft;
  canvasTop;


  canTouch = true;

  // -----
  KEY = 'dfzx_09';
  picArr;
  frameArr;
  cardArr;
  soundPlay;
  soundReplay;
  answerIdArr;
  answerIdIndex;
  iconIndex = 1;
  curCard;
  restartBtn;
  startBtn;
  hand1;
  hand2;
  clappingTimes = 0;
  posArr;


  itemBgArr;
  holePosArr = [
    [205.93, 141.49],
    [473.53, 191.69],
    [764.64, 191.51],
    [1080.43, 139.11],
  ];
  ball;
  indexArr;
  lightPosArr = [
    [188.93, 137.49],
    [465.53, 187.69],
    [775.64, 187.51],
    [1085.43, 136.11],
  ];
  light;
  curShape;
  picPosArr = [
    [-480.73, -138.63],
    [-173.3, -209.01],
    [136.04, -208.98],
    [476.12, -137.46],
  ];
  bottom;



  hotZoneArr;
  picRect;
  closeBtn;
  itemBg;
  curSong;



  oldFrameColorId;
  bottomCard;


  picW = 800;
  picH = 260;
  mask;
  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;


  starArr;

  wand;

  replayBtn;
  endPageArr;
  gameEndFlag;
  showPetalFlag;
  bg;

  delayPicSoundShowTime = 700;



  // @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() {


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

      const picArr = [];
      picArr.push({
        pic_url: 'assets/default/item.png',
        audio_url: 'assets/default/audio1.mp3'
      });
      picArr.push({
        pic_url: 'assets/default/item.png',
        audio_url: 'assets/default/audio2.mp3'
      });
      picArr.push({
        pic_url: 'assets/default/item.png',
        audio_url: 'assets/default/audio3.mp3'
      });
      picArr.push({
        pic_url: 'assets/default/item.png',
        audio_url: 'assets/default/audio4.mp3'
      });

      this.data.contentObj.picArr = picArr;

    }


  }

  ngOnDestroy() {
    window.cancelAnimationFrame(this.animationId);
    this.bgAudio.pause();
    this.gameEndFlag = true;
  }

  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.renderArr = [];

    if (!this.data.contentObj.picArr) {
      this.data.contentObj.picArr = [];
    }
    this.picArr = this.data.contentObj.picArr;
    //
    // // this.picArr = randomSortByArr(this.picArr);
    // this.picIndex = 0;
    //


  }





  initAudio() {

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

    const picArr = contentObj.picArr;

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


    // const addAudio = (key) => {
    //   const audioUrl = contentObj[key];
    //   if (audioUrl) {
    //     const audio = new Audio();
    //     audio.src = audioUrl;
    //     audio.load();
    //     this.audioObj[key] = audio;
    //   }
    // }
    //
   
    //
    // addAudio('audio_url');
    //


    const addUrlToAudioObj = (audioUrl) => {

      if (audioUrl) {

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

    };


    const arr = contentObj.picArr;

    if (arr) {
      for (let i = 0; i < arr.length; i++) {
        addUrlToAudioObj(arr[i].audio_url);
      }
    }









    //
    // 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/play/music/wrong.mp3';
    this.wrongAudio.load();

    // this.rightAudio.src = 'assets/common/music/right.mp3';
    // this.rightAudio.load();

    this.successAudio.src = 'assets/play/music/success.mp3';
    this.successAudio.load();

    this.closeAnimaAudio.src = 'assets/play/music/close_anima.mp3';
    this.closeAnimaAudio.load();

    this.openAnimaAudio.src = 'assets/play/music/open_anima.mp3';
    this.openAnimaAudio.load();

    this.handAnimaAudio.src = 'assets/play/music/hand.mp3';
    this.handAnimaAudio.load();

    this.showBtnAudio.src = 'assets/play/music/show_btn.mp3';
    this.showBtnAudio.load();


    this.clickAudio.src = 'assets/play/music/click.mp3';
    this.clickAudio.load();
    //
    // this.successAudio.onended = () => {
    //   // this.showSuccessAudio();
    // };
    //
    //
    //

  }

  initImg() {

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


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


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

        for (let i = 0; i < arr.length; i++) {
          addPicUrl(arr[i].pic_url);
          // const picUrl = arr[i].pic_url;
          // if (picUrl) {
          //   this.rawImages.set(picUrl, picUrl);
          // }
        }
      }

    }


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



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


  initView() {

    this.initBg();

    this.initCard();

    this.initSound();

    this.initMask();

    this.initHand();

    this.randomAnswerIdArr();

   
    // this.initBall();
    //
    // this.initLight();
    //
    // this.initPic();


  }

  initHand() {


    const sOffX = 110 * this.mapScale;
    const sOffY = 50 * this.mapScale;
    const eOffX = 20 * this.mapScale;
    const eOffY = 10 + this.mapScale;

    const hand1 = new MySprite(this.ctx);
    hand1.init(this.images.get('hand_1'));
    hand1.setScaleXY(this.mapScale);
    hand1.x = this.canvasWidth / 2;
    hand1.y = this.canvasHeight / 2 + 60 * this.mapScale;
    this.hand1 = hand1;
    hand1['startX'] = hand1.x - sOffX;
    hand1['startY'] = hand1.y - sOffY;


    const hand2 = new MySprite(this.ctx);
    hand2.init(this.images.get('hand_2'));
    hand2.setScaleXY(this.mapScale);
    hand2.x = hand1.x;
    hand2.y = hand1.y;
    this.hand2 = hand2;
    hand2['startX'] = hand2.x + sOffX;
    hand2['startY'] = hand2.y + sOffY;


    hand1['endX'] = hand1.x - eOffX;
    hand1['endY'] = hand1.y - eOffY;
    hand2['endX'] = hand2.x + eOffX;
    hand2['endY'] = hand2.y + eOffY;

    // hand1.x = hand1['endX'];
    // hand1.y = hand1['endY'];
    // hand2.x = hand2['endX'];
    // hand2.y = hand2['endY'];

    hand1.visible = false;
    hand2.visible = false;
    // this.showHand();
  }


  randomAnswerIdArr() {
    if (!this.answerIdArr) {
      this.answerIdArr = [0, 1, 2, 3];
    }

    this.answerIdArr = randomSortByArr(this.answerIdArr);

  }


  initCard() {

    // const arr = this.frameArr;

    this.posArr = [];
    let idArr = [1, 2, 3, 4];
    idArr = randomSortByArr(idArr);
    this.cardArr = [];
    for (let i = 0; i < 4; i ++) {

      const frame = this.frameArr[i];

      const card = new MySprite(this.ctx);
      card.init(this.images.get('card_' + idArr[i]));
      card.setScaleXY(this.mapScale);
      card.x = frame.x;
      card.y = this.canvasHeight / 2 + (this.canvasHeight / 2 - frame.y) - 30 * this.mapScale;
      this.addPic(card, i);

      card['baseX'] = card.x;
      card['baseY'] = card.y;
      this.renderArr.push(card);
      this.cardArr.push(card);

      card.x = this.canvasWidth / 2;

      this.posArr.push({x: card['baseX'], y: card['baseY']});
    }

  }



  initSound() {

    const offX = 20 * this.mapScale;
    const offY = 10 * this.mapScale;

    const soundPlay = new MySprite(this.ctx);
    soundPlay.init(this.images.get('sound_play'));
    soundPlay.setScaleXY(this.mapScale);
    soundPlay.x = this.canvasWidth - soundPlay.width / 2 * soundPlay.scaleX - offX;
    soundPlay.y = this.canvasHeight - soundPlay.height / 2 * soundPlay.scaleY - offY;
    this.renderArr.push(soundPlay);
    this.soundPlay = soundPlay;


    const soundReplay = new MySprite(this.ctx);
    soundReplay.init(this.images.get('sound_replay'));
    soundReplay.setScaleXY(this.mapScale);
    soundReplay.x = soundPlay.x;
    soundReplay.y = soundPlay.y;
    this.renderArr.push(soundReplay);
    this.soundReplay = soundReplay;
    soundReplay.visible = false;
  }

  initMask() {

    this.endPageArr = [];

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


    const startBtn = new MySprite(this.ctx);
    startBtn.init(this.images.get('btn_play'));
    startBtn.setScaleXY(this.mapScale);
    startBtn.x = this.canvasWidth / 2;
    startBtn.y = this.canvasHeight / 2;
    mask.addChild(startBtn);
    // startBtn.visible = false;

    this.startBtn = startBtn;


    const restartBtn = new MySprite(this.ctx);
    restartBtn.init(this.images.get('btn_replay'));
    restartBtn.setScaleXY(this.mapScale);
    restartBtn.x = this.canvasWidth / 2;
    restartBtn.y = this.canvasHeight / 2 + 80 * this.mapScale;
    mask.addChild(restartBtn);
    restartBtn.visible = false;

    this.restartBtn = restartBtn;



  }



  initLight() {

    const light = new MySprite(this.ctx);
    light.init(this.images.get('light'), 0.5, 1);
    light.setScaleXY(this.mapScale * 1.1);
    light.visible = false;
    this.renderArr.push(light);
    this.light = light;
  }




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





  // initCard() {
  //
  //   const card = new MySprite(this.ctx);
  //   card.init(this.images.get(this.getFrameColor()));
  //   card.setScaleXY(this.mapScale);
  //   card.x = this.canvasWidth / 2;
  //   card.y = this.canvasHeight / 2;
  //   this.addPic(card);
  //
  //   this.renderArr.push(card);
  //
  //   this.curCard = card;
  //
  //   this.addBottomCard();
  //
  // }

  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, index) {


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

    const w = 180;
    const h = 180;
    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.id = index;
    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(this.ctx);
    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.bgArr.push(bg);
    this.bg = bg;


    const len = 217 * this.mapScale;
    const disW = 50 * this.mapScale;
    const offX = this.canvasWidth / 2 - (len * 4 + disW * 3) / 2 + len / 2;


    this.frameArr = [];
    for (let i = 0; i < 4; i++) {
      const frame = new MySprite(this.ctx);
      frame.init(this.images.get('frame_' + (i + 1)));
      frame.setScaleXY(this.mapScale);
      frame.x = offX + (len + disW) * i;
      frame.y = this.canvasHeight / 2 - len / 1.2;
      this.renderArr.push(frame);
      this.frameArr.push(frame);
    }



  }


  initBall() {

    const ball = new MySprite(this.ctx);
    ball.init(this.images.get('ball'), 0.5, 1);
    ball.setScaleXY(this.mapScale);
    ball.x = this.canvasWidth / 2;
    ball.y = this.canvasHeight - 10 * this.mapScale;
    this.renderArr.push(ball);
    ball['baseX'] = ball.x;
    ball['baseY'] = ball.y;

    const shadow = new MySprite(this.ctx);
    shadow.init(this.images.get('shadow'));
    ball.addChild(shadow, -1);
    ball['shadow'] = shadow;

    this.ball = ball;


    this.canTouch = false;

    const time = 0.3;
    ball.y = this.canvasHeight + ball.height * ball.scaleY;
    moveItem(ball, ball.x, ball['baseY'], time, () => {
      this.canTouch = true;
    });

    ball.setScaleXY(this.mapScale * 1.05);
    scaleItem(ball, this.mapScale, time);



    // const index = 1;
    // ball.x = this.holePosArr[index][0] * this.mapScale;
    // ball.y = this.holePosArr[index][1] * this.mapScale;
  }





  resetArm() {
    this.arm1.page1.removeChildren();
    this.arm1.page2.removeChildren();
    this.arm2.page1.removeChildren();
    this.arm2.page2.removeChildren();

    this.arm1.x = this.arm1.baseX;
    this.arm1.y = this.arm1.baseY;

    this.arm2.x = this.arm2.baseX;
    this.arm2.y = this.arm2.baseY;

    this.arm1.page1.visible = true;
    this.arm2.page1.visible = true;
    this.arm1.page2.visible = false;
    this.arm2.page2.visible = false;


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

      this.picArr = randomSortByArr(this.picArr);
    }

    this.setPagePoint();
    this.initPic();
  }

  initPic() {

    const w = 180;
    const h = 180;

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

      // const shapeRect = new ShapeRect(this.ctx);
      // shapeRect.setSize(w, h);
      // shapeRect.alpha = 0.5;
      // this.bottom.addChild(shapeRect);
      // // this.curShape = shapeRect;
      //
      // shapeRect.anchorX = 0.5;
      // shapeRect.anchorY = 0.5;
      // shapeRect.x = pos[0];
      // shapeRect.y = pos[1] - this.bg.height / 2;


      const pic = new MySprite(this.ctx);
      const picUrl = this.picArr[i].pic_url;
      pic.init(this.images.get(picUrl));
      const sx = w / pic.width;
      const sy = h / pic.height;
      const s = Math.min(sx, sy);
      pic.setScaleXY(s);
      pic.x = pos[0];
      pic.y = pos[1] - this.bg.height / 2;
      this.bottom.addChild(pic);

    }


    // const shapeRect = new ShapeRect(this.ctx);
    // // shapeRect.setScaleXY(this.mapScale);
    // shapeRect.setSize(w, h);
    // shapeRect.anchorX = 0.5;
    // shapeRect.anchorY = 0.5;
    // shapeRect.alpha = 0.5;
    // this.bg.addChild(shapeRect);
    // // this.renderArr.push(shapeRect);
    // this.curShape = shapeRect;

    // const itemBgArr = this.itemBgArr;
    // // console.log('picArr:', this.picArr);
    // for (let i = 0; i < itemBgArr.length; i++) {
    //
    //   const itemBg = itemBgArr[i];
    //
    //   const picData = this.picArr[i];
    //   if (picData) {
    //     const picUrl = picData.pic_url;
    //     // console.log('pirUrl: ', picUrl);
    //     const pic = new MySprite(this.ctx);
    //     pic.init(this.images.get(picUrl));
    //     const sx = w / pic.width;
    //     const sy = h / pic.height;
    //     const s = Math.min(sx, sy);
    //     pic.setScaleXY(s);
    //     pic.x = -1;
    //     pic.y = -9;
    //     itemBg.addChild(pic);
    //     itemBg['pic'] = pic;
    //   }
    //
    //
    //   const iconKey = 'icon_' + (i + 1);
    //   const icon = new MySprite(this.ctx);
    //   icon.init(this.images.get(iconKey));
    //   icon.x = - itemBg.width / 2 + 40;
    //   icon.y = - itemBg.height / 2 + 40;
    //   itemBg.addChild(icon);
    //
    // }



  }




  initArm() {


    const pageOffX = this.pageOffX;

    const arm1 = new MySprite(this.ctx);
    arm1.init(this.images.get('arm_1_1'), 0, 1);
    arm1.setScaleXY(this.mapScale);
    arm1.x = - arm1.width * arm1.scaleX - this.pageW / 2 * this.mapScale;
    arm1.y = this.canvasHeight + 60 * this.mapScale;
    this.renderArr.push(arm1);

    const page1 = new MySprite(this.ctx);
    page1.init(this.images.get('page_1'), 0);
    page1.x = arm1.width - pageOffX;
    page1.y = - arm1.height + 80;
    arm1.addChild(page1);

    page1.alpha = 1;




    const page1_2 = new MySprite(this.ctx);
    page1_2.init(this.images.get('page_1_2'), 0);
    page1_2.x = page1.x;
    page1_2.y = page1.y;
    page1_2.visible = false;
    arm1.addChild(page1_2);

    arm1['page1'] = page1;
    arm1['page2'] = page1_2;

    arm1['baseX'] = arm1.x;
    arm1['baseY'] = arm1.y;


    const finger = new MySprite(this.ctx);
    finger.init(this.images.get('finger_1_1'), 0, 1);
    arm1.addChild(finger);




    const arm2 = new MySprite(this.ctx);
    arm2.init(this.images.get('arm_2_1'), 1, 1);
    arm2.setScaleXY(this.mapScale);
    arm2.x = this.canvasWidth + arm2.width * arm2.scaleX + this.pageW / 2 * this.mapScale;
    arm2.y = arm1.y;
    this.renderArr.push(arm2);

    const page2 = new MySprite(this.ctx);
    page2.init(this.images.get('page_2'), 1);
    page2.x = -arm2.width + pageOffX;
    page2.y = - arm2.height + 80;
    page2.alpha = 1;
    arm2.addChild(page2);


    const page2_2 = new MySprite(this.ctx);
    page2_2.init(this.images.get('page_2_2'), 1);
    page2_2.x = page2.x;
    page2_2.y = page2.y;
    page2_2.visible = false;
    arm2.addChild(page2_2);

    arm2['baseX'] = arm2.x;
    arm2['baseY'] = arm2.y;

    arm2['page1'] = page2;
    arm2['page2'] = page2_2;


    const finger2 = new MySprite(this.ctx);
    finger2.init(this.images.get('finger_2_1'), 1, 1);
    arm2.addChild(finger2);

    const offX = this.canvasWidth / 2 - this.pageW / 2 * this.mapScale;
    const tx = offX - (arm1.width) * arm1.scaleX + pageOffX * arm1.scaleX;




    // moveItem(arm1, tx, arm1.y);
    //
    // moveItem(arm2, this.canvasWidth - tx, arm2.y);



    this.page1 = page1;
    this.page2 = page2;
    this.arm1 = arm1;
    this.arm2 = arm2;








  }


  setPagePoint() {

    const page1 = this.page1;
    const page2 = this.page2;

    const curData = this.picArr[this.picIndex];
    console.log('this.picArr: ', this.picArr);
    console.log('curData: ', curData);

    if (!curData) {
      return;
    }

    const wordArr1 = curData.wordArr_1;
    const wordArr2 = curData.wordArr_2;


    const centerW = 60;
    const edge = 20;
    const maxW = page1.width - (centerW + edge * 2);

    let num = wordArr1.length;
    let disW = 20;
    let circleW = 68;

    let totalW = edge * 2 + circleW * num + disW * (num - 1);
    let s = 1;
    if (totalW >= maxW) {
      s = maxW / totalW;
      totalW = maxW;
    }

    disW *= s;
    circleW *= s;

    let offX = (maxW - totalW) / 2 + edge + circleW / 2;







    // const disW = (w - circleW * 3) / 4;
    // const offX = disW + circleW / 2;

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

      const tmpData = wordArr1[i];

      let color = 'green';
      if (tmpData.color) {
        color = tmpData.color;
      }
      const point = new MySprite(this.ctx);
      const key = 'point_' + color;
      point.init(this.images.get(key));
      point.setScaleXY(s);
      point.x = offX + i * (circleW + disW);
      page1.addChild(point);

    }




    num = wordArr2.length;
    disW = 20;
    circleW = 68;

    totalW = edge * 2 + circleW * num + disW * (num - 1);
    s = 1;
    if (totalW >= maxW) {
      s = maxW / totalW;
      totalW = maxW;
    }

    disW *= s;
    circleW *= s;

    offX = (maxW - totalW) / 2 + edge + circleW / 2;

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

      const tmpData = wordArr2[i];
      let color = 'green';
      if (tmpData.color) {
        color = tmpData.color;
      }
      const point = new MySprite(this.ctx);
      const key = 'point_' + color;
      point.init(this.images.get(key));
      point.setScaleXY(s);
      point.x = (offX + centerW - page2.width) + i * (circleW + disW);
      page2.addChild(point);
    }

  }


  initCenterPage() {

    this.centerPageArr = [];



    const offX = this.canvasWidth / 2 - this.pageW / 2 * this.mapScale;
    const tx = offX - (this.arm1.width) * this.arm1.scaleX + this.pageOffX * this.arm1.scaleX;

    const arm1_2 = new MySprite(this.ctx);
    arm1_2.init(this.images.get('arm_1_2'), 0, 1);
    arm1_2.setScaleXY(this.mapScale);
    arm1_2.x = tx;
    arm1_2.y = this.arm1.y;
    // arm1_2.visible = false;
    this.centerPageArr.push(arm1_2);

    const finger = new MySprite(this.ctx);
    finger.init(this.images.get('finger_1_2'), 0, 1);
    arm1_2.addChild(finger, -2);



    const arm2_2 = new MySprite(this.ctx);
    arm2_2.init(this.images.get('arm_2_2'), 1, 1);
    arm2_2.setScaleXY(this.mapScale);
    arm2_2.x = this.canvasWidth - tx;
    arm2_2.y = this.arm2.y;
    // arm2_2.visible = false;
    this.centerPageArr.push(arm2_2);

    const finger2 = new MySprite(this.ctx);
    finger2.init(this.images.get('finger_2_2'), 1, 1);
    arm2_2.addChild(finger2, -2);


    const centerPage = new MySprite(this.ctx);
    centerPage.init(this.images.get('center_page'), 0);
    centerPage.x = this.page1.x;
    centerPage.y = this.page1.y;
    arm1_2.addChild(centerPage, -1);


    this.hideArr(this.centerPageArr);
    // this.hideArr(this.centerPageArr);

  }








  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.showPetalFlag = true;
    this.addPetal();

  }

  addPetal() {

    if (!this.showPetalFlag) {
      return;
    }

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

    const randomLen = 20 * this.mapScale;
    moveItem(petal, petal.x + Math.random() * randomLen - randomLen / 2,
      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 = 3 + 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.canTouch = false;

    this.mask.visible = true;
    this.mask.alpha = 0;
    this.restartBtn.visible = false;

    tweenChange(this.mask, {alpha: this.mask.baseAlpha}, 0.5, null, TWEEN.Easing.Cubic.Out);

    this.showEndPatal();
    this.showHand();

    (<any> window).courseware.sendEvent('gameEnd');
    console.log('send gameEnd event')

    hideItem(this.soundReplay, 0.3, () => {
      this.soundReplay.alpha = 1;
      this.soundReplay.visible = false;
    });

    hideItem(this.soundPlay, 0.3, () => {
      this.soundPlay.alpha = 1;
      this.soundPlay.visible = false;
    });


    // this.showEndPage();
  }


  showHand() {

    this.handAnimaAudio.play();

    this.hand1.x = this.hand1.startX;
    this.hand1.y = this.hand1.startY;

    this.hand2.x = this.hand2.startX;
    this.hand2.y = this.hand2.startY;

    this.hand1.visible = true;
    this.hand2.visible = true;

    this.hand1.alpha = 0;
    this.hand2.aloha = 0;
    this.clappingTimes = 0;

    showItem(this.hand1, 0.2);
    showItem(this.hand2, 0.2, () => {
      // this.handClose();
    });

    this.handClose();
  }

  handOpen() {

    const hand1 = this.hand1;
    const hand2 = this.hand2;
    const time = 0.13;

    if (this.clappingTimes >= 11) {
      hideItem(hand1, time);
      hideItem(hand2, time);
    }

    moveItem(hand1, hand1.startX, hand1.startY, time, null, TWEEN.Easing.Sinusoidal.Out);
    moveItem(hand2, hand2.startX, hand2.startY, time, () => {
      this.handClose();
    }, TWEEN.Easing.Sinusoidal.Out);



  }

  handClose() {

    console.log(' in handClose');

    if (this.clappingTimes >= 11) {
      this.showRestartBtn();
      return;
    }

    const hand1 = this.hand1;
    const hand2 = this.hand2;
    const time = 0.13;

    moveItem(hand1, hand1.endX, hand1.endY, time, null, TWEEN.Easing.Sinusoidal.In);
    moveItem(hand2, hand2.endX, hand2.endY, time, () => {
      this.clappingTimes ++;
      this.handOpen();
    }, TWEEN.Easing.Sinusoidal.In);
  }

  showRestartBtn() {

    console.log(' in showRestartBtn');
    this.restartBtn.visible = true;
    this.restartBtn.alpha = 0;
    this.restartBtn.setScaleXY(0);

    const time = 0.6;
    setTimeout(() => {

      this.showBtnAudio.play();
      scaleItem(this.restartBtn, this.mapScale, time, () => {
        this.canTouch = true;
      }, TWEEN.Easing.Elastic.Out);

      showItem(this.restartBtn, time * 0.9, () => {

      }, TWEEN.Easing.Cubic.Out);

    }, 300);


  }


  mapDown(event) {


    if (!this.canTouch) {
      return;
    }


    // this.ball.x =

    // this.curShape.x = x - this.bg.x;
    // this.curShape.y = y - this.bg.y;
    //
    // console.log(`x: ${this.curShape.x}, y: ${this.curShape.y}`);


    if (this.mask.visible) {
      if (this.startBtn.visible && this.checkClickTarget(this.startBtn)) {


        this.playAudio(this.clickAudio);
        this.startBtnClick();
        return;
      }

      if (this.restartBtn.visible && this.checkClickTarget(this.restartBtn)) {

        this.playAudio(this.clickAudio);
        this.restartBtnClick();
        return;
      }


    } else {

      if (this.soundPlay.visible) {
        if (this.checkClickTarget(this.soundPlay)) {
          // this.playAudio(this.clickAudio);
          this.clickSoundPlay();
          return;
        }
      } else {
        if (this.checkClickTarget(this.soundReplay)) {
          // this.playAudio(this.clickAudio);
          this.clickSoundReplay();
          return;
        }
      }



      let arr = this.cardArr;
      for (let i = 0; i < arr.length; i ++) {
        if (this.checkClickTarget(arr[i])) {
          this.clickCard(arr[i]);
          return;
        }
      }
    }









  }

  playAudio(audio) {
    if (audio) {
      audio.pause();
      audio.currentTime = 0;
      audio.play();
    }
  }

  startBtnClick() {
    this.mask.visible = false;
    this.startBtn.visible = false;

    this.showStartAnima();
  }

  restartBtnClick() {

    this.canTouch = false;
    this.mask.visible = false;

    this.showPetalFlag = false;
    this.endPageArr.length = 0;

    // this.soundReplay.visible = false;

    this.randomAnswerIdArr();
    this.showMoveCenterAnima();
  }


  clickSoundPlay() {

    if (this.checkAllCardClicked()) {
      return;
    }
    this.soundPlay.visible = false;
    this.soundReplay.visible = false;
    this.setAudioAllReadyPlay();
    this.answerIdIndex = 0;
    this.showPicSound();
  }

  clickSoundReplay() {

    if (this.checkAllCardClicked()) {
      return;
    }

    this.soundPlay.visible = false;
    this.soundReplay.visible = false;
    this.answerIdIndex = 0;
    this.showPicSound();
  }

  checkAllCardClicked() {

    // 所有卡片已经到位;
    const arr = this.cardArr;
    for (let i = 0; i < arr.length; i++) {
      if (!arr[i].numIcon) {
        return false;
      }
    }

    return true;
  }


  clickCard(card) {

    if (card.numIcon) {
      return;
    }

    if (card.id != this.answerIdArr[this.iconIndex - 1]) {
      this.wrongAudio.pause();
      this.wrongAudio.currentTime = 0;
      this.wrongAudio.play();
      shake(card);
      return;
    }


    this.playAudio(this.clickAudio);


    const numIcon = this.getNumIcon();
    card.addChild(numIcon);
    numIcon.x = -card.width / 2 + 30;
    numIcon.y = -card.height / 2 + 25;
    numIcon.setScaleXY(0);

    card.numIcon = numIcon;
    card.zIndex = 10 + Number(numIcon['num']);
    this.renderArr.sort((a, b) => {
      if (!a.zIndex) a.zIndex = 0;
      if (!b.zIndex) b.zIndex = 0;

      return a.zIndex - b.zIndex;
    });

    scaleItem(numIcon, 1, 0.4, () => {
      this.jumpToFrame(card, numIcon['num'] - 1);
    }, TWEEN.Easing.Elastic.Out);
  }







  jumpToFrame(card, index) {


    const frame = this.frameArr[index];
    const addX = (frame.x - card.x) / 2;
    const addY = (frame.y - card.y) / 2;
    const time = 1;

    this.curCard = card;


    // moveItem(card, frame.x, frame.y, time);
    //
    // moveItem(card, card.x + addX, card.y + addY + 100, time / 2, () => {
    //   moveItem(card, frame.x, frame.y, time / 2);
    // });

    const topH = frame.y - 50;
    const totalLen = Math.abs(frame.y - card.y) + Math.abs(topH - frame.y) * 2;
    const ySpeed = totalLen / time;
    const time1 = Math.abs(totalLen - Math.abs(topH - frame.y)) / ySpeed;
    const time2 = time - time1;

    // const totalLenW = frame.x - card.x;
    // const xSpeed = totalLenW / time;
    // const targetX1 = card.x + xSpeed * time1;


    // tweenChange(card, {
    //   // x: card.x + addX,
    //   // y: card.y + addY,
    //   scaleX: 1.2 * this.mapScale,
    //   scaleY: 1.2 * this.mapScale
    // }, time / 2, () => {
    //
    //
    //   tweenChange(card, {
    //     // x: card.x + addX,
    //     // y: card.y + addY,
    //     scaleX: this.mapScale,
    //     scaleY: this.mapScale
    //   }, time / 2, () => {
    //
    //   },  TWEEN.Easing.Sinusoidal.Out);
    //
    // },  TWEEN.Easing.Sinusoidal.In);

    bezierMove(card, {x: card.x, y: card.y}, {x: frame.x, y: frame.y - 100}, frame, 0.85, () => {
      card.jumpEnd = true;
      this.checkGameEnd();

      this.successAudio.pause();
      this.successAudio.currentTime = 0;
      this.successAudio.play();
    }, TWEEN.Easing.Sinusoidal.InOut);

    // tweenChange(card, {x: frame.x, y: frame.y}, time, null, TWEEN.Easing.Sinusoidal.InOut);
    // tweenChange(card, { y: topH }, time / 2, () => {
    //   tweenChange(card, { y: frame.y}, time / 2, null, TWEEN.Easing.Sinusoidal.In);
    // }, TWEEN.Easing.Sinusoidal.Out);

    // const moveFrameAction2 = () => {
    //
    //   moveItem(card, card.x + addX, card.y + addY, time, () => {
    //
    //   }, TWEEN.Easing.Sinusoidal.In);
    //
    // };
    //
    // const moveFrameAction1 = () => {
    //
    //   moveItem(card, card.x + addX, card.y + addY, time, () => {
    //     moveFrameAction2();
    //   }, TWEEN.Easing.Sinusoidal.Out);
    //
    // };
    //
    // moveFrameAction1();

  }



  checkGameEnd() {
    const arr = this.cardArr;
    for (let i = 0; i < arr.length; i++) {
      if (!arr[i].jumpEnd) {
        return;
      }
    }

    this.gameEnd();
  }




  getNumIcon() {



    const iconRes = 'num_' + this.iconIndex;
    const icon = new MySprite(this.ctx);
    icon.init(this.images.get(iconRes));
    icon['num'] = this.iconIndex;

    this.iconIndex ++;

    if (this.iconIndex > 4) {
      this.iconIndex = 1;
    }

    return icon;
  }

  setAudioAllReadyPlay() {
    for (let i = 0; i < this.picArr.length; i++) {
      const item = this.picArr[i];
      let audio = this.audioObj[item.audio_url];
      audio.play();
      audio.pause();
    }
  }

  showPicSound() {

    this.canTouch = false;

    const index = this.answerIdArr[this.answerIdIndex];

    if (this.answerIdIndex >= this.answerIdArr.length) {
      this.soundReplay.visible = true;
      this.canTouch = true;
      return;
    }

    const curData = this.picArr[index];
    let audio = this.audioObj[curData.audio_url];
    if (audio) {

      console.log('answerIdIndex: ', this.answerIdIndex);
      console.log('audio: ', audio)

      // audio = new Audio();
      // audio.play();
      // audio.pause();
      // audio.src = curData.audio_url;
    

      if (!audio.hasEndedEvent) {
        audio.onended = () => {
          console.log(' in ended')
          this.showPicSound();
        };
        audio.hasEndedEvent = true;
      }
      audio.load();
      audio.play();
    } else {
      this.showPicSound();
    }

    this.answerIdIndex ++;

  }






  showStartAnima() {

    this.openAnimaAudio.play();
    this.cardArr = randomSortByArr(this.cardArr);


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

      const card = arr[i];
      const moveTime = 0.5;

      const pos = this.posArr[i];
      moveItem(card, pos.x, pos.y, moveTime, () => {
        this.canTouch = true;
      }, TWEEN.Easing.Quintic.Out);
    }
  }


  showMoveCenterAnima() {

    this.closeAnimaAudio.play();

    const arr = this.cardArr;

    const time = 0.3;
    for (let i = 0; i < arr.length; i++) {
      const card = arr[i];

      hideItem(card.numIcon, time / 2, () => {
        card.removeChild(card.numIcon);
        card.numIcon = null;
      });

      card.zIndex = 0;
      card.jumpEnd = false;

      if (i == arr.length - 1) {
        moveItem(card, this.canvasWidth / 2, card.baseY, time, () => {
          setTimeout(() => {
            this.showStartAnima();
          }, 200);
        }, TWEEN.Easing.Cubic.Out);

      } else {
        moveItem(card, this.canvasWidth / 2, card.baseY, time, null, TWEEN.Easing.Cubic.Out);
      }
    }

    this.soundPlay.visible = true;
    this.soundPlay.alpha = 0;
    showItem(this.soundPlay, time);

  }





  moveHole() {
    const index = this.getHoleIndex();
    const holePos = this.holePosArr[index];
    const px = holePos[0] * this.bottom.scaleX;
    const py = this.canvasHeight - holePos[1] * this.bottom.scaleY;


    let tmpS = 1;
    if (index == 0 || index == 3) {
      tmpS = 1.05;
    }

    const downBall = () => {

      removeItemFromArr(this.renderArr, this.ball);
      this.renderArr.unshift(this.ball);

      moveItem(this.ball, this.ball.x, this.canvasHeight, 0.3, () => {
        this.showLight(index);
      }, TWEEN.Easing.Quadratic.In);
    };


    const moveHoleStart = () => {
      const time = 1.5;
      tweenChange(this.ball, {x: px}, time, () => {
        downBall();
        // hideShadow();
      }, TWEEN.Easing.Quadratic.Out);


      const targetS = Math.round(0.75 * this.ball.scaleX * tmpS * 1000) / 1000;
      tweenChange(this.ball, {y: py}, time, null, TWEEN.Easing.Quadratic.Out);
      scaleItem(this.ball, targetS, time, null, TWEEN.Easing.Quadratic.Out);
    };

    moveHoleStart();

  }

  getHoleIndex() {
    // return 0;

    if (!this.indexArr || this.indexArr.length <= 0) {
      this.indexArr = randomSortByArr([0, 1, 2, 3]);
    }

    const i = this.indexArr.pop();
    return i;
  }


  showLight(i) {
    const pos = this.lightPosArr[i];

    this.light.alpha = 0;
    this.light.x = pos[0] * this.bottom.scaleX;
    this.light.y = this.canvasHeight - pos[1] * this.bottom.scaleY;
    showItem(this.light, 0.1, () => {
      setTimeout(() => {

        this.resetBall();
      }, 2000);
    });

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

  resetBall() {

    hideItem(this.light, 0.3);

    this.initBall();
  }


  clickItem(index) {


    const curData = this.picArr[index];
    console.log("curData: ", curData);
    const audio = this.audioObj[curData.audio_url];
    if (audio) {
      audio.play();
    }
  }






  changeCard() {

    this.canTouch = false;
    const x = this.canvasWidth * 1.5;
    const y = this.canvasHeight * - 0.7;
    moveItem(this.curCard, x, y, 1, () => {
      // this.canTouch = true;
    }, TWEEN.Easing.Sinusoidal.Out);

    rotateItem(this.curCard, 150);


    this.bottomCard.visible = true;
    scaleItem(this.bottomCard, this.mapScale, 0.6, () => {
      this.canTouch = true;
    }, TWEEN.Easing.Elastic.Out);
    this.curCard = this.bottomCard;

    this.addBottomCard();

  }

  addBottomCard() {

    const bottomCard = new MySprite(this.ctx);
    bottomCard.init(this.images.get(this.getFrameColor()));
    bottomCard.setScaleXY(this.mapScale * 0.95);
    bottomCard.x = this.canvasWidth / 2;
    bottomCard.y = this.canvasHeight / 2;
    bottomCard.visible = false;
    // this.addPic(bottomCard);

    this.renderArr.unshift(bottomCard);
    this.bottomCard = bottomCard;
  }



  moveArm1() {

    this.canTouch = false;
    const arm1 = this.arm1;
    const offX = this.canvasWidth / 2 - this.pageW / 2 * this.mapScale;
    const tx = offX - (arm1.width) * arm1.scaleX + this.pageOffX * arm1.scaleX;

    moveItem(this.arm1, tx, arm1.y, 0.8, () => {
     this.canTouch = true;
     this.clickLeft();
    } );
  }

  moveArm2() {

    const arm1 = this.arm1;
    const arm2 = this.arm2;
    const offX = this.canvasWidth / 2 - this.pageW / 2 * this.mapScale;
    const tx = offX - (arm1.width) * arm1.scaleX + this.pageOffX * arm1.scaleX;

    this.canTouch = false;

    moveItem(arm2, this.canvasWidth - tx, arm2.y, 0.8, () => {
     this.canTouch = true;
     this.clickRight();
    } );

  }



  clickTitle() {
    this.titleAudio.play();
  }

  clickEmpty() {
    this.moveDown();
  }


  clickBall() {

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

    this.canTouch = false;

    const down = () => {

      const targetY = this.stick.y + this.stick.height;
      tweenChange(this.ball, {y: targetY}, 0.8, () => {
        up();
      }, TWEEN.Easing.Quadratic.In, () => {
        this.stick.scaleY = (this.stick.y - this.ball.y) / this.stick.height;
      });

      if (this.curPic) {
        hideItem(this.curPic, 0.7);
        showItem(this.mask, 0.7);
      }
    };

    const up = () => {
      const targetY = this.stick.y - this.stick.height;
      tweenChange(this.ball, {y: targetY}, 0.8, () => {
        this.canTouch = true;
      }, TWEEN.Easing.Quadratic.Out, () => {
        this.stick.scaleY = (this.stick.y - this.ball.y) / this.stick.height;
      });

      this.showPic();
    };

    down();
  }

  showPic() {




    this.mask.removeChildren();

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

    const curPic = new MySprite(this.ctx);
    curPic.init(this.images.get(data.pic_url));
    const sx = this.picW / curPic.width;
    const sy = this.picH / curPic.height;
    const s = Math.min(sx, sy);
    curPic.setScaleXY(s);

    this.robot.addChild(curPic);
    curPic.x = this.mask.x;
    curPic.y = this.mask.y;

    this.curPic = curPic;

    curPic.alpha = 0;
    showItem(curPic);
    hideItem(this.mask);

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



  }


  clickPic() {

    // console.log('in clickPic');
    const curData = this.curData;
    const audio = this.audioObj[curData.audio_url];
    if (audio) {
      audio.play();
    }
  }


  clickLeft() {
    const curData = this.picArr[this.picIndex];
    const audio = this.audioObj[curData.word_1_audio_url];
    if (audio) {
      audio.play();
    }
  }

  clickRight() {
    const curData = this.picArr[this.picIndex];
    const audio = this.audioObj[curData.word_2_audio_url];
    if (audio) {
      audio.play();
    }
  }

  clickCenter() {

    console.log(' in clickCenter');

    this.canTouch = false;


    this.arm1.visible = false;
    this.arm2.visible = false;

    this.showArr(this.centerPageArr);

    setTimeout(() => {
      this.arm1.visible = true;
      this.arm2.visible = true;

      this.hideArr(this.centerPageArr);

      this.arm1.page1.visible = false;
      this.arm1.page2.visible = true;

      this.arm2.page1.visible = false;
      this.arm2.page2.visible = true;

      this.canTouch = true;
    }, 0.25 * 1000);
    // this.arm1.centerSpr.visible = true;

    // this.arm1.centerSpr.x = this.arm1.x;
    // this.arm1.centerSpr.y = this.arm1.y;



  }







  mapMove(event) {


  }

  mapUp(event) {


  }





  moveDown() {

    this.canTouch = false;

    const data = {y: this.arm1.y};
    const tween = tweenChange(data, {y: this.arm1.y + this.canvasHeight}, 1,
      () => {
      this.canTouch = true;
      this.resetArm();
    },
      TWEEN.Easing.Quadratic.In,
      (item, progress) => {

      this.arm1.y = item.y;
      this.arm2.y = item.y;

    });


  }



  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.updateItem(this.curCard);
    this.updateItem(this.mask);


    this.updateItem(this.hand2);
    this.updateItem(this.hand1);

    this.updateArr(this.endPageArr);


  }


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




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



  }




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


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

}
