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

import {
  Label,
  MySprite, randomSortByArr, removeItemFromArr, RichText, 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 { Title } from './Title';
import { Listening } from './Listening';
import { getDefaultTile } from '../bean/TitleBean';
import { getDefaultExercises } from '../bean/Exercises';
import { LineSpr } from './LineSpr';
import { Letter } from './Letter';
import { BigCard } from './BigCard';




@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 = 'YM5-16';

  canTouch = true;

  /**标题*/
  title: Title;

  listening: Listening;

  curAudio;

  curIndex = 0;

  curExercises;

  lineSprArr = [];

  answerSprArr = [];

  oldPos;

  itemOldPos;

  curDragItem;

  picBtn;

  bigCard: BigCard;

  bigCardRenderArr = [];

  pic;

  richText;

  @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;
      }
      else{
        let defaultData = '{"title":{"part1":"C","part2":"Read and point"},"exercisesArr":[{"answerArr":[{"index":0,"val":"she"},{"index":0,"val":"will"},{"index":0,"val":"prepare"},{"index":0,"val":"some"},{"index":0,"val":"soap"},{"index":0,"val":"for"},{"index":0,"val":"dinner"},{"index":0,"val":"with"},{"index":0,"val":"me"}],"val":"she will prepare some soap for dinner with me.","picUrl":"http://staging-teach.cdn.ireadabc.com/9db9d97240bd50d77b432aa5f1cd0727.png","audioUrl":"http://staging-teach.cdn.ireadabc.com/919b2c150b41b3306869ebe78ecb70b3.mp3"}]}';
        this.data = JSON.parse(defaultData);
      }
      // 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();
  }


  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 = false, 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(a);
      };
      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.title) {
      this.data.title = getDefaultTile();
    }

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

    let len = this.data.exercisesArr.length;

    for (let i = len; i < 1; ++i) {
      this.data.exercisesArr.push(getDefaultExercises());
    }

    len = this.data.exercisesArr.length;

    for (let i = 0; i < len; ++i) {
      if (!this.data.exercisesArr[i]) {
        this.data.exercisesArr[i] = getDefaultExercises();
      }
    }
  }


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

    //练习题音效
    for (let i = 0; i < this.data.exercisesArr.length; ++i) {

      let exercises = this.data.exercisesArr[i];

      if (exercises && exercises.picUrl) {
        this.addUrlToImages(exercises.picUrl);
      }
    }

  }

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

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



    //标题发音
    if (this.data.title.audioUrl) {
      this.addUrlToAudioObj('titleAudio', this.data.title.audioUrl);
    }


    //练习题音效
    for (let i = 0; i < this.data.exercisesArr.length; ++i) {

      let exercises = this.data.exercisesArr[i];

      if (exercises && exercises.audioUrl) {
        this.addUrlToAudioObj(exercises.audioUrl);
      }

      let answerArr = exercises.answerArr;

      for(let j = 0; j < answerArr.length; ++ j){
        if (answerArr[j].audioUrl) {
          this.addUrlToAudioObj(answerArr[j].audioUrl);
        }
      }
    }

  }



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

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

    this.curAudio = null;

    this.curIndex = 0;

    this.curExercises = null;

    this.bigCardRenderArr = [];
  }



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


    this.initBg();

    this.initTitle();

    this.initPicBtn();

    this.showNextExerises();
  }

  private initBg() {
    const bg = new ShapeRect();
    bg.fillColor = "#fff4c3";
    bg.setSize(this.canvasWidth, this.canvasHeight);
    this.renderArr.push(bg);
  }

  private initBottomPart() {

    const audio = this.audioObj[this.curExercises.audioUrl];

    if (this.listening) {
      this.listening.audio = audio;
    }
    else {
      const listening = new Listening(audio, this.images);

      listening.init(this.mapScale, this.mapScale);

      listening.bg.x = this.canvasWidth - listening.bg.width - 10 * this.mapScale;
      listening.bg.y = this.canvasHeight - listening.bg.height - 8 * this.mapScale;
      this.listening = listening;

      this.renderArr.push(listening.bg);
    }
  }

  private initTitle() {

    const title = new Title(this.data.title, this.images);

    title.init(this.mapScale, this.mapScale);
    title.audio = this.audioObj['titleAudio'];
    this.title = title;

    title.titleBg.y = 0;
    title.titleBg.x = 0;

    this.renderArr.push(title.titleBg);
  }


  private initPicBtn() {
    const picBtn = new MySprite();
    picBtn.init(this.images.get('pic-btn'));
    picBtn.setScaleXY(this.mapScale);

    picBtn.x = this.canvasWidth - 17 * this.mapScale - picBtn.getBoundingBox().width / 2;
    picBtn.y = this.canvasHeight / 2 - 190 * this.mapScale + picBtn.getBoundingBox().height / 2;
    this.picBtn = picBtn;
    this.renderArr.push(picBtn);
  }

  private showNextExerises() {

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

    this.initExerises(this.curExercises);

    this.curIndex++;
  }


  private initExerises(data) {

    this.initBottomPart();

    this.getLineArr(data);

    this.getLetter(data);

    this.getBigCard(data);

    this.canTouch = true;
  }

  private getBigCard(data) {

    if (!this.bigCard) {

      const bigCard = new BigCard();
      bigCard.init(this.images, this.mapScale, this.mapScale);
      bigCard.bg.x = this.picBtn.x;
      bigCard.bg.y = this.picBtn.y;
      this.bigCard = bigCard;
      this.bigCardRenderArr.push(bigCard.bg);
    }

    this.bigCard.setContent(data);
  }

  private getLineArr(data) {

    this.lineSprArr = [];

    let answerArr = data.answerArr;

    let w = 180 * this.mapScale;

    let h = 70 * this.mapScale;

    let dW = 53 * this.mapScale;

    let dH = 35 * this.mapScale;

    let row = Math.ceil(answerArr.length / 5);

    let col = answerArr.length > 5 ? 5 : answerArr.length;

    let totalWidth = col * w + (col - 1) * dW;

    let startX = (this.canvasWidth - totalWidth) / 2;

    let startY = this.canvasHeight / 2 + 208 * this.mapScale - h;

    let tempY = startY;

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


      let lineSpr = new LineSpr();
      lineSpr.init(this.images, this.mapScale, this.mapScale);
      lineSpr.bg.x = startX + (i % col) * (w + dW);
      lineSpr.bg.y = tempY;
      this.lineSprArr.push(lineSpr);

      if ((i + 1) % col == 0) {
        tempY = startY + h + dH;
      }

      this.renderArr.push(lineSpr.bg);
    }
  }

  private getLetter(data) {

    this.answerSprArr = [];

    let answerArr = data.answerArr;

    let h = 90 * this.mapScale;


    let dH = 34 * this.mapScale;

    let row = Math.ceil(answerArr.length / 3);

    let col = answerArr.length > 3 ? 3 : answerArr.length;

    //每行宽度
    let widthArr = [];

    //宽度临时值
    let tempWidth = 0;

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

      let bgColor = "#dbd0e7";

      let lineColor = "#8d4fad";

      if (i % 2 == 0) {
        bgColor = "#ffdd00";
        lineColor = "#cd9000";
      }

      let answerSpr = new Letter();
      answerSpr.lineColor = lineColor;
      answerSpr.init(this.images, answerArr[i], bgColor, this.mapScale, this.mapScale);

      this.answerSprArr.push(answerSpr);

      this.renderArr.push(answerSpr.bg);
    }

    //获取随机答案
    let tempAnswerSprArr = randomSortByArr(this.answerSprArr);

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

      let answerSpr = tempAnswerSprArr[i];

      let bgColor = "#dbd0e7";

      let lineColor = "#8d4fad";

      if (i % 2 == 0) {
        bgColor = "#ffdd00";
        lineColor = "#cd9000";
      }

      answerSpr.setColor(bgColor, lineColor);

      let dW = (45 + Math.ceil(Math.random() * 60)) * this.mapScale;
      answerSpr.dW = dW;

      tempWidth += answerSpr.bg.width;

      if ((i + 1) % col == 0) {
        widthArr.push(tempWidth);
        tempWidth = 0;
      }
      else {
        tempWidth += dW;
      }
    }

    if (tempWidth > 0) {
      widthArr.push(tempWidth);
    }

    let startY = this.canvasHeight / 2 - 244 * this.mapScale;

    let tempY = startY;

    let rowIndex = 0;

    let startX = (this.canvasWidth - widthArr[rowIndex]) / 2;

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

      let answerSpr = tempAnswerSprArr[i];
      answerSpr.bg.x = startX;
      answerSpr.bg.y = tempY;

      answerSpr.initX = startX;
      answerSpr.initY = tempY;

      if ((i + 1) % col == 0) {
        tempY += h + dH;
        rowIndex++;
        startX = (this.canvasWidth - widthArr[rowIndex]) / 2;
      }
      else {
        startX += answerSpr.dW + answerSpr.bg.width;
      }
    }
  }



  mapDown(event) {

    if (!this.canTouch) {
      return;
    }

    this.oldPos = { x: this.mx, y: this.my };

    if (this.curAudio) {
      if (!this.listening || this.curAudio != this.listening.audio) {
        this.curAudio.pause();
      }
    }

    //如果大卡片显示，则阻止后续点击事件
    if (this.bigCard.shown) {

      this.clickBigCard();

      return;
    }

    if (this.listening && this.checkClickTarget(this.listening.bg)) {

      this.curAudio = this.listening.play(() => {
        this.listening.reset();
      });

      return;
    }

    if (this.curAudio) {
      if (this.listening && this.curAudio == this.listening.audio) {
        this.listening.pauseAudio();
      }
      else {
        this.curAudio.pause();
      }

    }

    if (this.checkClickTarget(this.title.titleBg)) {
      this.curAudio = this.title.playAudio();
      return;
    }


    if (this.checkClickTarget(this.picBtn)) {
      this.clickPicBtn();
      return;
    }

    let clicked = false;

    let target;

    let callback;

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

      let answerSpr = this.answerSprArr[i];

      if (!answerSpr.canDrag) {
        continue;
      }

      if (this.checkClickTarget(answerSpr.bg)) {

        callback = this.clickLetter.bind(this);
        clicked = true;
        target = answerSpr;
        break;
      }
    }

    if (clicked) {
      callback(target);
      return;
    }

    if(this.pic && this.checkClickTarget(this.pic)){
      this.playAudio(this.curExercises.audioUrl, true);
      return;
    }

    if(this.richText && this.checkClickTarget(this.richText)){
      this.playAudio(this.curExercises.audioUrl, true);
      return;
    }
  }

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

    this.curDragItem.bg.strokeColor = this.curDragItem.lineColor;
    if (!this.isMove(this.curDragItem)) {
      return;
    }


    const addX = this.mx - this.oldPos.x;
    const addY = this.my - this.oldPos.y;
    this.curDragItem.bg.x += addX;
    this.curDragItem.bg.y += addY;

    this.curDragItem.bg.visible = true;

    let lineIndex = this.curDragItem.lineIndex;
    if(lineIndex != -1){
        let lineSpr = this.lineSprArr[lineIndex];
        if(lineSpr){
          lineSpr.hideLabel();
          lineSpr.answered = false;
          this.curDragItem.lineIndex = -1;
        }
        
    }

    this.oldPos = { x: this.mx, y: this.my };
  }

  mapUp(event) {
    if (!this.curDragItem) {
      return;
    }
    this.curDragItem.bg.strokeColor = this.curDragItem.lineColor;
    if (!this.isMove(this.curDragItem)) {
      this.curAudio = this.playAudio(this.curDragItem.data.audioUrl, true);

      this.curDragItem = null;
    }
    else {
      this.checkLetter();
    }
  }



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

  private clickPicBtn() {

    this.canTouch = false;

    let toX = (this.canvasWidth - this.bigCard.bg.width) / 2;
    let toY = (this.canvasHeight - this.bigCard.bg.height) / 2 + 28 * this.mapScale;

    this.playAudio('open');
    this.bigCard.showCard(toX, toY, () => {
      this.canTouch = true;
    })
  }

  private clickBigCard() {

    if (this.checkClickTarget(this.bigCard.closePic)) {

      this.playAudio('close');

      this.canTouch = false;

      let toX = this.picBtn.x;
      let toY = this.picBtn.y;

      this.bigCard.hideCard(toX, toY, () => {
        this.canTouch = true;
      })
      return;
    }

    if(this.checkClickTarget(this.bigCard.contentSpr)){

      if(this.curExercises){
        this.playAudio(this.curExercises.audioUrl, true);
      }
      
      return;
    }

  }

  isMove(item) {

    let result = false;

    if (!item) {
      return result;
    }

    let x = this.itemOldPos.x;
    let y = this.itemOldPos.y;

    if (Math.abs(x - this.mx) > 10 * this.mapScale || Math.abs(y - this.my) > 10 * this.mapScale) {
      result = true;
    }

    return result;
  }

  /**
   * 点击字母
   * @param item 
   */
  clickLetter(item: any) {
    if (!this.checkClickTarget(item.bg)) {
      return;
    }
    this.itemOldPos = { x: this.mx, y: this.my };
    this.curDragItem = item;

    let index = this.renderArr.indexOf(item.bg);

    if (index != -1) {
      this.renderArr.splice(index, 1);
    }
    item.bg.strokeColor = "#f26321";
    this.renderArr.push(item.bg);
  }

  /**
   * 检查拖拽单词是否匹配
   */
  checkLetter() {

    if (!this.curDragItem) {
      return;
    }

    let letterItem = this.curDragItem;
    this.curDragItem = null;

    this.canTouch = false;

    letterItem.lineIndex = -1;

    const back = () => {

      this.playAudio('back', true);

      let bg = letterItem.bg;

      let toX = letterItem.initX;
      let toY = letterItem.initY;
      letterItem.lineIndex = -1;

      tweenChange(bg, { x: toX, y: toY }, 0.3, () => {
        this.canTouch = true;
      })
    }

    let lineSpr;

    let lineIndex = -1;

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

      let tLineSpr = this.lineSprArr[i];
      let rect = tLineSpr.bg.getBoundingBox();
      rect.height += 30 * this.mapScale;
      if (this.checkPointInRect(this.mx, this.my, rect)) {
        lineIndex = i;
        lineSpr = tLineSpr;
        break;
      }

    }

    if (!lineSpr || lineSpr.answered) {
      back();
      return;
    }

    let answerSpr = this.answerSprArr[lineIndex];

    if(answerSpr.data.val != letterItem.data.val){
      back();
      return;
    }

    letterItem.lineIndex = lineIndex;

    this.playAudio('right', true);

    lineSpr.answered = true;
    letterItem.bg.x = lineSpr.bg.x + (letterItem.bg.width - letterItem.bg.width) / 2;
    letterItem.bg.y = lineSpr.bg.y + (letterItem.bg.height - letterItem.bg.height) / 2;
    letterItem.bg.visible = false;
    
    let val = letterItem.data.val;

    lineSpr.showLabel(val);

    lineSpr.letterItem = letterItem;

    let allAnswered = true;

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

      if (!this.lineSprArr[i].answered) {
        allAnswered = false;
        break;
      }
    }

    //如果全部答完，判断是否正确
    if (!allAnswered) {
      this.canTouch = true;
      return;
    }

    this.isRight();
  }

  private isRight() {

    let isRight = true;

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

      let answerSpr = this.answerSprArr[i];

      let compareSpr = this.lineSprArr[i].letterItem;

      if (answerSpr != compareSpr) {
        isRight = false;
        break;
      }
    }

    const back = (item) => {

      let bg = item.bg;

      let toX = item.initX;
      let toY = item.initY;
      item.lineIndex = -1;
      tweenChange(bg, { x: toX, y: toY }, 0.3, () => {
        this.canTouch = true;
        item.canDrag = true;
      })
    }

    //回答失败，则返回重选
    if (!isRight) {

      this.playAudio('back', true);

      for (let i = 0; i < this.answerSprArr.length; ++i) {
        let answerSpr = this.answerSprArr[i];

        let lineSpr = this.lineSprArr[i];

        lineSpr.hideLabel();
        lineSpr.answered = false;

        answerSpr.bg.visible = true;

        back(answerSpr);
      }
      return;
    }

    this.showRight();
  }

  private showRight() {

    for(let i = 0; i < this.lineSprArr.length; ++ i){
      let lineSpr = this.lineSprArr[i];
      removeItemFromArr(this.renderArr, lineSpr.bg);
      lineSpr.bg.visible = false;
    }

    this.lineSprArr = [];

    for(let i = 0; i < this.answerSprArr.length; ++ i){
      let answerSpr = this.answerSprArr[i];
      removeItemFromArr(this.renderArr, answerSpr.bg);

    }

    this.answerSprArr = [];

    let mW = 800 * this.mapScale;

    let mH = 397 * this.mapScale;

    const pic = new MySprite();
    pic.init(this.images.get(this.curExercises.picUrl));
    pic.x = this.canvasWidth / 2;
    pic.y = this.canvasHeight / 2 - 81 * this.mapScale;

    let scale = Math.min(mW / pic.width, mH / pic.height);
    pic.setScaleXY(scale);
    this.pic = pic;
    this.renderArr.push(pic);

    let richText = new RichText();
    richText.fontColor = '#2b292e';
    richText.fontName = 'MMB';
    richText.text = this.curExercises.val;
    richText.fontSize = 60;
    richText.textAlign = 'left';
    richText.disH = 10;
    richText.setScaleXY(this.mapScale);
    richText.maxWidth = 1120;
    richText.refreshSize();
    richText.x = ( this.canvasWidth - richText.getBoundingBox().width) / 2;
    richText.y = this.canvasHeight + 150 * this.mapScale;
    this.renderArr.push(richText);

    let toY = this.canvasHeight / 2 + 180 * this.mapScale;

    tweenChange(richText, {y : toY}, 0.5, () =>{
      this.canTouch = true;
    });

    this.richText = richText;

    this.picBtn.visible = false;
  }
}
