import {
  Component,
  ElementRef,
  EventEmitter,
  HostListener,
  Input,
  OnChanges,
  OnDestroy,
  OnInit,
  Output,
  ViewChild
} from '@angular/core';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr} from './Unit';
import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit";
import {tar} from "compressing";


@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 {


  @Input()
  imgItemArr = null;
  @Input()
  hotZoneItemArr = null;
  @Input()
  hotZoneArr = null;
  @Output()
  save = new EventEmitter();
  
  @ViewChild('canvas', {static: true}) canvas: ElementRef;
  @ViewChild('wrap', {static: true}) wrap: ElementRef;
  @ViewChild('hotZoneRef', {static: true}) hotZoneRef: ElementRef;
  @ViewChild('toolBoxRef', {static: true}) toolBoxRef: ElementRef;
  @ViewChild('previewBoxRef', {static: true}) previewBoxRef: ElementRef;
  @ViewChild('previewContainerRef', {static: true}) previewContainerRef: ElementRef;
  @ViewChild('RightContextMenuOnCanvasRef', {static: true}) RightContextMenuOnCanvasRef: ElementRef;

  @Input()
  isHasRect = true;
  @Input()
  isHasPic = true;
  @Input()
  isHasText = true;
  @Input()
  hotZoneFontObj = {
    size: 50,
    name: 'BRLNSR_1',
    color: '#8f3758'
  }
  @Input()
  defaultItemType = 'rect';

  @Input()
  hotZoneImgSize = 190;

  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;
  imgArr = [];
  oldPos;
  radioValue;
  curItem;
  curItems = []; // 多选热区 布局调整
  bg: MySprite;
  changeSizeFlag = false;
  changeTopSizeFlag = false;
  changeRightSizeFlag = false;

  // 布局模式
  inLayoutMode = false;
  
  // 右键菜单选择热区索引
  rightMenuSlecetHotZoneIndex = null;
  
  // 当前微调的对象
  currentSetting = {
    index: -1,
    itemName: "",
    x: 0,
    y: 0,
    width: 0,
    height: 0,
  }

  constructor() {
  }

  _bgItem = null;

  get bgItem() {
    return this._bgItem;
  }

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

    this.init();
  }

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

  toolBoxFixTop = false;
  @HostListener('window:scroll')
  onscroll(){
    const scrollTop = document.documentElement.scrollTop; // 页面顶端滚出屏幕的距离
    const offsetHeight = this.previewContainerRef.nativeElement.offsetHeight; // 预览框的高度
    const offsetTop = this.hotZoneRef.nativeElement.offsetTop; // 热区距离页面顶端的距离

    if(scrollTop <= offsetTop || (scrollTop - offsetTop) > offsetHeight) {
      this.toolBoxRef.nativeElement.style.position = "absolute";
      this.toolBoxFixTop = false;
    } else {
      this.toolBoxRef.nativeElement.style.position = "fixed";
      this.toolBoxFixTop = true;
    }
  }
  
  // keyCtrlDown = false; // ctrl键是否被按下
  // @HostListener('window:keydown', ['$event'])
  // onKeyDown(e) {
  //   console.log("onKeyDown", e.keyCode);
  //   if(e.keyCode == 91 || e.ctrlKey) {
  //     this.keyCtrlDown = true;
  //   }
  // }
  // @HostListener('window:keyup', ['$event'])
  // onKeyUp(e) {
  //   console.log("onKeyUp", e.keyCode);
  //   if(e.keyCode == 91 || e.ctrlKey) {
  //     this.keyCtrlDown = false;
  //   }
  // }

  rightClickOffsetX = -1;
  rightClickOffsetY = -1;
  handleContextmenuOnMenu(e) {
    this.RightContextMenuOnCanvasRef.nativeElement.style.display = "block";
    this.RightContextMenuOnCanvasRef.nativeElement.style.position = "absolute";
    this.RightContextMenuOnCanvasRef.nativeElement.style.top = e.offsetY + "px";
    this.RightContextMenuOnCanvasRef.nativeElement.style.left = e.offsetX + "px";
    this.rightClickOffsetX = e.offsetX;
    this.rightClickOffsetY = e.offsetY;
  }

  ngOnInit() {

    this.initListener();

    // this.init();
    this.update();
    document.oncontextmenu = function () {return false; };
  }

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


  ngOnChanges() {

  }


  onBackgroundUploadSuccess(e) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    this.bgItem.url = e.url;
    this.refreshBackground();
  }

  onItemImgUploadSuccess(e, item) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    item.pic_url = e.url;
    this.loadHotZonePic(item.pic, e.url);
  }

  onItemAudioUploadSuccess(e, item) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    item.audio_url = e.url;
  }


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

    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;

        if (callBack) {
          callBack();
        }
      });
    }

  }

  addHotZone(itemName) {
    // this.imgArr.push({});
    // this.hotZoneArr.push({});
    const item = this.getHotZoneItem();
    item.itemName = itemName;
    this.hotZoneArr.push(item);
    this.refreshItem(item);
    this.refreshHotZoneId();
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
  }

  addBtnClick() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    // this.imgArr.push({});
    // this.hotZoneArr.push({});
    const item = this.getHotZoneItem();
    this.hotZoneArr.push(item);

    this.refreshItem(item);

    this.refreshHotZoneId();

  }

  deleteBtnClick(index) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    const item = this.hotZoneArr.splice(index, 1)[0];
    removeItemFromArr(this.renderArr, item.pic);
    removeItemFromArr(this.renderArr, item.textLabel);

    this.refreshHotZoneId();

  }

  onImgUploadSuccessByImg(e, img) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    img.pic_url = e.url;
    this.refreshImage(img);
  }

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

      }
    }
  }


  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.defaultItemType;
    item.itemName = "";

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

    const pic = new HotZoneImg(this.ctx);
    pic.visible = false;
    item['pic'] = pic;
    if (saveData && saveData.pic_url) {
      this.loadHotZonePic(pic, saveData.pic_url);
    }
    pic.x = item.x;
    pic.y = item.y;
    this.renderArr.push(pic);

    const textLabel = new HotZoneLabel(this.ctx);
    textLabel.fontSize = this.hotZoneFontObj.size;
    textLabel.fontName = this.hotZoneFontObj.name;
    textLabel.fontColor = this.hotZoneFontObj.color;
    textLabel.textAlign = 'center';
    item['textLabel'] = textLabel;
    textLabel.setScaleXY(this.mapScale);
    if (saveData && saveData.text) {
      textLabel.text = saveData.text;
      textLabel.refreshSize();
    }
    textLabel.x = item.x;
    textLabel.y = item.y;
    this.renderArr.push(textLabel);

    return item;
  }


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

  onAudioUploadSuccessByImg(e, img) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    img.audio_url = e.url;
  }

  deleteItem(e, i) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    // this.imgArr.splice(i , 1);
    // this.refreshImageId();
    this.hotZoneArr.splice(i, 1);
    this.refreshHotZoneId();
  }

  radioChange(e, item) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    item.itemType = e;
    this.refreshItem(item);
  }

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


  init() {
    this.initData();
    this.initCtx();
    this.initItem();
  }

  initItem() {
    if (!this.bgItem) {
      this.bgItem = {};
    } else {
      this.refreshBackground(() => {
        if (!this.hotZoneItemArr) {
          this.hotZoneItemArr = [];
        } else {
          this.initHotZoneArr();
        }
      });
    }
  }

  initHotZoneArr() {
    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;
    this.hotZoneArr = [];
    const arr = this.hotZoneItemArr.concat();
    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;
      item.itemName = data.itemName;
      this.refreshItem(item);

      this.hotZoneArr.push(item);
    }

    this.refreshHotZoneId();
    // this.refreshImageId();
  }

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

    this.imgArr = [];
    const arr = this.imgItemArr.concat();
    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);
    }
    this.refreshImageId();
  }


  initData() {
    this.canvasWidth = this.wrap.nativeElement.clientWidth;
    this.canvasHeight = this.wrap.nativeElement.clientHeight;
    this.mapScale = this.canvasWidth / this.canvasBaseW;
    this.renderArr = [];
    this.bg = null;

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

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


  mapDown(event) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    // 如果是鼠标右键 不响应
    if(event.button == 2) {
      return
    }
    const altKey = event.altKey;
    this.oldPos = {x: this.mx, y: this.my};
    for (let i = 0; i < this.hotZoneArr.length; i++) {
      const item = this.hotZoneArr[i];
      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 (this.checkClickTarget(target)) {
        callback(target, altKey);
        return;
      }
    }

    // 点击时没有按下Command键 则清空选择的热区点
    if(!altKey) {
      this.resetAllItemColors();
    }

    this.hideContextMenuOnCanvas();
  }


  mapMove(event) {
    if (!this.curItem) {
      return;
    }
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    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.oldPos = {x: this.mx, y: this.my};

    this.saveDisabled = true;

  }

  mapUp(event) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    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;
    }
    this.curItem.setScaleXY(s);
    this.curItem.refreshLabelScale();
  }

  setCurItemSize(size) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存

    const curItem = this.hotZoneArr[size.index]

    if(size.width != null && !isNaN(size.width)) {
      curItem.scaleX = size.width / curItem.width;
    }

    if(size.height != null && !isNaN(size.height)) {
      curItem.scaleY = size.height / curItem.height;
    }

    if(size.itemName) {
      curItem.itemName = size.itemName;
    }

    if(size.x != null && !isNaN(size.x)) {
      curItem.x = Number(size.x) + size.width / 2;
    }

    if(size.y != null && !isNaN(size.y)) {
      curItem.y = Number(size.y) + size.height / 2;
    }

    curItem.refreshLabelScale();
  }

  // 根据索引 设置热区的位置
  setHotZonePosByIndex(index, posX, posY) {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    const curItem = this.hotZoneArr[index];
    if(posX != null && !isNaN(posX)) {
      curItem.x = Number(posX);
    }

    if(posY != null && !isNaN(posY)) {
      curItem.y = Number(posY);
    }
    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;
    // }
    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) {
    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.renderArr.length; i++) {
      this.renderArr[i].update(this);
    }

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

    this.updateArr(this.hotZoneArr);
    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) {

    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() {
    this.resetDataChange(); // 已经保存 清除离开提示
    const bgItem = this.bgItem;
    if (this.bg) {
      bgItem['rect'] = this.bg.getBoundingBox();
    } 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 = {
        index: hotZoneArr[i].index,
        pic_url: hotZoneArr[i].pic_url,
        text: hotZoneArr[i].text,
        audio_url: hotZoneArr[i].audio_url,
        itemType: hotZoneArr[i].itemType,
        itemName: hotZoneArr[i].itemName,
        fontSize: this.hotZoneFontObj.size,
        fontName: this.hotZoneFontObj.name,
        fontColor: this.hotZoneFontObj.color,
        fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1,
        imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1,
        mapScale: this.mapScale
      };
      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);
    }
    this.save.emit({bgItem, hotZoneItemArr});
  }

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

      item.x = x;
      item.y = y;
      item.pic.x = x;
      item.pic.y = y;
      item.textLabel.x = x;
      item.textLabel.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 clickedHotZoneRect(item: any, altKey = false) {
    if (this.checkClickTarget(item)) {
      if (!this.inLayoutMode && item.lineDashFlag && this.checkClickTarget(item.arrow)) {
        this.changeItemSize(item);
      } else if (!this.inLayoutMode && item.lineDashFlag && this.checkClickTarget(item.arrowTop)) {
        this.changeItemTopSize(item);
      } else if (!this.inLayoutMode && item.lineDashFlag && this.checkClickTarget(item.arrowRight)) {
        this.changeItemRightSize(item);
      } else {
        if(altKey) {
          const bd = item.getBoundingBox()
          const rectParams = {
            index: item.index,
            itemName: item.itemName,
            x: bd.x,
            y: bd.y,
            width: bd.width,
            height: bd.height,
          }
          // 如果之前没有选择过任何项目 则判断一下之前是否有选择过热区块，如果有选择，则把上次选择的热区作为第一个热区
          if(this.curItems.length == 0) {
            const lastItem = this.getCurrentMaskColorItem();
            if(lastItem) {
              const last_bd = lastItem.getBoundingBox()
              const last_rectParams = {
                index: lastItem.index,
                itemName: lastItem.itemName,
                x: last_bd.x,
                y: last_bd.y,
                width: last_bd.width,
                height: last_bd.height,
              }
              this.curItems.push(last_rectParams);
            } else {
              this.resetAllItemColors();
            }
          }
          item.showColorMask = true;
          this.curItems.push(rectParams)
        } else {
          this.resetAllItemColors();
          this.changeCurItem(item);
          item.showColorMask = true;
          const bd = item.getBoundingBox()
          const rectParams = {
            index: item.index,
            itemName: item.itemName,
            x: bd.x,
            y: bd.y,
            width: bd.width,
            height: bd.height,
          }
          this.currentSetting = rectParams;
        }
      }
      return;
    }
  }

  // 获取当前覆盖颜色的热区 - 上次选中（因为没有保存选择的Item, 所以把覆盖颜色的热区当做上一次的选择）
  getCurrentMaskColorItem() {
    const item = this.hotZoneArr.find(item=>item.showColorMask == true);
    return item;
  }

  // 清除所有当前选中的item - 清除高亮
  resetAllItemColors() {
    this.hotZoneArr.forEach(item=>{
      item.showColorMask = false;
    })
    this.curItems = [];
  }

  // 顶部对齐所选元素
  handleClickAlignTop() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let minY = -1;
    this.curItems.forEach(item=>{
      // 取所有元素中 y坐标最小值
      if( minY < 0 || item.y < minY) {
        minY = item.y;
      }
    })

    if(minY >=0 ) {
      this.curItems.forEach(item => {
        item.y = minY;
        this.setCurItemSize(item)
      });
    }
  }

  // 底部对齐所选元素
  handleClickAlignBottom() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let maxY = 100000;
    this.curItems.forEach(item=>{
      // 取所有元素中 y坐标最大值
      if( maxY > 99999 || item.y > maxY) {
        maxY = item.y + item.height;
      }
    })
    if(maxY < 100000 ) {
      this.curItems.forEach(item => {
        item.y = maxY - item.height;
        this.setCurItemSize(item);
      });
    }
  }

  // 左侧对齐所选元素
  handleClickAlignLeft() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let minX = -1;
    this.curItems.forEach(item=>{
      // 取所有元素中 y坐标最小值
      if( minX < 0 || item.x < minX) {
        minX = item.x;
      }
    })

    if(minX >=0 ) {
      this.curItems.forEach(item => {
        item.x = minX;
        this.setCurItemSize(item);
      });
    }
  }

  // 右侧对齐所选元素
  handleClickAlignRight() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let maxX = 100000;
    this.curItems.forEach(item=>{
      // 取所有元素中 y坐标最大值
      if( maxX > 99999 || item.x > maxX) {
        maxX = item.x + item.width;
      }
    })
    if(maxX < 100000 ) {
      this.curItems.forEach(item => {
        item.x = maxX - item.width;
        this.setCurItemSize(item);
      });
    }
  }

  // 水平居中所选元素
  handleClickHMiddle() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let baseY = 0;
    if(this.curItems.length > 0) {
      baseY = this.curItems[0].y + this.curItems[0].height / 2;
    }
    if(baseY > 0) {
      this.curItems.forEach(item => {
        item.y = baseY - item.height / 2;
        this.setCurItemSize(item);
      });
    }
  }

  // 垂直居中所选元素
  handleClickVMiddle() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let baseX = 0;
    if(this.curItems.length > 0) {
      baseX = this.curItems[0].x + this.curItems[0].width / 2;
    }
    if(baseX > 0) {
      this.curItems.forEach(item => {
        item.x = baseX - item.width / 2;
        this.setCurItemSize(item);
      });
    }
  }

  // 水平间距相同
  handleClickHSpaceBetween() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    this.curItems.sort((a, b) => {
      return a.x - b.x
    })

    let startX = 0;
    let endX = 0;
    let contentWidth = 0;

    if(this.curItems.length >= 2) {
      startX = this.curItems[0].x;
      endX = this.curItems[this.curItems.length - 1].x + this.curItems[this.curItems.length - 1].width;
    } else {
      return;
    }

    this.curItems.forEach(item=>{
      contentWidth += item.width;
    })
    
    let space = (endX - startX - contentWidth) / (this.curItems.length - 1);
    if(space > 0) {
      let currentX = this.curItems[0].x;
      this.curItems.forEach(item => {
        item.x = currentX;
        currentX += space + item.width;
        this.setCurItemSize(item);
      });
    }
  }

  // 垂直间距相同
  handleClickVSpaceBetween() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    this.curItems.sort((a, b) => {
      return a.y - b.y
    })

    let startY = 0;
    let endY = 0;
    let contentHeight = 0;

    if(this.curItems.length >= 2) {
      startY = this.curItems[0].y;
      endY = this.curItems[this.curItems.length - 1].y + this.curItems[this.curItems.length - 1].height;
    } else {
      return;
    }

    this.curItems.forEach(item=>{
      contentHeight += item.height;
    })

    let space = (endY - startY - contentHeight) / (this.curItems.length - 1);
    if(space > 0) {
      let currentY = this.curItems[0].y;
      this.curItems.forEach(item => {
        item.y = currentY;
        currentY += space + item.height;
        this.setCurItemSize(item);
      });
    }
  }

  // 使所有选择的热区和第一个选择的热区具有相同大小
  handleClickToSameSize() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存
    let baseWidth = 0;
    let baseHeight = 0;
    if(this.curItems.length > 0) {
      baseWidth = this.curItems[0].width;
      baseHeight = this.curItems[0].height;
    }

    if(baseWidth > 0 && baseHeight > 0) {
      this.curItems.forEach(item => {
        let adjustX = (item.width - baseWidth) / 2;
        let adjustY = (item.height - baseHeight) / 2;
        item.x = item.x + adjustX;
        item.y = item.y + adjustY;
        item.width = baseWidth;
        item.height = baseHeight;
        this.setCurItemSize(item);
      });
    }
  }

  // 处理微调更新热区位置参数
  handleClickUpdateHotZoneParams() {
    this.setDataChange(); // 标记数据改变 离开页面是提示保存ƒ√
    this.setCurItemSize({
      index: this.currentSetting.index,
      itemName: this.currentSetting.itemName,
      // x: this.currentSetting.x,
      // y: this.currentSetting.y,
      width: this.currentSetting.width,
      height: this.currentSetting.height,
    })
  }

  // 调整模式改变
  onAdjustModeChange(e) {
    this.hotZoneArr.forEach(zone => {
      zone.hideArrow = this.inLayoutMode;
    });
  }

  // 根据右键菜单选择热区索引 移动热区
  handleClickMoveHotZoneByRightMenu() {
    if(this.rightMenuSlecetHotZoneIndex != null) {
      this.setDataChange(); // 标记数据改变 离开页面是提示保存
      this.setHotZonePosByIndex(
        this.rightMenuSlecetHotZoneIndex,
        this.rightClickOffsetX,
        this.rightClickOffsetY
      );
      this.hideContextMenuOnCanvas();
    }
  }

  // 隐藏右键菜单
  hideContextMenuOnCanvas() {
    this.rightClickOffsetX = -1;
    this.rightClickOffsetY = -1;
    this.rightMenuSlecetHotZoneIndex = null;
    this.RightContextMenuOnCanvasRef.nativeElement.style.display = "none";
  }

  // 数据改变
  setDataChange() {
    // console.log("数据改变")
    window.onbeforeunload = function(event) {
        event.returnValue = "";
    };
  }

  // 数据改变
  resetDataChange() {
    // console.log("数据保存")
    window.onbeforeunload = function(event) {

    };
  }

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

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

  saveText(item) {
    item.textLabel.text = item.text;
  }



  private loadHotZonePic(pic: HotZoneImg, url) {
    const baseLen = this.hotZoneImgSize * this.mapScale;
    pic.load(url).then(() => {
      const s = getMinScale(pic, baseLen);
      pic.setScaleXY(s);
    });
  }
}
