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

import {
  createSprite, delayCall, getAngleByPos, getPosDistance,
  Label,
  MySprite, randomSortByArr, removeItemFromArr, ShapeRect, ShapeRectNew, showPopParticle, tweenChange,

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

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

import TWEEN from '@tweenjs/tween.js';




@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;
  mapScale = 1;

  canvasLeft;
  canvasTop;

  saveKey = 'ym_3_29';


  btnLeft;
  btnRight;
  pic1;
  pic2;

  canTouch = true;

  curPic;
  private title1: Label;
  private t1Bg: any;
  private title2: Label;
  private bgRect: ShapeRect;
  private gridBg: any;
  private gridObj: {};
  private wordArr: any;
  private curStrip: any;
  private startGrid: any;
  private endGrid: any;
  private curWord: any;
  private curGridSprArr: any[];
  private stripColorArr: any[];
  private stripColodId: 0;
  private timeId: NodeJS.Timeout;
  private isShowBallon: boolean;
  private particleLayer: any;

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


  ngOnInit() {

    this.data = {};

    // 获取数据
    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);
    this.cleanAudio();
    clearTimeout(this.timeId);
  }


  cleanAudio() {
    if (this.audioObj) {
      for (const key in this.audioObj) {
        this.audioObj[key].pause();
      }
    }
  }


  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;
    window['curImages'] = this.images;
  }






  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 = true, callback = null) {

    const audio = this.audioObj[key];
    if (audio) {
      if (now) {
        audio.pause();
        audio.currentTime = 0;
      }

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



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





  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.grid) {
      const strData = '{"logicX":10,"logicY":10,"grid":[[{},{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{},{}],[{},{},{},{"text":"a"},{"text":"a"},{},{},{},{},{}],[{},{},{},{"text":"b"},{"text":"p"},{},{},{},{},{}],[{},{},{},{"text":"c"},{"text":"p"},{"text":"d"},{},{},{},{}],[{},{},{},{},{"text":"l"},{"text":"e"},{},{},{},{}],[{},{},{},{},{"text":"e"},{"text":"f"},{},{},{},{}],[{},{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{},{}]],"picArr":[{"text":"apple","audio_url":"assets/play/default/apple.mp3","pic_url":"assets/play/default/apple.png"}]}'
      this.data = JSON.parse(strData);
      this.data.title = {
        t_val1: "C",
        t_val2: "Read, find and circle."
      };
    }
  }


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

    this.addUrlToImages(this.data.pic_url);
    this.addUrlToImages(this.data.pic_url_2);

  }

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

    // 音频资源
    this.addUrlToAudioObj(this.data.title.audio_url);

    this.data.picArr.forEach((item) => {
      this.addUrlToAudioObj(item.audio_url);

    })

    // 音效
    this.addUrlToAudioObj('right', this.rawAudios.get('right'), 1);
    this.addUrlToAudioObj('wrong', this.rawAudios.get('wrong'), 0.5);
    this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.2);
    this.addUrlToAudioObj('pop', this.rawAudios.get('pop'), 0.7);
    this.addUrlToAudioObj('finish', this.rawAudios.get('finish'), 0.3);

  }



  /**
   * 初始化数据
   */
  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 = [];

    const colorArr = [
      '#ee393c',
      '#9500ee',
      '#3821fb',
      '#4e9312',
      '#fe6702',
      '#17d8c8',
      '#f5c001',
      '#0095ff',
      '#ed2e9c',
      '#b65f15',
    ];
    this.stripColorArr = randomSortByArr(colorArr);
    this.stripColodId = 0;

  }



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


    this.initBg();
    this.initTitle();
    this.initWords();
    this.initGrid();
    this.initParticleLayer();
    // this.initPic();

    // this.initBottomPart();

  }

  initBg() {
    // 背景
    const bg = new ShapeRect();
    bg.setSize(this.canvasWidth, this.canvasHeight);
    bg.fillColor = '#ffdb84';
    this.renderArr.push(bg);


    const bgRect2 = new ShapeRect();
    bgRect2.setSize(57, 65);
    bgRect2.fillColor = '#fdcd00';
    const sx2 = this.canvasWidth / this.canvasBaseW;
    bgRect2.setScaleXY(sx2);
    bgRect2.x = 65 * sx2;
    this.t1Bg = bgRect2;
    this.renderArr.push(bgRect2);

    const letterbg = new ShapeRectNew();
    letterbg.setSize(923, 600, 20);
    letterbg.setScaleXY(this.mapScale);
    letterbg.fillColor = '#fdf8e9';
    letterbg.x = this.canvasWidth - letterbg.width * letterbg.scaleX - 90 * this.mapScale;
    letterbg.y = this.canvasHeight - letterbg.height * letterbg.scaleY - 30 * this.mapScale;
    letterbg.setShadow(0, 5, 7, 'rgba(0, 0, 0, 0.4)');
    // letterbg.setShadow()
    this.renderArr.push(letterbg);
    this.gridBg = letterbg;



    // const gridBg = createSprite('grid_bg');
    // this.bgRight.addChild(gridBg, -2);
    // gridBg.x = this.gridBg.x;
    // gridBg.y = this.gridBg.y;

    const stripLayer = createSprite('');
    this.gridBg.addChild(stripLayer);
    this.gridBg['stripLayer'] = stripLayer;

    // this.gridBg = gridBg;
  }

  initTitle() {

    //小标题
    console.log("title" + this.data);

    this.title1 = new Label();
    this.title1.text = this.data.title.t_val1;
    this.title1.fontName = 'BRLNSDB';
    this.title1.fontColor = '#ab5b22';
    this.title1.fontSize = 55;
    this.title1.textAlign = 'center';
    this.title1.refreshSize();
    this.t1Bg.addChild(this.title1);
    this.title1.setMaxSize(52);
    this.title1.x = this.t1Bg.width / 2;
    this.title1.y = this.t1Bg.height / 2;
    //大标题
    const bgRect = new ShapeRect();
    bgRect.setSize(1000, 60);
    bgRect.init();
    bgRect.fillColor = '#F7CB47';
    bgRect.alpha = 0;

    this.title2 = new Label();
    this.title2.text = this.data.title.t_val2;
    this.title2.fontName = 'FUTURAB';
    this.title2.fontColor = '#040404';
    this.title2.fontSize = 32 * this.t1Bg.scaleX;
    this.title2.textAlign = 'left';
    this.title2.setMaxSize(1000);
    this.title2.x = this.t1Bg.x + (this.t1Bg.width + 10) * this.t1Bg.scaleX;
    this.title2.y = this.t1Bg.y + (this.t1Bg.height / 2 + 8) * this.t1Bg.scaleY;
    this.title2.refreshSize();



    this.renderArr.push(this.title2);
    this.renderArr.push(bgRect);

    this.bgRect = bgRect;

  }




  mapDown(event) {

    if (!this.canTouch) {
      return;
    }

    if (this.curStrip) {
      this.cleanCurStrip();
      return false;
    }


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


    for (let x in this.gridObj) {
      for (let y in this.gridObj[x]) {
        if (this.checkClickTarget(this.gridObj[x][y])) {
          this.clickedGrid(this.gridObj[x][y]);
          return;
        }
      }
    }


    if (this.checkClickTarget(this.title2)) {

      console.log('aaa');
      this.playAudio(this.data.title.audio_url);
      return;
    }

  }

  mapMove(event) {
    if (!this.curStrip) {
      return;
    }
    for (let x in this.gridObj) {
      for (let y in this.gridObj[x]) {
        if (this.checkClickTarget(this.gridObj[x][y])) {
          if (this.gridObj[x][y] != this.startGrid) {
            this.refreshCurStrip(this.gridObj[x][y]);
            return;
          }
        }
      }
    }
  }

  mapUp(event) {
    if (this.curStrip) {
      this.checkIsWord();
      this.cleanCurStrip();
    }
  }



  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.particleLayer.update();

  }


  private initWords() {

    this.wordArr = [];

    const scale = this.gridBg.scaleX;
    const maxWidth = 245;
    const itemH = 50;
    const disH = 10;
    const baseX = this.gridBg.x / 2 - maxWidth / 2 * scale;
    const baseY = (this.gridBg.height * this.gridBg.scaleY - (itemH + disH) * this.data.picArr.length * scale) / 2 + this.gridBg.y;
    this.data.picArr.forEach((item, i) => {

      const word = this.getWordBg(item, maxWidth);
      word.setScaleXY(scale);
      word.setShadow(0, 3, 4, 'rgba(0, 0, 0, 0.5)');
      word['top'].setShadow(0, 3, 4, 'rgba(0, 0, 0, 0.5)');
      word.x = baseX + (maxWidth ) / 2 * scale;
      word.y = baseY + i * (disH + itemH) * scale;

      this.wordArr.push(word);
      this.renderArr.push(word);
    });
  }

  private getWordBg(item: any, maxLen) {
    const wordBg = new ShapeRectNew();
    // wordBg.setSize(50, 50, 25);
    wordBg.setScaleXY(this.mapScale);
    wordBg.fillColor = '#a6b500';

    const wordTop = new ShapeRectNew();
    wordTop.alpha = 0;
    wordTop.anchorX = 0.5;
    wordTop.anchorY = 0.5;
    wordBg['top'] = wordTop;
    wordBg.addChild(wordTop);
    wordBg.anchorX = 0.5;
    wordBg.anchorY = 0.5;



    const label = new Label();
    label.text = item.text;
    label.fontColor = '#fff';
    label.fontName = 'BRLNSDB_1';
    label.textAlign = 'center';
    label.refreshSize();

    const min = 100;
    const minMax = Math.max(min, label.width * 1.2)
    wordBg.setSize(Math.min(maxLen , minMax), 50, 25);
    wordTop.setSize(Math.min(maxLen , minMax), 50, 25);

    // label.x = wordBg.width / 2;
    // label.y = wordBg.height / 2;
    label.setMaxSize(wordBg.width * 0.9);
    wordBg.addChild(label);

    wordBg['data'] = item;

    return wordBg;
  }




  private initGrid() {

    this.gridObj = {};

    const numX = Number(this.data.logicX);
    const numY = Number(this.data.logicY);
    const len = 56;
    const dis = 8;
    const baseX = -(len * numX + dis * (numX - 1)) / 2 + len / 2 + this.gridBg.width / 2;
    let baseY = -(len * (numY) + dis * (numY - 1)) / 2 + len / 2 + this.gridBg.height / 2;

    const grid = this.data.grid;
    for (let j = 0; j < Number(this.data.logicY); j++) {

      for (let i = 0; i < Number(this.data.logicX); i++) {
        if (!this.gridObj[i.toString()]) {
          this.gridObj[i.toString()] = {};
        }

        const gridData = grid[i][j];
        const gridSpr = this.createGridRect(gridData, len);
        gridSpr.x = baseX + i * (len + dis);
        gridSpr.y = baseY;
        this.gridBg.addChild(gridSpr);
        gridSpr['logicX'] = i.toString();
        gridSpr['logicY'] = j.toString();

        this.gridObj[i.toString()][j.toString()] = gridSpr;
      }
      baseY += (len + dis);
    }
  }

  private createGridRect(data, len) {
    const grid = new MySprite();

    const shapeRect = new ShapeRect();
    shapeRect.setSize(len, len);
    shapeRect.x = - len / 2;
    shapeRect.y = - len / 2;
    shapeRect.visible = false;
    grid.addChild(shapeRect);

    if (data.text) {
      const label = new Label()
      label.text = data.text;
      label.setMaxSize(len * 0.9);
      label.textAlign = 'center';
      label.fontName = 'FZLSJW';
      label.fontSize = 56;
      label.fontColor = '#000';
      label.y = -3;
      grid.addChild(label);
      grid['label'] = label;

    }
    grid.width = len;
    grid.height = len;
    grid.anchorX = 0.5;
    grid.anchorY = 0.5;
    grid['data'] = data;
    return grid;
  }

  private cleanCurStrip() {
    const strip = this.curStrip;
    tweenChange(strip, {alpha: 0}, 0.1, () => {
      strip.parent.removeChild(this.curStrip);
    });
    this.curStrip = null;
  }

  private checkIsWord() {

    if (this.startGrid == this.endGrid) {
      if(this.startGrid.audio) {
        this.startGrid.audio.play()
      }
      return;
    }

    const word = this.getWord();

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

      if (!item.isCheckEnd && item.data && word == item.data.text) {
        this.showWordRight(item);

        item.isCheckEnd = true;
        this.checkGameEnd();

        return;
      }
    }


    this.playAudio('wrong');
  }

  private getWord() {
    const startNumX = Number(this.startGrid['logicX']);
    const startNumY = Number(this.startGrid['logicY']);
    const endNumX = Number(this.endGrid['logicX']);
    const endNumY = Number(this.endGrid['logicY']);

    let subX = endNumX - startNumX;
    let subY = endNumY - startNumY;
    const loopNum = Math.max(Math.abs(subX), Math.abs(subY));

    subX = subX / loopNum;
    subY = subY / loopNum;

    this.curGridSprArr = [];
    let word = '';
    for (let i = 0; i <= loopNum; i++) {
      const logicX = (startNumX + subX * i).toString();
      const logicY = (startNumY + subY * i).toString();
      const gridSpr = this.gridObj[logicX][logicY];

      this.curGridSprArr.push(gridSpr);

      word += gridSpr['data'].text || ' ';
    }
    return word;
  }


  private checkGameEnd() {

    const isGameEnd = this.wordArr.every((word) => {
      return word.isCheckEnd;
    });

    if (isGameEnd) {
      this.gameEnd();
    }
  }

  private gameEnd() {
    this.showBallonAnimation();
    this.playAudio('finish');
  }

  private refreshCurStrip(endGrid) {
    if (this.endGrid == endGrid) {
      return;
    }

    const x1 = Number(this.startGrid['logicX']);
    const y1 = Number(this.startGrid['logicY']);
    const x2 = Number(endGrid['logicX']);
    const y2 = Number(endGrid['logicY']);
    const angle = Math.round( getAngleByPos(x1, y1, x2, y2) );

    if (angle % 45 !== 0) {
      return;
    }

    const len = getPosDistance(this.startGrid.x, this.startGrid.y, endGrid.x, endGrid.y);

    this.curStrip.width = len + this.curStrip.height;
    this.curStrip.rotation = angle - 90;
    this.curStrip.anchorX = this.curStrip.height / 2 / this.curStrip.width;
    console.log('angle: ', angle);

    this.endGrid = endGrid;
  }

  private clickedWord(word: any) {

    this.playAudio(word.data.audio_url);

  }

  private createStrip(len) {
    const strip = new ShapeRectNew();
    strip.setSize(len, len, len / 2);
    strip.anchorX = 0.5;
    strip.anchorY = 0.5;
    strip.fillColor = this.stripColorArr[this.stripColodId];
    strip.alpha = 0.72;

    return strip;
  }

  private clickedGrid(gridSpr: any) {

    const strip = this.createStrip(gridSpr.width * 1.05);
    strip.x = gridSpr.x;
    strip.y = gridSpr.y;

    // console.log('gridSpr.logicX: ', gridSpr.logicX);
    // console.log('gridSpr.logicY: ', gridSpr.logicY);

    this.gridBg.stripLayer.addChild(strip);
    this.curStrip = strip;
    this.startGrid = this.endGrid = gridSpr;

    this.playAudio('click');
  }

  private createRightStrip() {
    const strip = this.curStrip;
    const rightStrip = new ShapeRectNew();
    rightStrip.setSize(strip.width, strip.height, strip.radius);
    rightStrip.anchorX = strip.anchorX;
    rightStrip.anchorY = strip.anchorY;
    rightStrip.rotation = strip.rotation;
    rightStrip.x = strip.x;
    rightStrip.y = strip.y;
    rightStrip.fillColor = this.stripColorArr[this.stripColodId];
    rightStrip.alpha = 0.72;
    return rightStrip;
  }

  private changeLetterColor(item) {
    this.curGridSprArr.forEach((gridSpr) => {
      const label = gridSpr['label'];
      tweenChange(label, {alpha: 0} , 0.3, () => {
        label.fontColor = '#ffffff';
        tweenChange(label, {alpha: 1}, 0.3);
      });
      gridSpr['audio'] = this.audioObj[item.data.audio_url];
    });
  }

  private showWordRight(item: any) {
    console.log(' in showWordRight')

    const audio = this.audioObj[item.data.audio_url];
    this.playAudio('right', null, () => {
      if (audio) {
        audio.play();
      }
    });

    const rightStrip = this.createRightStrip();
    this.gridBg.stripLayer.addChild(rightStrip);

    rightStrip.alpha = 0;
    tweenChange(rightStrip, {alpha: 0.72}, 0.5, () => {
    }, TWEEN.Easing.Cubic.In);
    this.changeLetterColor(item);
    this.changeWordBgColor(item, rightStrip.fillColor);

    this.stripColodId ++;
  }


  private changeWordBgColor(wordBg: any, fillColor) {

    wordBg.top.fillColor = fillColor;
    tweenChange(wordBg, {alpha: 0}, 1);
    tweenChange(wordBg.top, {alpha: 1}, 0.5);


    const rect = wordBg.getBoundingBox();
    tweenChange(wordBg, {scaleX: 1.2 * this.mapScale, scaleY: 1.2 * this.mapScale}, 0.15, () => {
      tweenChange(wordBg, {scaleX: this.mapScale, scaleY: this.mapScale}, 0.15, () => {

      }, TWEEN.Easing.Cubic.In);
    }, TWEEN.Easing.Cubic.Out);
    setTimeout(() => {
      this.playAudio('pop');
      showPopParticle(this.images.get('dot'), {x: rect.x + rect.width / 2, y: rect.y + rect.height / 2}, this.particleLayer, 20, 40 * this.mapScale, 80 * this.mapScale, 0.5, this.mapScale);
    }, 100);
  }

  private showBallonAnimation() {
    this.isShowBallon = true;
    this.showOneBallon();

    setTimeout(() => {
      this.isShowBallon = false;
    }, 2700);
  }

  private showOneBallon() {

    console.log(' in showBallonAnima');
    const getBallon = () => {
      const ballonId = Math.floor( Math.random() * 6 );
      const ballon = createSprite('ballon_' + ballonId);

      const randomS = 0.8 + 0.2 * Math.random();
      ballon.setScaleXY(randomS * this.mapScale);

      const randomX = this.canvasWidth * Math.random();
      ballon.x = randomX;
      ballon.y = this.canvasHeight + ballon.height / 2 * ballon.scaleY;

      return ballon;
    };

    const ballon = getBallon();
    this.renderArr.push(ballon);

    const time = Math.floor( (1 + Math.random() * 2) * 100 ) / 100 ;
    tweenChange(ballon, {y: -ballon.height / 2 * ballon.scaleY}, time, () => {
      removeItemFromArr(this.renderArr, ballon);
    }, TWEEN.Easing.Quadratic.In);


    this.timeId = setTimeout(() => {
      if (this.isShowBallon) {
        this.showOneBallon();
      }
    }, 20 + 50 * Math.random());
  }

  private initParticleLayer() {
    this.particleLayer = new MySprite();
  }
}
