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

import {
  Label,
  MyAnimation,
  MySprite, removeItemFromArr, shake, ShapeRect, tweenChange,

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

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

import TWEEN from '@tweenjs/tween.js';
import { Petal } from './PetalUtil';
import { Celebrate } from './Celebrate';




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

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

  // 数据
  data;

  ctx;

  canvasWidth = 1280; // canvas实际宽度
  canvasHeight = 720; // canvas实际高度

  canvasBaseW = 1280; // canvas 资源预设宽度
  canvasBaseH = 720;  // canvas 资源预设高度

  mx; // 点击x坐标
  my; // 点击y坐标


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

  images = new Map();

  animationId: any;
  winResizeEventStream = new Subject();

  audioObj = {};

  renderArr;

  magnifierArr = [];

  mapScale = 1;

  canvasLeft;
  canvasTop;

  saveKey = 'LST-04-01';



  canTouch = true;

  private bg: any;
  private hotZoneArr: any[];
  private magnifier: MySprite;
  private isMagnifierTouched: boolean;
  private curHotZoneItem: any;
  private photoAnima: MyAnimation;
  private hotZoneRate: number;
  private oldHotMapScale: number;
  private textLabelArr: any;
  private allBtns: any;
  private curAudio: any;

  private endRenderArr: any[];

  private bgAudio: any;

  private finished = false;

  private curExercises: any;

  private curIndex = 0;

  timeId = null;

  startBtn;
  startLayer;

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


  ngOnInit() {

    this.data = {};

    this.data.bgItem = {};

    this.data.exercisesArr = [];

    // 获取数据
    const getData = (<any>window).courseware.getData;
    getData((data) => {

      if (data && typeof data == 'object') {
        this.data = data;
      }
      // console.log('data:' , data);

      // 初始化 各事件监听
      this.initListener();

      // 若无数据 则为预览模式 需要填充一些默认数据用来显示
      this.initDefaultData();

      // 初始化 音频资源
      this.initAudio();
      // 初始化 图片资源
      this.initImg();
      // 开始预加载资源
      this.load();

    }, this.saveKey);

  }

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


  load() {

    // 预加载资源
    this.loadResources().then(() => {
      window["air"].hideAirClassLoading(this.saveKey, this.data);
      this.init();
      this.update();
    });
  }


  init() {

    this.initCtx();
    this.initData();
    this.initView();
  }

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


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

    window['curCtx'] = this.ctx;
  }






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


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

      return audio;
    }
  }



  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(a);
      };
      audio.onerror = () => {
        reject();
      };
      audio.src = url;
      audio.load();
    });
  }


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


  checkClickHotZoneTarget(target) {
    const rect = target.getBoundingBox();

    rect.width += 60 * this.mapScale;

    rect.height += 60 * this.mapScale;

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


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





  addUrlToAudioObj(key, url = null, vlomue = 1, loop = false, callback = null) {

    const audioObj = this.audioObj;

    if (url == null) {
      url = key;
    }

    this.rawAudios.set(key, url);

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

    audioObj[key] = audio;

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

  addUrlToImages(url) {
    this.rawImages.set(url, url);
  }






  // ======================================================编写区域==========================================================================





  /**
   * 添加默认数据 便于无数据时的展示
   */
  initDefaultData() {

    if (!this.data.bgItem) {
      this.data.bgItem = {
        rect: { height: 892, width: 1585, x: 392, y: 0 },
        url: 'assets/play/default/pic.jpg'
      };
    }

    if (!this.data.exercisesArr) {
      this.data.exercisesArr = [{
        hotZoneItemArr: [
          {
            audio_url: 'assets/play/default/audio.mp3',
            fontColor: "#a63f0b",
            fontName: "MMTextBook-Bold",
            fontScale: 1.85,
            fontSize: 52,
            imgScale: 1,
            index: 0,
            itemType: "text",
            mapScale: 1.85,
            rect: { x: 391.84, y: 446.02, width: 244.05, height: 244.05 },
            text: "test_1"
          }
        ]
      }, {
        hotZoneItemArr: [
          {
            audio_url: 'assets/play/default/audio.mp3',
            fontColor: "#a63f0b",
            fontName: "MMTextBook-Bold",
            fontScale: 1.85,
            fontSize: 52,
            imgScale: 1,
            index: 1,
            itemType: "text",
            mapScale: 1.85,
            rect: { x: 961.36, y: 450.36, width: 244.05, height: 244.05 },
            text: "test_2"
          }
        ]
      }
      ]
    }

  }


  /**
   * 添加预加载图片
   */
  initImg() {

    this.addUrlToImages(this.data.bgItem.picUrl);

    console.log('this.data:', this.data);
    this.data.exercisesArr.forEach((item) => {

      item.hotZoneItemArr.forEach(hotZoneItem => {
        if (hotZoneItem.itemType === 'pic') {
          this.addUrlToImages(hotZoneItem.pic_url);
        }
      });

    });


  }

  /**
   * 添加预加载音频
   */
  initAudio() {

    this.data.exercisesArr.forEach((item) => {

      item.hotZoneItemArr.forEach(hotZoneItem => {
        if (hotZoneItem.audio_url) {
          this.addUrlToAudioObj(hotZoneItem.audio_url);
        }
      });

      if (item.audio_url) {
        this.addUrlToAudioObj(item.audio_url);
      }
    });




    this.rawAudios.forEach((item, key) => {
      // 音效
      this.addUrlToAudioObj(key, this.rawAudios.get(key));
    })

  }



  /**
   * 初始化数据
   */
  initData() {

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

    // this.mapScale = sx;
    // this.mapScale = sy;


    this.renderArr = [];

    this.magnifierArr = [];

    this.isMagnifierTouched = false;
    this.photoAnima = null;
    this.textLabelArr = [];
    this.allBtns = [];
    this.endRenderArr = [];
    this.finished = false;

    this.curIndex = 0;

    this.curExercises = null;
  }

  playBgAudio() {

    if (this.timeId) {
      clearTimeout(this.timeId);
    }

    if (this.bgAudio) {
      this.bgAudio.pause();
    }

    if (this.finished && this.bgAudio) {
      this.bgAudio.pause();
    }

    this.bgAudio = this.playAudio(this.curExercises.audio_url, true, () =>{
      this.timeId = setTimeout(() => {

        if (!this.finished) {
          this.playBgAudio();
        }
  
      }, 3000);
    });
  }


  /**
   * 初始化试图
   */
  initView() {

    this.initBg();


    this.addStartLayer();

  }


  addStartLayer() {
    const startLayer = new ShapeRect();
    startLayer.setSize(this.canvasWidth, this.canvasHeight);
    startLayer.alpha = 0.5;
    startLayer.fillColor = "#000000";
    startLayer.x = 0;
    startLayer.y = 0;
    this.startLayer = startLayer;

    const startBtn = new MySprite();
    startBtn.init(this.images.get('start_btn'));
    startBtn.setScaleXY(this.mapScale);
    startBtn.x = this.canvasWidth / 2;
    startBtn.y = this.canvasHeight / 2;
    startLayer.addChild(startBtn);
    this.startBtn = startBtn;

  }

  private createSprite(key: string) {
    const sprite = new MySprite();
    sprite.init(this.images.get(key));
    return sprite;
  }


  private initBg() {

    console.log('data:', this.data);
    const url = this.data.bgItem.picUrl;
    const bg = this.createSprite(url);

    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.min(sx, sy);
    bg.setScaleXY(s);
    this.bg = bg;

    this.renderArr.push(bg);
  }

  showNext() {

    if (this.magnifier) {
      this.magnifier['light'].visible = false;
      this.magnifier['wrong'].visible = false;
    }


    if (this.curHotZoneItem) {
      this.curHotZoneItem.alpha = 0;
      this.curHotZoneItem = null;
    }

    if (this.bgAudio) {
      this.bgAudio.pause();
    }

    this.finished = false;

    if (this.data.exercisesArr.length == this.curIndex) {
      this.showEnd();
      return;
    }

    this.allBtns = [];

    this.curExercises = this.data.exercisesArr[this.curIndex];

    if (!this.curExercises) {
      return;
    }

    this.initHotZone();

    this.playBgAudio();

    this.canTouch = true;
  }


  initHotZone() {

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

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

    const rate = curBgRect.width / oldBgRect.width;
    this.hotZoneRate = rate;

    this.hotZoneArr = [];
    const arr = this.curExercises.hotZoneItemArr;
    if (!arr && arr.length > 0) {
      return;
    }

    this.oldHotMapScale = arr[0].mapScale;


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

      const data = JSON.parse(JSON.stringify(arr[i]));

      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, rate);
      hotZone.alpha = 0;
      this.hotZoneArr.push(hotZone);

    }
  }

  getHotZoneItem(data, rate) {

    const saveRect = data.rect;
    let item;
    if (data.itemType === 'rect') {
      item = new ShapeRect(this.ctx);
      item.setSize(saveRect.width, saveRect.height);
      item.x = saveRect.x;
      item.y = saveRect.y;

    } else if (data.itemType == 'pic') {
      item = this.createBtn(data.pic_url, null, 1);
      item.setScaleXY(data.imgScale * rate);
      item.x = saveRect.x + saveRect.width / 2;
      item.y = saveRect.y + saveRect.height / 2;
      item.onClick = () => {
        console.log('item.data:', item.data);
        if (this.curAudio && !this.curAudio.paused) {
          this.curAudio.pause();
        }
        this.curAudio = this.playAudio(item.data.audio_url);
      }

    } else if (data.itemType == 'text') {
      item = new Label();
      item.text = data.text;
      item.textAlign = 'center';
      item.fontSize = 52;
      item.fontName = "MMTextBook-Bold";
      item.fontColor = "#a63f0b";
      item.x = saveRect.x + saveRect.width / 2;
      item.y = saveRect.y + saveRect.height / 2;
      item.childDepandAlpha = true;


      item.setScaleXY(data.fontScale * rate);
      item.refreshSize();

      const textBg = this.createBtn('bg_zi', null, 1);
      item.setMaxSize(textBg.width * 0.98);
      textBg.onClick = () => {
        console.log('item.data:', item.data);
        if (this.curAudio && !this.curAudio.paused) {
          this.curAudio.pause();
        }
        this.curAudio = this.playAudio(item.data.audio_url);
      }

      textBg.y = 5;
      textBg.setScaleXY(1 / item.scaleX * this.oldHotMapScale * this.hotZoneRate);
      item.addChild(textBg, -1);
      item.bg = textBg;


      this.textLabelArr.push(item);
    }

    item['data'] = data;

    this.renderArr.push(item);

    return item;
  }

  private initMagnifier() {
    const magnifier = this.createSprite('bg_jing');
    magnifier.setScaleXY(this.mapScale);
    magnifier.x = this.canvasWidth / 2;
    magnifier.y = this.canvasHeight / 2;
    this.magnifierArr.push(magnifier);

    console.log('rate: ', this.hotZoneRate);

    const light = this.createSprite('icon_tiao');
    light.x = -magnifier.width / 2;
    light.y = -magnifier.height / 2;
    magnifier.addChild(light);
    magnifier['light'] = light;
    light.visible = false;

    const wrong = this.createSprite('bg_wrong');
    wrong.x = 45;
    wrong.y = -125;
    magnifier.addChild(wrong);
    magnifier['wrong'] = wrong;
    wrong.visible = false;

    this.magnifier = magnifier;
  }

  private touchDownMagnifier() {
    this.isMagnifierTouched = true;
    this.playAudio('click');
  }

  private magnifierMove() {
    this.magnifier.x = this.mx;
    this.magnifier.y = this.my;
  }

  private checkHotZone() {
    this.magnifier['light'].visible = false;
    this.magnifier['wrong'].visible = false;
    let hotZoneItem;
    this.hotZoneArr.forEach((item) => {
      if (this.checkClickHotZoneTarget(item)) {
        hotZoneItem = item;
        return;
      }
    });

    if (hotZoneItem) {
      if (this.curHotZoneItem && this.curHotZoneItem != hotZoneItem) {
        this.curHotZoneItem.alpha = 0;
        this.curHotZoneItem = null;
      }

      this.curHotZoneItem = hotZoneItem;

      if (this.curHotZoneItem.alpha === 0) {

        this.magnifier['light'].visible = true;

        setTimeout(() => {
          this.magnifier['light'].visible = false;

          setTimeout(() => {
            this.magnifier['light'].visible = true;

          }, 100);
        }, 100);

      }

    } else {
      if (this.curHotZoneItem) {
        this.curHotZoneItem.alpha = 0;
        this.curHotZoneItem = null;
      }
    }
  }

  private showPhotoAnima() {

    if (!this.photoAnima) {
      this.photoAnima = this.createAnima('bg_', 15);
      this.magnifier.addChild(this.photoAnima, -1);
    } else {
      this.photoAnima.frameIndex = 0;
    }

    this.photoAnima.playEndFunc = this.photoAnimaCloseEnd.bind(this);

    this.photoAnima.visible = true;
    this.photoAnima.play();
  }


  private createAnima(key, num, delayPerUnit = 0.07, loop = false) {
    const anima = new MyAnimation();
    for (let i = 1; i <= num; i++) {
      anima.addFrameByImg(this.images.get(key + i));
    }
    anima.delayPerUnit = delayPerUnit;
    anima.loop = loop;
    return anima;
  }

  private photoAnimaCloseEnd() {

    this.curHotZoneItem.answered = true;

    console.log('close...');

    tweenChange(this.curHotZoneItem, { alpha: 1 }, 0.2, () => {

      this.photoAnima.visible = false;
      this.photoAnima.reverse();
      this.magnifier['light'].visible = false;

      if (this.curAudio) {
        this.curAudio.pause();
      }

      let answered = true;

      this.hotZoneArr.forEach((item) => {

        if (!item.answered) {

          answered = false;
          return;
        }
      });

      console.log(answered);

      if (!answered) {
        this.curAudio = this.playAudio(this.curHotZoneItem.data.audio_url, true, () => {
          this.canTouch = true;
        });
      }
      else {

        this.finished = true;

        if (this.bgAudio) {
          this.bgAudio.pause();
        }

        this.curAudio = this.playAudio(this.curHotZoneItem.data.audio_url, true);

        setTimeout(()=>{
          this.curIndex++;
          this.showNext();
        }, 3000);
      }

    });

    this.playAudio('find');
  }



  mapDown(event) {

    if(this.startBtn && this.checkClickTarget(this.startBtn)){
      console.log(' in startbtn')
      this.startBtnClick();
      return;
    }

    if (!this.canTouch) {
      return;
    }

    if (this.curHotZoneItem) {
      this.allBtns.forEach((btn) => {
        if (this.curHotZoneItem == btn || this.curHotZoneItem.bg == btn && this.checkClickTarget(btn)) {
          btn._onTouchStart();
          return;
        }
      });
    }


    if (this.checkClickTarget(this.magnifier)) {
      this.touchDownMagnifier();
      return;
    }


  }

  mapMove(event) {
    if (!this.isMagnifierTouched) {
      return;
    }

    this.magnifierMove();
    this.checkHotZone();

    this.allBtns.forEach((btn) => {
      if (!this.checkClickTarget(btn)) {
        btn._isDown = false;
        return;
      }
    });

  }

  mapUp(event) {
    this.allBtns.forEach((btn) => {
      if (btn._isDown) {
        btn._onTouchEnd();
      }
    });

    if (this.isMagnifierTouched) {

      if (this.curHotZoneItem) {

        this.canTouch = false;

        if (this.curHotZoneItem.alpha === 0) {

          this.magnifier['light'].visible = true;
          this.magnifier.x = this.curHotZoneItem.x;
          this.magnifier.y = this.curHotZoneItem.y + 50 * this.mapScale;
          this.showPhotoAnima();

        }
      }
      else {
        this.magnifier['wrong'].visible = true;

        this.canTouch = true;
 
        this.playAudio('try_again', true);
        
        shake(this.magnifier, 0.5, () => {
          
        })
        
      }
    }
    this.isMagnifierTouched = false;

  }

  startBtnClick() {
    // removeItemFromArr(this.renderArr, this.startLayer);
    this.startLayer = null;
    this.startBtn = null;

    this.initMagnifier();

    this.showNext();
  }


  update() {

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



    this.updateArr(this.renderArr);

    this.updateArr(this.magnifierArr);

    this.updateArr(this.textLabelArr);

    this.updateArr(this.endRenderArr);

    if (this.startLayer) {
      this.startLayer.update();
    }
  }


  private createBtn(url_up: string, url_down: string = null, downScale = 0.9) {
    const btnUp: any = this.createSprite(url_up);
    let btnDown;
    if (url_down) {
      btnDown = this.createSprite(url_down);
      btnUp.addChild(btnDown);
    }
    btnUp.btnDown = btnDown;

    btnUp._onTouchStart = () => {
      if (btnDown) {
        btnDown.alpha = 1;
        btnUp.alpha = 0;
      }
      if (!btnUp.baseScale) {
        btnUp.baseScale = btnUp.scaleX;
      }

      btnUp.setScaleXY(btnUp.baseScale * downScale);

      if (btnUp.onTouchStart) {
        btnUp.onTouchStart();
      }
      btnUp._isDown = true;
    };

    btnUp._onTouchMove = () => {
    };

    btnUp._onTouchEnd = () => {
      if (btnDown) {
        btnDown.alpha = 0;
        btnUp.alpha = 1;
      }
      btnUp.setScaleXY(btnUp.baseScale);
      if (btnUp.onClick) {
        btnUp.onClick();
      }
      btnUp._isDown = false;
    };

    this.allBtns.push(btnUp);
    return btnUp;
  }

  showEnd() {

    console.log('play end ....');

    this.finished = true;

    this.canTouch = false;

    if (this.curAudio) {
      this.curAudio.pause();
    }

    if (this.bgAudio) {
      this.bgAudio.pause();
    }

    const mask = new ShapeRect();
    mask.setSize(this.canvasWidth, this.canvasHeight);
    mask.alpha = 0.5;
    mask.fillColor = "#000000";
    mask.x = 0;
    mask.y = 0;
    this.endRenderArr.push(mask);

    let celebrate = new Celebrate();
    celebrate.init(this.images, this.audioObj);
    celebrate.bg.setScaleXY(this.mapScale);
    celebrate.bg.x = (this.canvasWidth - celebrate.bg.getBoundingBox().width) / 2;
    celebrate.bg.y = (this.canvasHeight - celebrate.bg.getBoundingBox().height) / 2;
    this.endRenderArr.push(celebrate.bg);
    celebrate.show(this.mapScale);

    let petal = new Petal(this.endRenderArr, this.images, this.ctx);

    //显示花瓣
    petal.showPetal({ x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight }, this.mapScale, 100, 8);


  }

}
