import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, Input } from '@angular/core';
import * as PIXI from 'pixi.js';
import { EventEmitter } from 'events';
import { EventManager } from '@angular/platform-browser';
import { OutlineFilter } from 'pixi-filters';
import { AssetData, CanvasShareDataService, DisposalNodeData, FloorNodeData } from '../canvas-share-data.service';
import * as ObjectID from 'bson-objectid';
import { Charm } from './charm';
import { AxImageShape } from './model/axImageShape';
import { GameMode } from './model/gameMode';
import { MultipointIcon } from './model/multipointIcon';
import { PolygonIcon } from './model/polygonIcon';
import { PaintMode } from './model/paintModel';
import { AxShape } from './model/axShape';
import { PropertyInfo } from './model/PropertyInfo';
import { AxPreviewImageShape } from './model/axPreviewImageShape';
import { AxArrowConnector } from './model/axArrowConnector';


@Component({
  selector: 'app-working-area',
  templateUrl: './working-area.component.html',
  styleUrls: ['./working-area.component.scss']
})
/**
 * 工作区
 */
export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterViewInit {

  constructor(private eventManager: EventManager, public canvasData: CanvasShareDataService) {
    super();
  }

  @ViewChild('content')
  content: ElementRef;
  /**
   * 父组件
   */
  @Input() init: any;
  /**
   * pixijs 程序
   */
  public app: PIXI.Application;
  /**
   * 资源加载器
   */
  public loader = PIXI.Loader.shared;
  /**
   * 背景图
   */
  public backgroundImage: PIXI.Sprite = null;
  /**
   * 绘制图片形状时预览状态的图片
   */
  public previewImage: AxPreviewImageShape = null;
  /**
   * 预览线段
   */
  public previewLineSegment = new PIXI.Graphics();
  /**
   * 预览原点
   */
  public circleShadow = new PIXI.Graphics();
  /**
   * 鼠标位置
   */
  public mousePosition: PIXI.Point = new PIXI.Point(0, 0);
  /**
   * 绘画模式
   */
  private paintMode: PaintMode = PaintMode.endPaint;
  /**
   * 选择器
   */
  public selection: Selection = new Selection(this);
  /**
   * 当前鼠标的点
   */
  public currentClickPoint: PIXI.Graphics = new PIXI.Graphics();
  /**
   * 绘制点集合
   */
  public paintPoints: PIXI.Point[] = [];
  /**
   * 绘制中的多点图标
   */
  public paintingIcon: MultipointIcon;
  /**
   * 绘制中的图形
   */
  public paintingShape: AxShape = null;
  /**
   * 绘制中的连线
   */
  public paintingLine: PIXI.Graphics = new PIXI.Graphics();
  /**
   * 绿色描边
   */
  public outlineFilterGreen = new OutlineFilter(2, 0x00ff00);
  /**
   * 拷贝素材数据
   */
  public copyData: any[] = [];
  /**
   * 确认绘制按钮
   */
  private enterPaintEndButton = PIXI.Sprite.from('assets/images/enterPaintButton.png');
  /**
   * 框选工具图形
   */
  private rectToolGraphics = new PIXI.Graphics();
  /**
   * 初始鼠标位置
   */
  private initialScreenMousePos: PIXI.Point = new PIXI.Point();
  /**
   * 最终鼠标位置
   */
  private finalScreenMousePos: PIXI.Point = new PIXI.Point();
  /**
   * 允许编辑
   */
  public allowEdit = true;
  /**
   * 动画控制器
   */
  public animator;
  public animation;
  public animationIcon;
  public animationTime;
  // 车辆作业面
  public carAreas: PolygonIcon[];
  // 车辆数据
  public carData: Map<string, any> = new Map<string, any>();
  // 当前选择的车辆id
  public selectCar: any = null;
  /**
   * 数据初始化
   */
  ngOnInit(): void {
    this.eventManager.addGlobalEventListener('window', 'keydown', (event: any) => {
      if (event.keyCode === 17) {
        this.selection.isMultiselection = true;
      }
    });
    this.eventManager.addGlobalEventListener('window', 'keyup', (event: any) => {
      if (event.keyCode === 17) {
        this.selection.isMultiselection = false;
        this.rectToolGraphics.visible = false;
        this.rectToolGraphics.clear();
      }
      // 按Del键删除选中的图标
      if (event.keyCode === 46) {
        this.selection.objects.forEach(item => {
          if (this.allowEdit
            && this.canvasData.gameMode === item.assetData.GameMode) {
            switch (this.canvasData.gameMode) {
              case 0:
                // 删除楼层数据
                delete this.canvasData.originaleveryStoreyData.data[item.assetData.Id];
                // 删除建筑数据
                delete this.canvasData.originalcompanyBuildingData.data[item.assetData.Id];
                // 取消渲染
                this.backgroundImage.removeChild(this.backgroundImage.getChildByName(item.assetData.Id));
                // 数据更改
                this.canvasData.isChange = true;
                break;
              case 1:
                delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[item.assetData.Id];
                delete this.canvasData.selectPanelPoint.Data.Increment[item.assetData.Id];
                delete this.canvasData.selectPanelPoint.Data.Stock[item.assetData.Id];
                this.backgroundImage.removeChild(this.backgroundImage.getChildByName(item.assetData.Id));
                this.canvasData.isChange = true;
                break;
            }
          }
        });
        this.selection.deselectAll();
        this.emit('deleteIcon');
      }
    });
  }
  /**
   * 页面初始化
   */
  ngAfterViewInit(): void {
    this.createCanvas();
    window.onresize = () => {
      this.resetCanvas();
    };
  }
  /**
   *
   * @param event 鼠标滑动事件
   */
  public mouseWheelHandel(event) {
    const delX = this.mousePosition.x - this.backgroundImage.position.x;
    const delY = this.mousePosition.y - this.backgroundImage.position.y;
    const pivot = this.backgroundImage.toLocal(this.mousePosition);
    const delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
    if (delta > 0) {
      if (this.backgroundImage.scale.x >= 32) {
        this.backgroundImage.scale.x = 32;
        this.backgroundImage.scale.y = 32;
        this.emit('backgroundScale', this.backgroundImage.scale.x);
        return;
      }
      this.backgroundImage.pivot.set(pivot.x, pivot.y);

      this.backgroundImage.scale.x += this.backgroundImage.scale.x * 0.1;
      this.backgroundImage.scale.y += this.backgroundImage.scale.y * 0.1;

      this.backgroundImage.position.x += delX;
      this.backgroundImage.position.y += delY;
    } else if (delta < 0) {
      if (this.backgroundImage.scale.x <= 0.1) {
        this.backgroundImage.scale.x = 0.1;
        this.backgroundImage.scale.y = 0.1;
        this.emit('backgroundScale', this.backgroundImage.scale.x);
        return;
      }
      this.backgroundImage.pivot.set(pivot.x, pivot.y);

      this.backgroundImage.scale.x -= this.backgroundImage.scale.x * 0.1;
      this.backgroundImage.scale.y -= this.backgroundImage.scale.y * 0.1;

      this.backgroundImage.position.x += delX;
      this.backgroundImage.position.y += delY;
    }
    this.emit('backgroundScale', this.backgroundImage.scale.x);
  }
  /**
   *
   * @param icon 移动到选中车辆到屏幕中心点
   */
  public moveIconToScreenCenter(icon) {
    if (icon.parent === this.backgroundImage && (
      icon.assetData.Type === 1 ||
      icon.assetData.Type === 2 ||
      icon.assetData.Type === 3 ||
      icon.assetData.Type === 4
    )) {
      console.log(this.backgroundImage.position);
      this.backgroundImage.pivot.set(icon.x, icon.y);
      this.backgroundImage.position.set(771, 404);
      clearTimeout(this.animationTime);
      this.animation?.pause();
      this.animationIcon?.scale.set(1);
      this.animation = this.animator.breathe(icon, 10, 10, 30, true, 0);
      this.animationIcon = icon;
      this.animationTime = setTimeout(() => {
        this.animation?.pause();
        this.animationIcon?.scale.set(1);
      }, 5000);
    }
  }
  /**
   * 创建画布
   */
  private createCanvas(): void {
    this.app = new PIXI.Application({
      width: this.content.nativeElement.clientWidth,
      height: this.content.nativeElement.clientHeight,
      antialias: true,
      transparent: false,
      resolution: 1,
      backgroundColor: 0xE9FAFF
    });
    this.content.nativeElement.appendChild(this.app.view);
    this.animator = new Charm(PIXI);

    this.app.ticker.add((delta) => {
      this.animator.update();
      this.mousePosition = this.app.renderer.plugins.interaction.mouse.global;
      // 预览图片
      if (this.previewImage !== null && this.backgroundImage !== null) {
        this.previewImage.position = this.backgroundImage.toLocal(this.mousePosition);
      }

      if (this.circleShadow !== null && this.backgroundImage !== null) {
        this.circleShadow.position = this.backgroundImage.toLocal(this.mousePosition);
        this.refreshPreviewLineSegment(this.currentClickPoint.position, this.circleShadow.position);
      }
      /**
       * 显示框选
       */
      if (this.rectToolGraphics.visible === true) {

        const init = this.initialScreenMousePos;
        const final = this.finalScreenMousePos;

        this.rectToolGraphics.clear();
        this.rectToolGraphics.lineStyle(2, 0x00ff00, 1);
        this.rectToolGraphics.beginFill(0xccccf2, 0.25);
        if (final.x > init.x && final.y > init.y) {
          this.rectToolGraphics.drawRect(init.x, init.y, final.x - init.x, final.y - init.y);
        } else if (final.x > init.x && final.y < init.y) {
          this.rectToolGraphics.drawRect(init.x, final.y, final.x - init.x, init.y - final.y);
        } else if (final.x < init.x && final.y > init.y) {
          this.rectToolGraphics.drawRect(final.x, init.y, init.x - final.x, final.y - init.y);
        } else if (final.x < init.x && final.y < init.y) {
          this.rectToolGraphics.drawRect(final.x, final.y, init.x - final.x, init.y - final.y);
        }
        this.rectToolGraphics.endFill();
      }
    });
    /**
     * 选中事件
     */
    this.on('select', obj => {
      if (this.allowEdit) {
        if (obj instanceof AxArrowConnector) {
          obj.setPointsVisible(true);
        }
        else if (obj instanceof MultipointIcon) {
          if (obj.assetData.GameMode === this.canvasData.gameMode) {
            obj.setPointVisiable(true);
          } else {
            obj.filters = [this.outlineFilterGreen];
          }
        } else if (obj instanceof PolygonIcon) {
          if (obj.assetData.GameMode === this.canvasData.gameMode) {
            obj.setPointVisiable(true);
          } else {
            obj.filters = [this.outlineFilterGreen];
          }
        } else {
          obj.filters = [this.outlineFilterGreen];
        }
      } else {
        obj.filters = [this.outlineFilterGreen];
      }
    });
    /**
     * 取消选中事件
     */
    this.on('deselect', obj => {
      if (this.allowEdit) {
        if (obj instanceof AxArrowConnector) {
          obj.setPointsVisible(false);
        }
        else if (obj instanceof MultipointIcon) {
          obj.setPointVisiable(false);
        } else if (obj instanceof PolygonIcon) {
          obj.filters = [];
          obj.setPointVisiable(false);
        } else {
          obj.filters = [];
        }
      } else {
        obj.filters = [];
      }
    });
    /**
     * 根据背景缩放事件
     */
    this.on('backgroundScale', scale => {
      this.backgroundImage?.children.forEach(item => {
        if (item instanceof AxImageShape) {
          if (item.assetData.FixedSize) {
            const data = 1 / scale;
            item.scale.set(data);
          } else {
            const data = 1 / scale;
            item.text.scale.set(data);
          }
        } else if (item instanceof MultipointIcon) {
          const data = 1 / scale;
          item.text.scale.set(data);
        } else if (item instanceof PolygonIcon) {
          const data = 1 / scale;
          item.text.scale.set(data);
          item.pointsGraphics.forEach(point => {
            point.scale.set(data);
          });
        } else if (item instanceof AxPreviewImageShape) {
          const data = 1 / scale;
          item.scale.set(data);
        }else if (item instanceof AxArrowConnector) {
          const data = 1 / scale;
          item.text.scale.set(data);
          item.pointSprites.forEach(point => {
            point.scale.set(data);
          });
        }
      });

    });
    /**
     * 创建图标事件
     */
    this.on('createIcon', obj => {
      if (obj.assetData.GameMode === GameMode.BasicInformation) { // 基本信息
        // 添加楼层数据
        this.canvasData.originaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
        // 添加建筑数据
        this.canvasData.originalcompanyBuildingData.data[obj.assetData.Id] = obj.assetData;
      } else if(obj.assetData.GameMode === GameMode.Assignment){ // 处置预案
        if (this.canvasData.selectPanelPoint.Data === undefined
        || this.canvasData.selectPanelPoint.Data === null) {
          this.canvasData.selectPanelPoint.Data = new FloorNodeData();
        }
        this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id] = obj.assetData;
      } else if (obj.assetData.GameMode === GameMode.Examinee) { // 考生考试      
        console.log(obj.assetData.Tag)
        if (obj.assetData.Tag === 1) {
          this.canvasData.examOriginaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
        } else {
          if (this.canvasData.selectPanelPoint.Data === undefined
            || this.canvasData.selectPanelPoint.Data === null) { 
              this.canvasData.selectPanelPoint.Data = new FloorNodeData();
          }
          this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id] = obj.assetData;
        }
      }
      this.canvasData.isChange = true;
    });
  }
  /**
   * 重置画布
   */
  public resetCanvas() {
    this.app.renderer.resize(this.content.nativeElement.clientWidth, this.content.nativeElement.clientHeight);
  }
  /**
   * 设置名称显示
   * @param value true  显示 false 隐藏
   * @param mode BasicInformation = 0 基本信息 Assignment想定作业 = 1 想定作业
   */
  public setNameVisible(value: boolean, mode: GameMode): void {
    this.backgroundImage?.children.forEach(item => {
      if (item instanceof AxImageShape) {
        item.setNameVisible(value, mode);
      } else if (item instanceof MultipointIcon) {
        item.setNameVisible(value, mode);
      } else if (item instanceof PolygonIcon) {
        item.setNameVisible(value, mode);
      }
    });
  }
  /**
   * 根据id刷新图标
   * @param id 图标数据id
   */
  public refreshIcon(id: string): void {
    const icon = this.backgroundImage.children.find(item => item.name === id);
    console.log(icon);
    if (icon instanceof AxImageShape) {
      icon.refresh();
    } else if (icon instanceof MultipointIcon) {
      icon.refresh();
    } else if (icon instanceof PolygonIcon) {
      icon.refresh();
    } else if (icon instanceof AxArrowConnector) {
      icon.redraw();
    }
  }
  /**
   *
   * @param value 缩放倍数
   */
  public setIconScale(value: number): void {
    this.backgroundImage.children.forEach(item => {
      if (item instanceof AxImageShape) {
        console.log(item.image.scale);
        item.image.scale.set(value);
      } else if (item instanceof MultipointIcon) {

      } else if (item instanceof PolygonIcon) {

      }
    });
  }
  /**
   * 设置高亮
   */
  public setHighlight(ids: string[]): void {
    this.selection.deselectAll();
    ids.forEach(item => {
      let obj = this.backgroundImage.getChildByName(item);
      if (obj === null) {
        obj = this.app.stage.getChildByName(item);
      }
      this.selection.select(obj);
    });
  }
  // /**
  //  * 刷新工作区
  //  */
  public async refresh() {
    this.loadExamineeData();
    // this.setPaintMode(PaintMode.endPaint);
    // this.resetCanvas();
    // this.destroyBackgroundImage();
    // if (!this.canvasData.selectStorey.imageUrl) {
      
    //   return;
    // }

    // await this.createBackgroundImage(this.canvasData.selectStorey.imageUrl);
    // this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
    // if (this.canvasData.gameMode === GameMode.Assignment) {
    //   this.createNodeShape(this.canvasData.selectPanelPoint.Data);
    // }
  }
    /**
   * 加载考生数据
   */
  public loadExamineeData() {
    this.createBackground();// 创建背景图
    this.refreshBackgroundImage();// 刷新背景图
    this.processinghiddenData();// 处理数据
    this.createFloorShape(this.canvasData.originaleveryStoreyData.data);// 基本信息
    this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data);// 考生信息
    this.createNodeShape(this.canvasData.selectPanelPoint.Data);// 处置节点
  }
  /**
   * 处理隐藏数据
   */
  public processinghiddenData() {
    for (let key1 in this.canvasData.originaleveryStoreyData.data){
      for (let key2 in this.canvasData.hiddenBasicInfoFacilities){
        if (this.canvasData.originaleveryStoreyData.data[key1].Id==this.canvasData.hiddenBasicInfoFacilities[key2].Id) {
          delete this.canvasData.originaleveryStoreyData.data[key1];
        }
      }
    }
  }
  /**
   * 异步创建背景图
   */
  public createBackground() {
    if (this.backgroundImage !== null) {
      this.backgroundImage.destroy();
      this.backgroundImage = null;
    } 
    this.createBackgroundImage()
  }
  /**
   * 创建楼层图形
   */
  public createFloorShape(floorData: any) {
    Object.keys(floorData).forEach((key) => {
      switch (floorData[key].InteractiveMode) {
        case 0:
          const singleIcon = new AxImageShape(floorData[key], this);
          singleIcon.moveable = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode;
          break;
        case 1:
          const icon = new MultipointIcon(floorData[key], this);
          break;
        case 2:
          const polygonIcon = new PolygonIcon(floorData[key], this);
          break;
        case 3:
          if (floorData[key].Name === '水带') {
            const distance = new AxArrowConnector(floorData[key], this,false,true);
          } else if(floorData[key].Name === '距离'){
            const distance = new AxArrowConnector(floorData[key], this,true,true);
          }else if(floorData[key].Name === '普通墙' || floorData[key].Name === '承重墙'){
            const wall = new AxArrowConnector(floorData[key], this,false,false);
          }
          break;
        }
    });
    this.emit('backgroundScale', this.backgroundImage.scale.x);
  }
  /**
   * 创建节点图形
   */
  public createNodeShape(nodeData: any) {
    if (nodeData !== undefined && nodeData !== null) {
      Object.keys(nodeData).forEach((key) => {
        Object.keys(nodeData[key]).forEach((tempKey) => {
          switch (nodeData[key][tempKey].InteractiveMode) {
            case 0:
              const singleIcon = new AxImageShape(nodeData[key][tempKey], this);
              singleIcon.moveable = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode;
              break;
            case 1:
                const icon = new MultipointIcon(nodeData[key][tempKey], this);
                break;
            case 2:
              const polygonIcon = new PolygonIcon(nodeData[key][tempKey], this);
              break;
            case 3:
              const pipeline = new AxArrowConnector(nodeData[key][tempKey], this,false,true);
              break;
        }
        });
      });
    }
    this.emit('backgroundScale', this.backgroundImage.scale.x);
  }
  /**
   *
   * @param id 图标ID
   * @param b 显示/隐藏
   */
  public setIconVisible(ids: string[], b: boolean) {
    ids.forEach(item => {
      this.backgroundImage.getChildByName(item).visible = b;
    });
  }
  // /**
  //  * 版本检查
  //  */
  // public versionChecking(): void {
  //   const floorData = this.canvasData.originaleveryStoreyData;
  //   const buildingData = this.canvasData.originalcompanyBuildingData;
  //   const nodeData = this.canvasData.selectPanelPoint;
  //   if (floorData.version && floorData.version === '1.0') {
  //     floorData.version = '2.0';
  //     Object.keys(floorData.data).forEach(item => {
  //       floorData.data[item].Point.y *= -1;
  //       floorData.data[item].MultiPoint?.forEach(element => {
  //         element.y *= -1;
  //       });
  //     });
  //   }
  //   if (buildingData.version && buildingData.version === '1.0') {
  //     buildingData.version = '2.0';
  //     Object.keys(buildingData.data).forEach(item => {
  //       buildingData.data[item].Point.y *= -1;
  //       buildingData.data[item].MultiPoint?.forEach(element => {
  //         element.y *= -1;
  //       });
  //     });
  //   }
  //   if (nodeData.Version && nodeData.Version === '1.0') {
  //     nodeData.Version = '2.0';
  //     console.log(this.canvasData.selectPanelPoint.Version);
  //     Object.keys(nodeData.Data).forEach((key) => {
  //       Object.keys(nodeData.Data[key]).forEach((tempKey) => {
  //         nodeData.Data[key][tempKey].Point.y *= -1;
  //         nodeData.Data[key][tempKey].MultiPoint?.forEach(element => {
  //           element.y *= -1;
  //         });
  //       });
  //     });
  //   }
  // }
  /**
   * 创建确认绘制结束按钮
   */
  private createEnterPaintEndButton() {
    this.enterPaintEndButton.width = 60;
    this.enterPaintEndButton.height = 60;
    this.enterPaintEndButton.anchor.set(0.5);
    this.enterPaintEndButton.position =  new PIXI.Point(0, 0);
    this.enterPaintEndButton.interactive = true;
    this.enterPaintEndButton.buttonMode = true;
    this.enterPaintEndButton
      .on('mousedown', event => {
        event.stopPropagation();
        this.enterPaint();
      });
    this.backgroundImage.addChild(this.enterPaintEndButton);
    this.enterPaintEndButton.zIndex = this.backgroundImage.children.length;
    this.enterPaintEndButton.visible = false;
  }
  /**
   * 创建背景图
   */
  public createBackgroundImage(){
    this.backgroundImage = PIXI.Sprite.from('assets/images/noImg.png')
    this.backgroundImage.anchor.set(0.5);
    this.backgroundImage.x = this.app.view.width / 2;
    this.backgroundImage.y = this.app.view.height / 2;
    this.backgroundImage.interactive = true;
    this.backgroundImage.name = 'background';
    this.backgroundImage.angle = this.canvasData.selectStorey.imageAngle;
    const imageWidth = 665;
    const imageHeight = 530;
    const appWidth = this.app.view.width - 470;
    const appHeight = this.app.view.height;

    const wScale = appWidth / imageWidth;
    const hScale = appHeight / imageHeight;

    const scale = wScale < hScale
      ? wScale
      : hScale;
    this.backgroundImage.scale.set(scale);
    this.backgroundImage.sortableChildren = true;
    this.backgroundImage
      .on('mousedown', event => {
        if (!event.currentTarget.dragging && this.selection.isMultiselection === false) {
          event.currentTarget.data = event.data;
          event.currentTarget.dragging = true;
          event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
          event.currentTarget.dragPoint.x -= event.currentTarget.x;
          event.currentTarget.dragPoint.y -= event.currentTarget.y;
          switch (this.paintMode) {
            case PaintMode.endPaint:
              console.log(this.backgroundImage.toLocal(this.mousePosition));
              break;
            case PaintMode.singlePointIcon:
              const json = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos));
              const list = [];
              json.forEach(element => {
                const property = new PropertyInfo(element);
                list.push(property);
              });

              const assetData =  {
                TemplateId: this.canvasData.selectTemplateData.id,
                CanConnect: this.canvasData.selectTemplateData.canConnect,
                Pipelines: new Array(),
                FloorId: this.canvasData.selectStorey.id,
                Angle: this.canvasData.selectTemplateData.angle,
                Color: this.canvasData.selectTemplateData.color,
                Enabled: this.canvasData.selectTemplateData.enabled,
                FillMode: this.canvasData.selectTemplateData.fillMode,
                FireElementId: this.canvasData.selectTemplateData.fireElementId,
                FixedSize: this.canvasData.selectTemplateData.fixedSize,
                Height : 32,
                Width : 32,
                Id: ObjectID.default.generate(),
                ImageUrl: this.canvasData.selectTemplateData.imageUrl,
                InteractiveMode: this.canvasData.selectTemplateData.interactiveMode,
                MultiPoint : null,
                Point: new PIXI.Point(this.previewImage.x, this.previewImage.y),
                Name : this.canvasData.selectTemplateData.name,
                PropertyInfos: list,
                Border : this.canvasData.selectTemplateData.border,
                DrawMode : this.canvasData.selectTemplateData.drawMode,
                Thickness : this.canvasData.selectTemplateData.thickness,
                IsFromBuilding : this.canvasData.selectTemplateData.isFromBuilding,
                GameMode: this.canvasData.gameMode,
                Tag: this.canvasData.selectTemplateData.tag
              };
              const singleIcon = new AxImageShape(assetData, this);
              this.emit('createIcon', singleIcon);
              this.emit('backgroundScale', this.backgroundImage.scale.x);
              break;
            case PaintMode.lineIcon:
              this.previewLineSegment.visible = true;
              this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
              this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));

              if (this.paintPoints.length >= 2) {
                this.enterPaintEndButton.position = this.circleShadow.position;
                this.enterPaintEndButton.visible = true;
              }

              if (this.paintingIcon !== null) {
                this.backgroundImage.removeChild(this.paintingIcon);
              }
              const jsonObject = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos));
              const propertyList = [];
              jsonObject.forEach(element => {
                const property = new PropertyInfo(element);
                propertyList.push(property);
              });
              const assetData1 = {
                TemplateId: this.canvasData.selectTemplateData.id,
                FloorId: this.canvasData.selectStorey.id,
                Angle: this.canvasData.selectTemplateData.angle,
                Color: this.canvasData.selectTemplateData.color,
                Enabled: this.canvasData.selectTemplateData.enabled,
                FillMode: this.canvasData.selectTemplateData.fillMode,
                FireElementId: this.canvasData.selectTemplateData.fireElementId,
                FixedSize: this.canvasData.selectTemplateData.fixedSize,
                Height: 32,
                Width: 32,
                Id: ObjectID.default.generate(),
                ImageUrl: this.canvasData.selectTemplateData.imageUrl,
                InteractiveMode: this.canvasData.selectTemplateData.interactiveMode,
                MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)),
                Point: new PIXI.Point(0, 0),
                Name: this.canvasData.selectTemplateData.name,
                PropertyInfos: propertyList,
                Border: this.canvasData.selectTemplateData.border,
                DrawMode: this.canvasData.selectTemplateData.drawMode,
                Thickness: this.canvasData.selectTemplateData.thickness,
                IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding,
                GameMode: this.canvasData.gameMode,
                Tag: this.canvasData.selectTemplateData.tag
              };
              // const assetData1 = {
              //   ImageUrl: this.canvasData.selectTemplateData.imageUrl,
              //   Point: new PIXI.Point(0, 0),
              //   Width: 32,
              //   Height: 32,
              //   MultiPoint: this.paintPoints,
              //   Name: this.canvasData.selectTemplateData.name
              // };
              this.paintingIcon = new MultipointIcon(assetData1, this);
              // this.paintingIcon = new MultipointIcon(this.previewSinglePointIcon.texture, new PIXI.Point(0, 0), this.paintPoints, this,
              //   this.canvasData.selectTemplateData.name);
              this.emit('backgroundScale', this.backgroundImage.scale.x);
              break;
            case PaintMode.polygonIcon:
              this.previewLineSegment.visible = true;
              this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
              this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
              if (this.paintPoints.length === 1) {
                this.enterPaintEndButton.position = this.circleShadow.position;
              } else if (this.paintPoints.length >= 3) {
                this.enterPaintEndButton.visible = true;
              }
              this.paintPoints.forEach((value, index, array) => {
                if (index === 0) {
                  this.paintingLine.clear();
                  this.paintingLine.lineStyle(1, 0xffd900, 1);
                  this.paintingLine.moveTo(value.x, value.y);
                } else {
                  this.paintingLine.lineTo(value.x, value.y);
                }
              });

              // if (this.paintingIcon !== null) {
              //   this.backgroundImage.removeChild(this.paintingIcon);
              // }
              // this.paintingIcon = new PolygonIcon(this.paintPoints, this);
              break;
            case PaintMode.Pipeline:
              if (this.canvasData.selectTemplateData.name === '水带') {
                if (this.paintingShape !== null) {
                  this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
                  this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
                  this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
                  this.paintingShape.refresh();
                }
              } else {
                this.previewLineSegment.visible = true;
                this.enterPaintEndButton.position = this.circleShadow.position;
                this.enterPaintEndButton.visible = true;
                this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y);
                this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y));
                if (this.paintPoints.length < 2) {
                  return;
                }
                if (this.paintingShape === null) {
                  const jsonObject = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos));
                  const propertyList = [];
                  jsonObject.forEach(element => {
                    const property = new PropertyInfo(element);
                    propertyList.push(property);
                  });
                  const assetData2 = {
                    TemplateId: this.canvasData.selectTemplateData.id,
                    FloorId: this.canvasData.selectStorey.id,
                    Angle: this.canvasData.selectTemplateData.angle,
                    Color: this.canvasData.selectTemplateData.color,
                    Enabled: this.canvasData.selectTemplateData.enabled,
                    FillMode: this.canvasData.selectTemplateData.fillMode,
                    FireElementId: this.canvasData.selectTemplateData.fireElementId,
                    FixedSize: this.canvasData.selectTemplateData.fixedSize,
                    Height: 32,
                    Width: 32,
                    Id: ObjectID.default.generate(),
                    ImageUrl: this.canvasData.selectTemplateData.imageUrl,
                    InteractiveMode: this.canvasData.selectTemplateData.interactiveMode,
                    MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)),
                    Point: new PIXI.Point(0, 0),
                    Name: this.canvasData.selectTemplateData.name,
                    PropertyInfos: propertyList,
                    Border: this.canvasData.selectTemplateData.border,
                    DrawMode: this.canvasData.selectTemplateData.drawMode,
                    Thickness: this.canvasData.selectTemplateData.thickness,
                    IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding,
                    GameMode: this.canvasData.gameMode,
                    Tag: this.canvasData.selectTemplateData.tag
                  };
                  if (this.canvasData.selectTemplateData.name === '距离') {
                    this.paintingShape = new AxArrowConnector(assetData2, this,true,true); 
                  } else if (this.canvasData.selectTemplateData.name === '普通墙' || this.canvasData.selectTemplateData.name === '承重墙') {
                    this.paintingShape = new AxArrowConnector(assetData2, this,false,false);  
                  }
                } else {
                  this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
                  this.paintingShape.redraw();
                }
              }
              this.emit('backgroundScale', this.backgroundImage.scale.x);
              break;
          }
        } else if (!event.currentTarget.dragging && this.selection.isMultiselection === true) {
          this.rectToolGraphics.visible = true;
          event.currentTarget.dragging = true;
          this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
          this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
        }
      })
      .on('mouseup', event => {
        if (event.currentTarget.dragging) {
          event.currentTarget.dragging = false;
          event.currentTarget.data = null;
        }
        if (this.rectToolGraphics.visible === true) {
          this.backgroundImage.children.forEach(item => {
            if ( item instanceof AxImageShape
              || item instanceof MultipointIcon
              || item instanceof PolygonIcon
              || item instanceof AxArrowConnector) {
              // 判断2个矩形是否相交
              const rect1 = this.rectToolGraphics.getBounds();
              const rect2 = item.getBounds();
              if (this.isOverlap(rect1, rect2)) {
                this.selection.select(item);       
              }
            }
          });
          this.rectToolGraphics.clear();
          this.rectToolGraphics.visible = false;
        }
      })
      .on('mouseupoutside', event => {
        if (event.currentTarget.dragging) {
          event.currentTarget.dragging = false;
          event.currentTarget.data = null;
        }
      })
      .on('mousemove', event => {
        if (event.currentTarget.dragging && this.selection.isMultiselection === false) {
          const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
          event.currentTarget.x = newPosition.x - event.currentTarget.dragPoint.x;
          event.currentTarget.y = newPosition.y - event.currentTarget.dragPoint.y;
        } else if (event.currentTarget.dragging && this.selection.isMultiselection === true) {
          if (this.rectToolGraphics.visible === true) {
            this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
          }
        }
      })
      .on('rightclick', event => {
        event.stopPropagation();
        this.selection.deselectAll();
        this.setPaintMode(PaintMode.endPaint);
      })
      .on('pointerover', (event) => {
        if (this.previewImage !== null
        && this.paintMode === PaintMode.singlePointIcon) {
          this.previewImage.visible = true;
        }
      })
      .on('pointerout', (event) => {
        if (this.previewImage !== null
        && this.paintMode === PaintMode.singlePointIcon) {
          this.previewImage.visible = false;
        }
      });
    this.app.stage.addChild(this.backgroundImage);
    this.createPreviewImage();
    this.createPreviewLineSegment();
    this.createCircleShadow();
    this.createEnterPaintEndButton();
    this.backgroundImage.addChild(this.paintingLine);

  }
  public isOverlap(rect1, rect2):boolean {
    const l1 = { x: rect1.x, y: rect1.y }
    const r1 = { x: rect1.x + rect1.width, y: rect1.y + rect1.height }
    const l2 = { x: rect2.x, y: rect2.y }
    const r2 = { x: rect2.x + rect2.width, y: rect2.y + rect2.height }
    if (
      l1.x > r2.x ||
      l2.x > r1.x ||
      l1.y > r2.y ||
      l2.y > r1.y
    ) return false
    return true
  }

  /**
   * 刷新背景图
   */
  public async refreshBackgroundImage(): Promise<void> {
    if (!this.canvasData.selectStorey.imageUrl) {
      this.backgroundImage.visible = false;
    } else {
      this.backgroundImage.texture = await PIXI.Texture.fromURL(this.canvasData.selectStorey.imageUrl);
      const imageWidth = this.backgroundImage.texture.width;
      const imageHeight = this.backgroundImage.texture.height;
      const appWidth = this.app.view.width - 470;
      const appHeight = this.app.view.height;

      const wScale = appWidth / imageWidth;
      const hScale = appHeight / imageHeight;

      const scale = wScale < hScale? wScale: hScale;
      this.backgroundImage.scale.set(scale);
      this.backgroundImage.angle = this.canvasData.selectStorey.imageAngle;
      this.backgroundImage.visible = true;
    }
  }
  /**
   * 清空画布
   */
  public destroyBackgroundImage(): void {
    this.app.stage.removeChild(this.backgroundImage);
    this.backgroundImage = null;
  }
  /**
   * 设置背景图缩放
   * @param scale 缩放系数
   */
  public setBackgroundScale(scale: number): void {
    this.backgroundImage?.scale.set(scale);
    this.emit('backgroundScale', this.backgroundImage?.scale.x);
  }
  /**
   * 设置背景图角度
   * @param imageAngle 角度值
   */
  public setBackgroundAngle(imageAngle: number) {
    this.backgroundImage.angle = imageAngle;
  }
  /**
   * 创建预览单点图标
   */
  private createPreviewImage(): void {
    // if (this.previewSinglePointIcon === null) {
    //   this.previewSinglePointIcon = PIXI.Sprite.from(this.canvasData.selectTemplateData.imageUrl);
    //   this.previewSinglePointIcon.width = this.canvasData.selectTemplateData.width;
    //   this.previewSinglePointIcon.height = this.canvasData.selectTemplateData.height;
    //   this.previewSinglePointIcon.anchor.set(0.5);
    //   this.previewSinglePointIcon.interactive = false;
    //   this.backgroundImage.addChild(this.previewSinglePointIcon);
    //   this.previewSinglePointIcon.scale.set(1 / this.backgroundImage.scale.x);
    // }
    this.previewImage = new AxPreviewImageShape(this);
    this.previewImage.visible = false;
  }
  /**
   * 创建预览线段
   */
  private createPreviewLineSegment() {
    this.previewLineSegment.visible = false;
    this.backgroundImage.addChild(this.currentClickPoint);
    this.backgroundImage.addChild(this.previewLineSegment);

    this.backgroundImage.addChild(this.rectToolGraphics);
    this.rectToolGraphics.visible = false;
  }
  /**
   * 刷新预览线段
   * @param pointA 点A
   * @param pointB 点B
   */
  private refreshPreviewLineSegment(pointA: PIXI.Point, pointB: PIXI.Point) {
    this.previewLineSegment.clear();
    this.previewLineSegment.lineStyle(5, 0x00ff00, 1);
    this.previewLineSegment.moveTo(pointA.x, pointA.y);
    this.previewLineSegment.lineTo(pointB.x, pointB.y );
  }
  /**
   * 创建半径图标影子
   * @param x 半径
   */
  private createCircleShadow(): void {
    this.circleShadow.beginFill(0xFFCC5A);
    this.circleShadow.drawCircle(0, 0, 10);
    this.circleShadow.endFill();
    this.circleShadow.visible = false;
    this.backgroundImage.addChild(this.circleShadow);
  }
  showConnectionPoint(b: boolean) {
    this.backgroundImage?.children.forEach(item => {
        if (item instanceof AxImageShape) {
          if (item.assetData.CanConnect) {
            item.showConnectionPoint(b);
         }
      }
    });
  }
  /**
   * 开始绘制
   */
  public beginPaint() {
    console.log(this.canvasData.selectTemplateData);
    this.selection.deselectAll();
    this.setPaintMode(PaintMode.endPaint);
    this.setPaintMode(this.canvasData.selectTemplateData.interactiveMode);
  }
  /**
   * 初始化管线数据
   */
  public initPipelineData(): void {
    this.paintPoints = [];
    this.paintingShape = null;
  }
  public beginPaintingArrows(): void {
    this.paintMode = PaintMode.Arrows;
  }
  /**
   * 设置绘制状态
   * @param mode 状态
   */
  public setPaintMode(mode: PaintMode) {
    if (this.paintMode === mode) {
      return;
    }
    this.paintMode = mode;
    switch (this.paintMode) {
      case PaintMode.singlePointIcon:
        this.previewImage.visible = true;
        this.previewImage.setImageUrl(this.canvasData.selectTemplateData.imageUrl);
        break;
      case PaintMode.lineIcon:
        this.circleShadow.visible = false;
        this.previewLineSegment.visible = false;
        this.paintPoints.splice(0, this.paintPoints.length);
        if (this.paintingIcon !== null) {
          this.backgroundImage.removeChild(this.paintingIcon);
        }
        this.previewImage.setImageUrl(this.canvasData.selectTemplateData.imageUrl);
        this.circleShadow.visible = true;
        break;
      case PaintMode.polygonIcon:
        this.circleShadow.visible = false;
        this.previewLineSegment.visible = false;
        this.paintingIcon = null;
        this.paintPoints.splice(0, this.paintPoints.length);
        this.paintingLine.clear();
        this.circleShadow.visible = true;
        break;
      case PaintMode.Pipeline:
        if (this.canvasData.selectTemplateData.name==='水带') {
          this.showConnectionPoint(true);
        } else {
          
        }
        break;
      case PaintMode.endPaint:
        this.showConnectionPoint(false);
        if (this.previewImage !== null) {
          this.previewImage.visible = false;
        }
        // 重置组件状态
        if ( this.paintingIcon !== undefined
          && this.paintingIcon !== null) {
          this.backgroundImage.removeChild(this.paintingIcon);
        }

        // if (this.paintingShape !== undefined
        //   && this.paintingShape !== null) {
        //   this.backgroundImage.removeChild(this.paintingShape);
        // }
        if (this.paintingShape !== null) {
          this.backgroundImage.removeChild(this.paintingShape);
          this.paintingShape = null;
        }
        this.enterPaintEndButton.visible = false;
        this.paintingLine.clear();
        this.resetData();
        break;
      default:
        break;
    }
  }
  /**
   * 获取绘制状态
   */
  public getPaintMode(): PaintMode {
    return this.paintMode;
  }
  /**
   * 重置
   */
  public resetData() {
    this.initPipelineData();
    //
    this.circleShadow.visible = false;
    this.previewLineSegment.visible = false;
  }
  /**
   * 确认绘制
   */
  private enterPaint(): void {
    this.previewLineSegment.visible = false;
    this.enterPaintEndButton.visible = false;
    console.log(this.paintMode);
    switch (this.paintMode) {
      case PaintMode.singlePointIcon:
        break;
      case PaintMode.lineIcon:
        if (this.paintPoints.length >= 2) {
          this.emit('createIcon', this.paintingIcon);
          this.paintingIcon = null;
        }
        break;
      case PaintMode.polygonIcon:
        this.paintingLine.clear();
        if (this.paintPoints.length >= 3) {
          const jsonList = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos));
          const propertyList = [];
          jsonList.forEach(element => {
            const property = new PropertyInfo(element);
            propertyList.push(property);
          });
          const assetData = {
            TemplateId: this.canvasData.selectTemplateData.id,
            FloorId: this.canvasData.selectStorey.id,
            Angle: this.canvasData.selectTemplateData.angle,
            Color: this.canvasData.selectTemplateData.color,
            Enabled: this.canvasData.selectTemplateData.enabled,
            FillMode: this.canvasData.selectTemplateData.fillMode,
            FireElementId: this.canvasData.selectTemplateData.fireElementId,
            FixedSize: this.canvasData.selectTemplateData.fixedSize,
            Height: 32,
            Width: 32,
            Id: ObjectID.default.generate(),
            ImageUrl: this.canvasData.selectTemplateData.imageUrl,
            InteractiveMode: this.canvasData.selectTemplateData.interactiveMode,
            MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)),
            Point: new PIXI.Point(0, 0),
            Name: this.canvasData.selectTemplateData.name,
            PropertyInfos: propertyList,
            Border: this.canvasData.selectTemplateData.border,
            DrawMode: this.canvasData.selectTemplateData.drawMode,
            Thickness: this.canvasData.selectTemplateData.thickness,
            IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding,
            GameMode: this.canvasData.gameMode
          };
          const polygonIcon = new PolygonIcon(assetData, this);
          this.emit('createIcon', polygonIcon);
        }
        break;
      case PaintMode.Pipeline:
        if (this.canvasData.selectTemplateData.name !== '水带') {
          this.emit('createIcon', this.paintingShape);
          this.paintingShape = null;
        }
        break;
    }
    this.paintPoints.splice(0, this.paintPoints.length);
    this.emit('backgroundScale', this.backgroundImage.scale.x);
  }
  /**
   * 复制
   */
  public copy(): void {
    this.copyData = [];
    this.selection.objects.forEach(item => {
      const newData = JSON.parse(JSON.stringify(item.assetData));
      this.copyData.push(newData);
    });
  }
  /**
   * 粘贴
   */
  public paste(companyId: string, buildingId: string, floorId: string): void {
    this.copyData.forEach(item => {
      item.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5);
      const newData = JSON.parse(JSON.stringify(item));
      newData.Id = ObjectID.default.generate(),
      newData.CompanyId = companyId;
      newData.BuildingId = buildingId;
      newData.FloorId = floorId;
      newData.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5);
      // if (newData.IsFromBuilding) {
      //   this.canvasData.originalcompanyBuildingData.data[newData.Id] = newData;
      // } else {
      this.canvasData.originaleveryStoreyData.data[newData.Id] = newData;
      // }
      switch (item.InteractiveMode) {
        case PaintMode.singlePointIcon:
          const singleIcon = new AxImageShape(newData, this);
          break;
        case PaintMode.lineIcon:
          const lineIcon = new MultipointIcon(newData, this);
          break;
        case PaintMode.polygonIcon:
          const polygonIcon = new PolygonIcon(newData, this);
          break;
        case PaintMode.Pipeline:
          if (item.Name === '距离') {
            const wall = new AxArrowConnector(newData, this,true,true);
          } else if (item.Name === '普通墙' || item.Name === '承重墙') {
            const wall = new AxArrowConnector(newData, this,false,false);
          }
          break;
      }
      this.selection.select(this.backgroundImage.getChildByName(newData.Id));
    });
    this.emit('backgroundScale', this.backgroundImage.scale.x);
  }

}

