import {
  ApplicationRef,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  HostListener,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  Output,
  ViewChild
} from '@angular/core';
import {Subject} from 'rxjs';
import {debounceTime, retryWhen} from 'rxjs/operators';
import {DragItem, EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, HotZoneMultRect, Label, MySprite, removeItemFromArr, ShapeCircle, ShapeRect, ShapeRectNew} from './Unit';
import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from '../../play/Unit';
import {tar} from 'compressing';
import {NzMessageService} from 'ng-zorro-antd';


@Component({
  selector: 'app-custom-hot-zone',
  templateUrl: './custom-hot-zone.component.html',
  styleUrls: ['./custom-hot-zone.component.scss']
})
export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {

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


  @Input()
  hotZoneItemArr = null;
  @Input()
  hotZoneArr = null;
  @Input()
  isHasRect = true;
  @Input()
  isHasPic = true;
  @Input()
  isHasText = true;
  @Input()
  isHasAudio = true;
  @Input()
  isHasAnima = false;
  @Input()
  customTypeGroupArr; // [{name:string, rect:boolean, pic:boolean, text:boolean, audio:boolean, anima:boolean, animaNames:['name1', ..]}, ...]
  @Input()
  // hotZoneFontObj;
  @Input()
  isCopyData = false;

  @Input()
  isRotate = false;
  
  hotZoneFontObj;
  // hotZoneFontObj = {
  //   size: 50,
  //   name: 'ahronbd-1',
  //   color: '#8f3758'
  // }
  @Input()
  defaultItemType = 'text';
  @Input()
  hotZoneImgSize = 0;


  @Output()
  save = new EventEmitter();


  saveDisabled = true;

  canvasWidth = 1280;
  canvasHeight = 720;
  canvasBaseW = 1280;
  // @HostListener('window:resize', ['$event'])
  canvasBaseH = 720;
  mapScale = 1;
  ctx;
  mx;
  my; // 点击坐标
  // 声音
  bgAudio = new Audio();
  images = new Map();
  animationId: any;


  // 资源
  // rawImages = new Map(res);
  winResizeEventStream = new Subject();
  canvasLeft;
  canvasTop;
  renderArr;
  renderTopArr;
  imgArr = [];
  oldPos;
  radioValue;
  curItem;
  bg: MySprite;
  changeSizeFlag = false;
  changeTopSizeFlag = false;
  changeRightSizeFlag = false;
  animaPanelVisible = false;

  uploadUrl;
  uploadData;
  skeJsonData = {};
  texJsonData = {};
  texPngData = {};
  animaName = '';
  curDragonBoneIndex;
  curDragonBoneGIdx;
  pasteData = '';

  isSkeJsonLoading = false;
  isTexJsonLoading = false;
  isTexPngLoading = false;

  isAnimaSmall = false;

  savePropertyArr = [
    'id',
    'gIdx',
    'selectType',
    'labelText',
    'posX',
    'posY',
    'mathLabel',
    'checkbox',
    'dropDownItem'
  ]


  constructor(private nzMessageService: NzMessageService, private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
    this.uploadUrl = (<any> window).courseware.uploadUrl();
    this.uploadData = (<any> window).courseware.uploadData();

    window['air'].getUploadCallback = (url, data) => {
      this.uploadUrl = url;
      this.uploadData = data;
    };
  }

  _bgItem = null;

  get bgItem() {
    return this._bgItem;
  }

  @Input()
  set bgItem(v) {
    this._bgItem = v;

    this.init();
  }




  onResize(event) {
    this.winResizeEventStream.next();
  }


  ngOnInit() {


    this.initListener();

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

    this.refresh();

  }

  ngOnDestroy() {
    window.cancelAnimationFrame(this.animationId);
  }


  ngOnChanges() {

  }


  onBackgroundUploadSuccess(e) {
    console.log('e: ', e);
    this.bgItem.url = e.url;

    this.init();
    // this.refreshBackground();
  }

  onItemImgUploadSuccess(e, item) {
    item.pic_url = e.url;
    this.loadHotZonePic(item, item.pic, e.url);
    this.refresh();
  }

  onItemAudioUploadSuccess(e, item) {
    item.audio_url = e.url;
    this.refresh();
  }


  refreshBackground(callBack = null) {

    if (!this.bg) {
      this.bg = new MySprite(this.ctx);
      this.renderArr.push(this.bg);
    }

    if (!this.bgItem.url) {
      this.bgItem.url = 'http://teach.cdn.ireadabc.com/8ebb1858564340ea0936b83e3280ad7d.jpg';
    }

    const bg = this.bg;
    // if (this.bgItem.url) {

    bg.load(this.bgItem.url).then(() => {
      const rate1 = this.canvasWidth / bg.width;
      const rate2 = this.canvasHeight / bg.height;

      const rate = Math.min(rate1, rate2);
      bg.setScaleXY(rate);
      
      bg.x = this.canvasWidth / 2;
      bg.y = this.canvasHeight / 2;

      bg.removeChildren();

      const bgBorder = new ShapeRectNew(this.ctx);
      bgBorder.setSize(bg.width, bg.height, 0);
      bgBorder.fillColor = '#ff0000';
      bgBorder.fill = false;
      bgBorder.stroke = true;
      bgBorder.x = -bg.width / 2;
      bgBorder.y = -bg.height / 2;
      bgBorder.lineWidth = 0.5;
      bg.addChild(bgBorder);


      if (callBack) {
        callBack();
      }

      this.refresh();

    });
    // }

  }


  addBtnClick(data=null) {
    // this.imgArr.push({});
    // this.hotZoneArr.push({});

    const item = this.getHotZoneItem(data);
    this.hotZoneArr.push(item);


    if (this.customTypeGroupArr) {
      this.refreshCustomItem(item);
    } else {
      this.refreshItem(item);
    }

    this.refreshHotZoneId();

  }

  deleteBtnClick(index) {

    const item = this.hotZoneArr.splice(index, 1)[0];
    removeItemFromArr(this.renderArr, item.pic);
    removeItemFromArr(this.renderArr, item.textLabel);
    removeItemFromArr(this.renderArr, item.drag);
    removeItemFromArr(this.renderArr, item.centerDot);

    this.refreshHotZoneId();

  }

  onImgUploadSuccessByImg(e, img) {
    img.pic_url = e.url;
    this.refreshImage(img);
    this.refresh();
  }

  refreshImage(img) {

    this.hideAllLineDash();

    img.picItem = this.getPicItem(img);

    this.refreshImageId();

  }


  refreshHotZoneId() {
    for (let i = 0; i < this.hotZoneArr.length; i++) {
      this.hotZoneArr[i].index = i;

      if (this.hotZoneArr[i]) {
        this.hotZoneArr[i].title = 'item-' + (i + 1);

      }
    }
    this.refresh();
  }


  refreshImageId() {
    for (let i = 0; i < this.imgArr.length; i++) {
      this.imgArr[i].id = i;

      if (this.imgArr[i].picItem) {
        this.imgArr[i].picItem.text = 'Image-' + (i + 1);
      }
    }

  }

  getHotZoneItem(saveData = null) {

    const itemW = 200;
    const itemH = 200;
    const item = new HotZoneItem(this.ctx);
    item.setSize(itemW, itemH);
    item.anchorX = 0.5;
    item.anchorY = 0.5;


    item.x = this.canvasWidth / 2;
    item.y = this.canvasHeight / 2;

    item.itemType = this.getDefaultItemType();
    item.gIdx = '0';


    item['id'] = this.createItemId() // new Date().getTime().toString();
    item['data'] = saveData;

    console.log('item.x: ', item.x);

    if (saveData) {

      const saveRect = saveData.rect;
      item.scaleX = saveRect.width / item.width;
      item.scaleY = saveRect.height / item.height;
      item.x = saveRect.x + saveRect.width / 2;
      item.y = saveRect.y + saveRect.height / 2;
      item.gIdx = saveData.gIdx;

      item['id'] = saveData.id;
      item['skeJsonData'] = saveData.skeJsonData;
      item['texJsonData'] = saveData.texJsonData;
      item['texPngData'] = saveData.texPngData;


      item['actionData_' + item.gIdx] = saveData['actionData_' + item.gIdx];

      this.savePropertyArr.forEach((key) => {
        if (saveData[key]) {
          item[key] = saveData[key];
        }
      })


    }

    console.log('item.x:~~ ', item.x);

    item.showLineDash();

    // const pic = new HotZoneImg(this.ctx);
  

    this.setItemPic(item, saveData);

    this.setItemLabel(item, saveData);

    this.setItemAnima(item, saveData);

    this.setItemDrag(item, saveData);

    this.setItemCenterDot(item, saveData);

    this.setItemMultRect(item, saveData);

    return item;
  }



  setItemPic(item, saveData) {

    console.log('in setItemPic ', saveData);
    const pic = new EditorItem(this.ctx);
    pic.visible = false;
    item['pic'] = pic;
    if (saveData) {

      let picUrl = saveData.pic_url;
      const actionData = saveData['actionData_' + item.gIdx];
      if (actionData && actionData.type == 'pic') {
        picUrl = actionData.pic_url;
      }

      console.log('saveData: ', saveData);
      console.log('picUrl: ', picUrl);

      if (picUrl) {
        this.loadHotZonePic(item, pic, picUrl, saveData.imgScale);
      }
    }

    pic.x = item.x;
    pic.y = item.y;
    this.renderArr.push(pic);
  }


  setItemDrag(item, saveData) {

    console.log('in setItemDrag ', saveData);
    const dragItem = new DragItem(this.ctx);
    dragItem.init();
    dragItem.item = item;
    item['drag'] = dragItem;

    dragItem.visible = false;

    dragItem.x = item.x;
    dragItem.y = item.y;
    this.renderArr.push(dragItem);

    if (saveData) {
      if (saveData.dragDot) {
        dragItem.x = saveData.dragDot.x / saveData.mapScale * this.mapScale;
        dragItem.y = saveData.dragDot.y / saveData.mapScale * this.mapScale;
      }  
    }

   
  }

  setItemAnima(item, saveData) {
    console.log('in setItemAnima ', saveData);
    // const pic = new EditorItem(this.ctx);
    // pic.visible = false;
    // item['pic'] = pic;
    // if (saveData) {

    //   let picUrl = saveData.pic_url;
    //   const actionData = saveData['actionData_' + item.gIdx];
    //   if (actionData && actionData.type == 'pic') {
    //     picUrl = actionData.pic_url;
    //   }

    //   console.log('saveData: ', saveData);
    //   console.log('picUrl: ', picUrl);

    //   if (picUrl) {
    //     this.loadHotZonePic(pic, picUrl, saveData.imgScale);
    //   }
    // }

    // pic.x = item.x;
    // pic.y = item.y;
    // this.renderArr.push(pic);
  }

  setItemCenterDot(item, saveData) {
    console.log('in setItemDrag ', saveData);
    const circle = new ShapeCircle(this.ctx);
    circle.setRadius(6);
    // circle.fillColor = '#9834ff'
    item['centerDot'] = circle;

    circle.visible = false;

    circle.x = item.x;
    circle.y = item.y;
    this.renderArr.push(circle);

    if (saveData) {
      if (saveData.dragDot) {
        circle.x = saveData.dragDot.x / saveData.mapScale * this.mapScale;
        circle.y = saveData.dragDot.y / saveData.mapScale * this.mapScale;
      }  
    }
  }

  setItemMultRect(item, saveData) {

    console.log(" in setItemMultRect")



    if (saveData && saveData.multRect) {

      this.setItemMultRectByData(item, saveData.multRect);
      console.log("multRect ~", saveData.multRect);
    }
  }

  cleanMultRect(multRectArr) {
    for (let i=0; i<multRectArr.length; i++) {
      removeItemFromArr(this.renderTopArr, multRectArr[i]);
    }
  }

  setItemMultRectByData(item, multRectDataArr) {


    if (item.multRectArr) {
      this.cleanMultRect(item.multRectArr);
    }


    let curBgRect;
    if (this.bg) {
      curBgRect = this.bg.getBoundingBox();
    } else {
      curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
    }

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

    const rate = curBgRect.width / oldBgRect.width;


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

      const multRectData = multRectDataArr[i];

      const multRectItem = new HotZoneMultRect(this.ctx);
      multRectItem.showLineDash();
      multRectItem.anchorX = 0.5;
      multRectItem.anchorY = 0.5;
      multRectItem.rectEdgeColor = multRectData.color;
      multRectItem.showLabel("M-" + (i+1));
      multRectItem.item = item;
  
      multRectItem.visible = true;
  
      if (!multRectData.rect) {
        //无数据小矩形

        multRectItem.setSize(multRectData.width, multRectData.height);
        multRectItem.x = item.x + multRectItem.width * i * 0.3;
        multRectItem.y = item.y + multRectItem.width * i * 0.3;
      } else {
        //有数据小矩形

        console.log('multRectData.rect: ', multRectData.rect);

        const saveRect = multRectData.rect;

        saveRect.x *= rate;
        saveRect.y *= rate;
        saveRect.width *= rate;
        saveRect.height *= rate;
        saveRect.x += curBgRect.x;
        saveRect.y += curBgRect.y;
  

        multRectItem.setSize(saveRect.width, saveRect.height);

        multRectItem.scaleX = saveRect.width / multRectItem.width;
        multRectItem.scaleY = saveRect.height / multRectItem.height;
        multRectItem.x = saveRect.x + saveRect.width / 2;
        multRectItem.y = saveRect.y + saveRect.height / 2;

      }
     
      this.renderTopArr.push(multRectItem);
      arr.push(multRectItem);
    }

    item.multRectArr = arr;

  }


  setItemLabel(item, saveData) {

    const textLabel = new HotZoneLabel(this.ctx);
    if (this.hotZoneFontObj) {
      textLabel.fontSize = this.hotZoneFontObj.size;
      textLabel.fontName = this.hotZoneFontObj.name;
      textLabel.fontColor = this.hotZoneFontObj.color;
    }

    textLabel.textAlign = 'center';
    // textLabel.setOutline();
    item['textLabel'] = textLabel;
    textLabel.setScaleXY(this.mapScale);
    if (saveData) {

      if (saveData.text && this.hotZoneFontObj) {
        textLabel.text = saveData.text
      }

      this.setActionFont(textLabel, saveData['actionData_' + item.gIdx]);
      textLabel.refreshSize();

    }
    textLabel.x = item.x;
    textLabel.y = item.y;
    this.renderArr.push(textLabel);
  }

  setActionFont(textLabel, actionData) {
    if (actionData && actionData.type == 'text') {

      textLabel.text = actionData.text;

      for (let i=0; i<actionData.changeOption.length; i++) {
        const op = actionData.changeOption[i];
        textLabel[op[0]] = op[1];
      }
    }
  }

  getDefaultItemType() {
    if (this.customTypeGroupArr) {
      const group = this.customTypeGroupArr[0];
      if (group.rect) {
        return 'rect';
      }
      if (group.pic) {
        return 'pic';
      }
      if (group.text) {
        return 'text';
      }
    } else {
      return this.defaultItemType;
    }
  }

  getPicItem(img, saveData = null) {


    const item = new EditorItem(this.ctx);
    item.load(img.pic_url).then(img => {

      let maxW, maxH;
      if (this.bg) {
        maxW = this.bg.width * this.bg.scaleX;
        maxH = this.bg.height * this.bg.scaleY;
      } else {
        maxW = this.canvasWidth;
        maxH = this.canvasHeight;
      }

      let scaleX = maxW / 3 / item.width;
      let scaleY = maxH / 3 / item.height;

      if (item.height * scaleX < this.canvasHeight) {
        item.setScaleXY(scaleX);
      } else {
        item.setScaleXY(scaleY);
      }
      item.x = this.canvasWidth / 2;
      item.y = this.canvasHeight / 2;

      if (saveData) {

        const saveRect = saveData.rect;
        item.setScaleXY(saveRect.width / item.width);
        item.x = saveRect.x + saveRect.width / 2;
        item.y = saveRect.y + saveRect.height / 2;

      } else {
        // item.showLineDash();
      }

      item.showLineDash();
      console.log('aaa');
    });
    return item;
  }


  onAudioUploadSuccessByImg(e, img) {
    img.audio_url = e.url;
    this.refresh();
  }

  deleteItem(e, i) {
    // this.imgArr.splice(i , 1);
    // this.refreshImageId();

    this.hotZoneArr.splice(i, 1);
    this.refreshHotZoneId();
    this.refresh();
  }
  


  // radioChange(e, item) {
  //   item.itemType = e;

  //   this.refreshItem(item);
  //   this.refresh();
  //   // console.log(' in radioChange e: ', e);
  // }

  customRadioChange(e, item) {

    console.log('in customRadioChange', e);
    item.gIdx = -1;
    setTimeout(() => {
      item.gIdx = e;
      this.refreshCustomItem(item);
      this.refresh();
    }, 1);
    
    // const curGroup = this.customTypeGroupArr[e];

  }

  refreshCustomItem(item) {


    this.hideHotZoneItem(item);
    const group = this.customTypeGroupArr[item.gIdx];
    if (!group) {
      return;
    }

    if (group.text) {
      this.showItemLabel(item);
    }

    if (group.rect) {
      this.showItemRect(item, !group.isFixed);
    }

    if (group.pic) {
     this.showItemPic(item);
    }

    if (group.centerDot) {
      console.log('item: ~~~~', item)

      this.showItemCenterDot(item);
    }

    if (group.action) {
      if (group.action.type == 'pic') {
        this.showItemPic(item);
      }
      if (group.action.type == 'text') {
        this.showItemLabel(item);
      }
      if (group.action.type == 'anima') {
        this.showItemRect(item);
      }
    }

    if (group.checkbox) {
      if (!item.checkbox) {
        item.checkbox = JSON.parse(JSON.stringify(group.checkbox)) ;
      }
    }

    if (group.multRect) {
      this.showItemMultRect();
    }

    

    item.drag.visible = group.drag;

    item.setAnimaStyle(group.animaSmall)
  

  }

  showItemMultRect() {

  }

  showItemDrag(item) {
    item.drag.visible = true;
    // item.dragBody.visible = true;
    // item.itemType = 'pic';
    // this.showArrowTop(item)
  }

  showItemCenterDot(item) {
    item.centerDot.visible = true;
  }

  showItemPic(item) {
    item.pic.visible = true;
    item.itemType = 'pic';
    this.showArrowTop(item)
  }

  showItemLabel(item) {
    item.textLabel.visible = true;
    item.itemType = 'text';
    this.showArrowTop(item)
  }

  showItemRect(item, isShowArrowTop = true) {
    item.visible = true;
    item.itemType = 'rect';
    this.showArrowTop(item, isShowArrowTop)
  }

  showArrowTop(item, isShowArrowTop = false) {
    if (isShowArrowTop) {
      item.arrowTop.visible = true;
      item.arrowRight.visible = true;
    } else {
      item.arrowTop.visible = false;
      item.arrowRight.visible = false;
    }
  }

  hideHotZoneItem(item) {
    item.visible = false;
    item.pic.visible = false;
    item.textLabel.visible = false;
    item.centerDot.visible = false;
  }

  refreshItem(item) {

    //弃用

    switch (item.itemType) {
      case 'rect':
        this.setRectState(item);
        break;
      case 'pic':
        this.setPicState(item);
        break;
      case 'text':
        this.setTextState(item);
        break;
      default:
        this.setNoneState(item);
    }
  }


  init() {

    console.log('init');
    this.initData();
    this.initCtx();
    this.initItem();
  }

  initItem() {

    this.changeDetectorRef.markForCheck();
    this.changeDetectorRef.detectChanges();

    if (!this.bgItem) {
      this.bgItem = {};
    } else {

      const oldId = this.initId;
      this.refreshBackground(() => {
      
        if (oldId != this.initId) {
          return;
        }

        console.log(' in refreshBackground')
        if (!this.hotZoneItemArr) {
          this.hotZoneItemArr = [];
        } else {
          this.initHotZoneArr();
        }

      });
    }

    this.refresh();
  }

  initHotZoneArr() {

    // console.log('this.hotZoneArr: ', this.hotZoneArr);
    let curBgRect;
    if (this.bg) {
      curBgRect = this.bg.getBoundingBox();
    } else {
      curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
    }

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

    const rate = curBgRect.width / oldBgRect.width;

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

    this.hotZoneArr = [];
    const arr = this.hotZoneItemArr.concat();
    console.log('this.hotZoneItemArr: ', this.hotZoneItemArr);
    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;

      // img['picItem'] = this.getPicItem(img, data);
      // img['audio_url'] = arr[i].audio_url;
      // this.imgArr.push(img);

      const item = this.getHotZoneItem(data);
      item.audio_url = data.audio_url;
      item.pic_url = data.pic_url;
      item.text = data.text;
      item.itemType = data.itemType;

      if (this.customTypeGroupArr) {
        this.refreshCustomItem(item);
      } else {
        this.refreshItem(item);
      }


      console.log('1 item: ', item);
      this.hotZoneArr.push(item);

    }

    this.refreshHotZoneId();

    // this.refreshImageId();

  }

  initId
  initData() {

    console.log(' in initData')

    this.canvasWidth = this.wrap.nativeElement.clientWidth;
    this.canvasHeight = this.wrap.nativeElement.clientHeight;
    this.mapScale = this.canvasWidth / this.canvasBaseW;
    this.renderArr = [];
    this.renderTopArr = [];
    this.bg = null;

    this.imgArr = [];
    this.hotZoneArr = [];

    this.initId = new Date().getTime();
  }

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


  mapDown(event) {

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

    
    // 先检测拖拽点
    for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
      
      const item = this.hotZoneArr[i];

      if (item && item.drag && item.drag.visible) {

        if (this.checkClickTarget(item.drag)) {

          this.clickedDragPoint(item.drag);
          return;
        }
      }
    }

    // 检测多矩形
    for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
    
      const item = this.hotZoneArr[i];

      if (item && item.multRectArr) {

        for (let j=item.multRectArr.length - 1; j>=0; j--) {
          if (this.checkClickTarget(item.multRectArr[j])) {
            this.clickedMultRect(item.multRectArr[j]); 
            return;
          }
        }
      }
    }


    for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
      
      const item = this.hotZoneArr[i];

      console.log('mapDown item: ', item);
      let callback;
      let target;
      switch (item.itemType) {
        case 'rect':
          target = item;
          callback = this.clickedHotZoneRect.bind(this);
          break;
        case 'pic':
          target = item.pic;
          callback = this.clickedHotZonePic.bind(this);
          break;
        case 'text':
          target = item.textLabel;
          callback = this.clickedHotZoneText.bind(this);
          break;
      }

      if (target && this.checkClickTarget(target)) {
        callback(target);
        return;
      }
    }


  }


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

    if (this.changeSizeFlag) {
      this.changeSize();

    } else if (this.changeTopSizeFlag) {
      this.changeTopSize();

    } else if (this.changeRightSizeFlag) {
      this.changeRightSize();

    } else {

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

      this.curItem.posX = this.curItem.x;
      this.curItem.posY = this.curItem.y;
    }

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

    // this.saveDisabled = false;

  }

  mapUp(event=null) {
    this.curItem = null;
    this.changeSizeFlag = false;
    this.changeTopSizeFlag = false;
    this.changeRightSizeFlag = false;
  }


  changeSize() {
    const rect = this.curItem.getBoundingBox();

    let lenW = (this.mx - (rect.x + rect.width / 2)) * 2;
    let lenH = ((rect.y + rect.height / 2) - this.my) * 2;


    let minLen = 20;
    let s;
    if (lenW < lenH) {
      if (lenW < minLen) {
        lenW = minLen;
      }
      s = lenW / this.curItem.width;

    } else {
      if (lenH < minLen) {
        lenH = minLen;
      }
      s = lenH / this.curItem.height;
    }


    // console.log('s: ', s);
    this.curItem.setScaleXY(s);
    this.curItem.refreshLabelScale();
  }


  changeTopSize() {
    const rect = this.curItem.getBoundingBox();

    // let lenW = ( this.mx - (rect.x + rect.width / 2) ) * 2;
    let lenH = ((rect.y + rect.height / 2) - this.my) * 2;


    let minLen = 20;
    let s;
    // if (lenW < lenH) {
    //   if (lenW < minLen) {
    //     lenW = minLen;
    //   }
    //   s = lenW / this.curItem.width;
    //
    // } else {
    if (lenH < minLen) {
      lenH = minLen;
    }
    s = lenH / this.curItem.height;
    // }


    // console.log('s: ', s);
    this.curItem.scaleY = s;
    this.curItem.refreshLabelScale();
  }

  changeRightSize() {
    const rect = this.curItem.getBoundingBox();

    let lenW = (this.mx - (rect.x + rect.width / 2)) * 2;
    // let lenH = ( (rect.y + rect.height / 2) - this.my ) * 2;

    let minLen = 20;
    let s;
    if (lenW < minLen) {
      lenW = minLen;
    }
    s = lenW / this.curItem.width;

    this.curItem.scaleX = s;
    this.curItem.refreshLabelScale();
  }

  changeItemSize(item) {
    this.curItem = item;
    this.changeSizeFlag = true;
  }

  changeItemTopSize(item) {
    this.curItem = item;
    this.changeTopSizeFlag = true;
  }

  changeItemRightSize(item) {
    this.curItem = item;
    this.changeRightSizeFlag = true;
  }

  changeCurItem(item) {

    console.log(' in changeCurItem', item)

    this.hideAllLineDash();

    this.curItem = item;
    this.curItem.showLineDash();

  }

  hideAllLineDash() {

    for (let i = 0; i < this.imgArr.length; i++) {
      if (this.imgArr[i].picItem) {
        this.imgArr[i].picItem.hideLineDash();
      }
    }
  }


  update() {
    if (!this.ctx) {
      return;
    }


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

  

    // for (let i = 0; i < this.imgArr.length; i++) {
    //   const picItem = this.imgArr[i].picItem;
    //   if (picItem) {
    //     picItem.update(this);
    //   }
    // }

    

    for (let i = 0; i < this.renderArr.length; i++) {
      this.renderArr[i].update(this);
    }

    this.updateArr(this.hotZoneArr);

    this.updateArr(this.renderTopArr);

   

    this.updatePos();



    TWEEN.update();
  }

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


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

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

  IsPC() {
    if (window['ELECTRON']) {
      return false; // 封装客户端标记
    }
    if (document.body.ontouchstart !== undefined) {
      return false;
    } else {
      return true;
    }
  }


  checkClickTarget(target) {
    if (!target || !target.visible) {
      return;
    }
    const rect = target.getBoundingBox();
    if (this.checkPointInRect(this.mx, this.my, rect)) {
      return true;
    }
    return false;
  }

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


  saveClick() {

    const sendData = this.getSendData();
    this.save.emit(sendData);
  }

  getSendData() {

    const bgItem = this.bgItem;
    if (this.bg) {
      const rect = this.bg.getBoundingBox();
      bgItem['rect'] = rect;
      rect.x = Math.round(rect.x * 100) / 100;
      rect.y = Math.round(rect.y * 100) / 100;
      rect.width = Math.round(rect.width * 100) / 100;
      rect.height = Math.round(rect.height * 100) / 100;
    } else {
      bgItem['rect'] = {
        x: 0,
        y: 0,
        width: Math.round(this.canvasWidth * 100) / 100,
        height: Math.round(this.canvasHeight * 100) / 100
      };
    }


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

      const hotZoneItem = {
        id: hotZoneArr[i].id,
        index: hotZoneArr[i].index,
        pic_url: hotZoneArr[i].pic_url,
        text: hotZoneArr[i].text,
        audio_url: hotZoneArr[i].audio_url,
        itemType: hotZoneArr[i].itemType,
        fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1,
        imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1,
        imgSizeW: hotZoneArr[i].pic ? hotZoneArr[i].pic.width : 0,
        imgSizeH: hotZoneArr[i].pic ? hotZoneArr[i].pic.height : 0,
        mapScale: this.mapScale,
        skeJsonData: hotZoneArr[i].skeJsonData,
        texJsonData: hotZoneArr[i].texJsonData,
        texPngData: hotZoneArr[i].texPngData,
        dragDot: hotZoneArr[i].drag.getPosition(),
        gIdx: hotZoneArr[i].gIdx,
      };

      this.savePropertyArr.forEach((key) => {
        if (hotZoneArr[i][key]) {
          hotZoneItem[key] = hotZoneArr[i][key];
        }
      })

      if (hotZoneArr[i].multRectArr) {
        const tempArr = [];
        hotZoneArr[i].multRectArr.forEach(element => {
          const rectData = element.getBoundingBox();
          rectData.x = Math.round((rectData.x - bgItem['rect'].x) * 100) / 100;
          rectData.y = Math.round((rectData.y - bgItem['rect'].y) * 100) / 100;
          rectData.width = Math.round((rectData.width) * 100) / 100;
          rectData.height = Math.round((rectData.height) * 100) / 100;

          const oneData = {rect: rectData, color: element.rectEdgeColor}
          tempArr.push(oneData);
        });
        hotZoneItem['multRect'] = tempArr;
      }

      hotZoneItem['actionData_' + hotZoneItem.gIdx] = hotZoneArr[i]['actionData_' + hotZoneArr[i].gIdx]


      if (this.hotZoneFontObj) {
        hotZoneItem['fontSize'] = this.hotZoneFontObj.size;
        hotZoneItem['fontName'] = this.hotZoneFontObj.name;
        hotZoneItem['ontColor'] = this.hotZoneFontObj.color;
      }


      if (hotZoneArr[i].itemType == 'pic') {
        hotZoneItem['rect'] = hotZoneArr[i].pic.getBoundingBox();
      } else if (hotZoneArr[i].itemType == 'text') {
        hotZoneArr[i].textLabel.refreshSize();
        hotZoneItem['rect'] = hotZoneArr[i].textLabel.getLabelRect();
        // hotZoneItem['rect'].width =  hotZoneItem['rect'].width / hotZoneArr[i].textLabel.scaleX;
        // hotZoneItem['rect'].height = hotZoneArr[i].textLabel.height * hotZoneArr[i].textLabel.scaleY;

      } else {
        hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
      }
      // hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
      hotZoneItem['rect'].x = Math.round((hotZoneItem['rect'].x - bgItem['rect'].x) * 100) / 100;
      hotZoneItem['rect'].y = Math.round((hotZoneItem['rect'].y - bgItem['rect'].y) * 100) / 100;
      hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100;
      hotZoneItem['rect'].height = Math.round((hotZoneItem['rect'].height) * 100) / 100;


      hotZoneItemArr.push(hotZoneItem);
    }

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

    return {bgItem, hotZoneItemArr};
  }

  saveText(item) {
    if (item.itemType == 'text') {
      item.textLabel.text = item.text;
    }
  }

  saveItemPos(item) {
  
    console.log('item.posX: ', item.posX)
    console.log('item.posY: ', item.posY)

      item.x = Number(item.posX || 0)
      item.y = Number(item.posY || 0)
  

 
    this.changeCurItem(item);



    this.curItem.x = Number(item.posX || 0);
    this.curItem.y = Number(item.posY || 0);

    this.mapUp();


  }

  onSaveCustomAction(e, item) {
  
    const data = e;
    item['actionData_' + item.gIdx] = data;

    if (data.type == 'pic') {
      let picUrl = data.pic_url;
      if (picUrl) {
        this.loadHotZonePic(item, item.pic, picUrl);
      }
    }
   
    if (data.type == 'text') {
      this.setActionFont(item.textLabel, data);
      item.textLabel.refreshSize();
    }
   
    // if (data.type == 'anima') {
    //   this.setActionAnima(item.anima, data);
    // }
    
    // this.loadHotZonePic(item.pic, e.url);
    this.refresh()
  }
 
  setActionAnima() {

  }
  

  setAnimaBtnClick(index) {

    console.log('aaaa')
    this.isAnimaSmall = false;

    this.setCurDragonBone(index);

    // this.curDragonBoneIndex = index;
    // this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);

    // const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];

    // this.skeJsonData = skeJsonData || {};
    // this.texJsonData = texJsonData || {};
    // this.texPngData = texPngData || {};

    // this.animaPanelVisible = true;

    // this.refresh();
  }

  
  setAnimaSmallBtnClick(index) {


    console.log('bbb')
    this.isAnimaSmall = true;

    this.setCurDragonBone(index);

  }

  setCurDragonBone(index) {
    this.curDragonBoneIndex = index;
    this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);

    const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];

    this.skeJsonData = skeJsonData || {};
    this.texJsonData = texJsonData || {};
    this.texPngData = texPngData || {};

    this.animaPanelVisible = true;

    this.refresh();
  }

  setItemSizeByAnima(jsonData, item) {
    console.log('json: ', jsonData);

    const request = new XMLHttpRequest();
    //通过url获取文件，第二个选项是文件所在的具体地址
    request.open('GET', jsonData.url, true);
    request.send(null);
    request.onreadystatechange = ()=> {
    if (request.readyState === 4 && request.status === 200) {
        var type = request.getResponseHeader('Content-Type');
              if (type.indexOf("text") !== 1) {
                  //返回一个文件内容的对象

                  const data = JSON.parse(request.responseText);
                  console.log('request.responseText;', data)
                  const animaSize = data.armature[0].canvas;
                  item.width = animaSize.width;
                  item.height = animaSize.height;
                  // return request.responseText;
              }
          }
    }
  }

  animaPanelCancel() {
    this.animaPanelVisible = false;
    this.refresh();
  }

  animaPanelOk() {

    this.setItemDragonBoneData(this.hotZoneArr[this.curDragonBoneIndex]);
    console.log('this.hotZoneArr: ', this.hotZoneArr);
    this.animaPanelVisible = false;

    if (this.isAnimaSmall) {
      this.setItemSizeByAnima(this.skeJsonData, this.hotZoneArr[this.curDragonBoneIndex]);
    }

    this.refresh();
  }

  setItemDragonBoneData(item) {
    item['skeJsonData'] = this.skeJsonData;
    item['texJsonData'] = this.texJsonData;
    item['texPngData'] = this.texPngData;
  }

  skeJsonHandleChange(e) {
    console.log('e: ', e);
    switch (e.type) {
      case 'start':
        this.isSkeJsonLoading = true;
        break;

      case 'success':
        this.skeJsonData['url'] = e.file.response.url;
        this.skeJsonData['name'] = e.file.name;
        this.nzMessageService.success('上传成功');
        this.isSkeJsonLoading = false;
        break;

      case 'progress':
        break;
    }
  }

  texJsonHandleChange(e) {
    console.log('e: ', e);
    switch (e.type) {
      case 'start':
        this.isTexJsonLoading = true;
        break;

      case 'success':
        this.texJsonData['url'] = e.file.response.url;
        this.texJsonData['name'] = e.file.name;
        this.nzMessageService.success('上传成功');
        this.isTexJsonLoading = false;
        break;

      case 'progress':
        break;
    }
  }

  texPngHandleChange(e) {
    console.log('e: ', e);
    switch (e.type) {
      case 'start':
        this.isTexPngLoading = true;
        break;

      case 'success':
        this.texPngData['url'] = e.file.response.url;
        this.texPngData['name'] = e.file.name;
        this.nzMessageService.success('上传成功');
        this.isTexPngLoading = false;
        break;

      case 'progress':
        break;
    }
  }
  

  copyItem(it) {

    const {hotZoneItemArr} = this.getSendData();
    let itemData;
    hotZoneItemArr.forEach((data) => {
      if (data.id == it.id) {
        itemData = JSON.parse( JSON.stringify(data) );
      }
    })


    let curBgRect;
    if (this.bg) {
      curBgRect = this.bg.getBoundingBox();
    } else {
      curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
    }

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

    const rate = curBgRect.width / oldBgRect.width;

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


    const data = itemData
  
    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 item = this.getHotZoneItem(data);
    item.audio_url = data.audio_url;
    item.pic_url = data.pic_url;
    item.text = data.text;
    item.itemType = data.itemType;

    this.hotZoneArr.push(item);

    if (this.customTypeGroupArr) {
      this.refreshCustomItem(item);
    } else {
      this.refreshItem(item);
    }

    this.refreshHotZoneId();

    item['id'] = this.createItemId();

  }

  createItemId() {
    return new Date().getTime().toString();
  }

  copyHotZoneData() {

    const {bgItem, hotZoneItemArr} = this.getSendData();

    // const hotZoneItemArrNew = [];
    // const tmpArr = JSON.parse(JSON.stringify(hotZoneItemArr));
    // tmpArr.forEach((item) => {
    //   if (item.gIdx === '0') {
    //     hotZoneItemArr.push(item);
    //   }
    // })

    const jsonData = {
      bgItem,
      hotZoneItemArr,
      isHasRect: this.isHasRect,
      isHasPic: this.isHasPic,
      isHasText: this.isHasText,
      isHasAudio: this.isHasAudio,
      isHasAnima: this.isHasAnima,
      hotZoneFontObj: this.hotZoneFontObj,
      defaultItemType: this.defaultItemType,
      hotZoneImgSize: this.hotZoneImgSize,
    };


    const oInput = document.createElement('input');
    oInput.value = JSON.stringify(jsonData);
    document.body.appendChild(oInput);
    oInput.select(); // 选择对象
    document.execCommand('Copy'); // 执行浏览器复制命令

    document.body.removeChild(oInput);
    this.nzMessageService.success('复制成功');
    // alert('复制成功');


  }

  importData() {
    if (!this.pasteData) {
      return;
    }


    try {
      const data = JSON.parse(this.pasteData);
      console.log('data:', data);
      const {
        bgItem,
        hotZoneItemArr,
        isHasRect,
        isHasPic,
        isHasText,
        isHasAudio,
        isHasAnima,
        hotZoneFontObj,
        defaultItemType,
        hotZoneImgSize,
      } = data;

      this.hotZoneItemArr = hotZoneItemArr;
      this.isHasRect = isHasRect;
      this.isHasPic = isHasPic;
      this.isHasText = isHasText;
      this.isHasAudio = isHasAudio;
      this.isHasAnima = isHasAnima;
      this.hotZoneFontObj = hotZoneFontObj;
      this.defaultItemType = defaultItemType;
      this.hotZoneImgSize = hotZoneImgSize;

      this.bgItem = bgItem;

      this.pasteData = '';
    } catch (e) {
      console.log('err: ', e);
      this.nzMessageService.error('导入失败');
    }
  }

  private updatePos() {
    this.hotZoneArr.forEach((item) => {
      let x, y;
      switch (item.itemType) {
        case 'rect':
          x = item.x;
          y = item.y;
          break;

        case 'pic':
          x = item.pic.x;
          y = item.pic.y;
          break;

        case 'text':
          x = item.textLabel.x;
          y = item.textLabel.y;
          break;
      }

   

      if (x != undefined && y != undefined) {
        item.x = x;
        item.y = y;
        item.pic.x = x;
        item.pic.y = y;
        item.textLabel.x = x;
        item.textLabel.y = y;
        item.centerDot.x = x;
        item.centerDot.y = y;
      }

    });
  }

  private setPicState(item: any) {
    item.visible = false;
    item.textLabel.visible = false;
    item.pic.visible = true;
  }

  private setRectState(item: any) {
    item.visible = true;
    item.textLabel.visible = false;
    item.pic.visible = false;
  }

  private setTextState(item: any) {
    item.visible = false;
    item.pic.visible = false;
    item.textLabel.visible = true;
  }

  private setNoneState(item: any) {
    item.visible = false;
    item.pic.visible = false;
    item.textLabel.visible = false;
  }

  private clickedHotZoneRect(item: any) {
    if (this.checkClickTarget(item)) {

      if (item.lineDashFlag && this.checkClickTarget(item.arrow)) {
        this.changeItemSize(item);
      } else if (item.lineDashFlag && this.checkClickTarget(item.arrowTop)) {
        this.changeItemTopSize(item);
      } else if (item.lineDashFlag && this.checkClickTarget(item.arrowRight)) {
        this.changeItemRightSize(item);
      } else {
        this.changeCurItem(item);
      }
      return;
    }
  }

  private clickedHotZonePic(item: any) {
    if (this.checkClickTarget(item)) {

      if (item.lineDashFlag && this.checkClickTarget(item.arrow)) {
        this.changeItemSize(item);
        // } else if (item.lineDashFlag && this.checkClickTarget(item.arrowTop)) {
        //   this.changeItemTopSize(item);
        // } else if (item.lineDashFlag && this.checkClickTarget(item.arrowRight)) {
        //   this.changeItemRightSize(item);
      } else {
        this.changeCurItem(item);
      }

      this.curItem = item;
    }
  }

  private clickedHotZoneText(item: any) {
    if (this.checkClickTarget(item)) {
      this.curItem = item;
    }
  }

  private clickedMultRect(multRect: any) {
    
    if (this.checkClickTarget(multRect)) {
      if (multRect.lineDashFlag && this.checkClickTarget(multRect.arrow)) {
        this.changeItemSize(multRect);
      } 
      else if (multRect.lineDashFlag && this.checkClickTarget(multRect.arrowTop)) {
        this.changeItemTopSize(multRect);
      } else if (multRect.lineDashFlag && this.checkClickTarget(multRect.arrowRight)) {
        this.changeItemRightSize(multRect);
      } else {
        this.changeCurItem(multRect);
      }
      return;
    }
  }

  clickedDragPoint(item) {
    this.curItem = item;
  }

  checkboxChange(checkbox, hzItem) {
    console.log('checkbox: ', checkbox);
    hzItem.checkbox = checkbox;
    console.log('hzItem: ', hzItem);
  }

  dropdownClick(data, item) {

    item.dropDownItem = data;
    console.log("data: ", data);
    console.log("item: ", item);
  }

  private loadHotZonePic(item, pic: HotZoneImg, url, scale = null) {

    let baseLen;
    if (this.hotZoneImgSize) {
      baseLen = this.hotZoneImgSize * this.mapScale;
    }

    pic.load(url).then(() => {
      if (!scale) {
        if (baseLen) {
          scale = getMinScale(pic, baseLen);
        } else {
          scale = this.bg.scaleX;
        }

        pic.setScaleXY(scale);

      } else {
        const w = item.width * item.scaleX;
        const h = item.height * item.scaleY;
        pic.setScaleXY(getMinScale(pic, w, h));
      }



      
    });
  }

  
  closeAfterPanel() {
    this.refresh();
  }

  onMultRectSave(e, item) {
    console.log(' in onMultRectSave: ', e);

    item.multRect = e;
    this.setItemMultRectByData(item, item.multRect);
  }



  /**
   * 刷新 渲染页面
   */
  refresh() {
    setTimeout(() => {
      this.appRef.tick();
    }, 1);
  }


}