/**
 * 选择器
 */
export class Selection {
  constructor(private workingArea: WorkingAreaComponent) {}
  public objects: any[] = [];
  public isMultiselection = false;
  /**
   * 返回选择器中是否包含对象
   * @param obj 对象
   */
  public contains(obj: any): boolean {
    return this.objects.includes(obj);
  }
  /**
   * 选定对象
   * @param obj 对象
   */
  public select(obj: any) {
    if (!this.contains(obj)) {
      this.workingArea.emit('select', obj);
      this.objects.push(obj);
    }
  }
  /**
   * 取消选定对象
   * @param obj 对象
   */
  public deselect(obj: any) {
    if (this.contains(obj)) {
      this.workingArea.emit('deselect', obj);
      const idx = this.objects.findIndex(x => x === obj);
      this.objects.splice(idx, 1);
    }
  }
  /**
   * 选定或取消选定对象
   * @param obj 对象
   */
  public selectOrDeselect(obj: any) {
    if (this.contains(obj)) {
      this.deselect(obj);
    } else {
      this.select(obj);
    }
  }
  /**
   * 取消选定所有已选定对象
   */
  public deselectAll() {
    this.objects.forEach(item => {
      this.workingArea.emit('deselect', item);
    });
    this.objects.splice(0, this.objects.length);
  }
  /**
   * 取消选定所有对象后选定一个对象
   * @param obj 对象
   */
  public selectOne(obj: any) {
    if (this.isMultiselection) {
      this.selectOrDeselect(obj);
    } else {
      this.deselectAll();
      this.select(obj);
    }
  }
  /**
   * 选定对象集合中所有对象
   * @param objects 对象集合
   */
  public selectAll(objects: any[]) {
    this.objects.forEach(item => {
      this.select(item);
    });
  }
}


/**
 * 车辆类型
 */
export enum Type {
  水源 = 0,
  举高喷射消防车 = 1,
  泡沫消防车 = 2,
  水罐消防车 = 3,
  压缩空气泡沫消防车 = 4
}