(function (window, mars3d) {
  //创建widget类，需要继承BaseWidget
  class MyWidget extends mars3d.widget.BaseWidget {
    //弹窗配置
    get view() {
      return {
        type: "window",
        url: "view.html",
        windowOptions: {
          width: 320,
          height: 400,
        },
      };
    }

    //初始化[仅执行1次]
    create() {
      this.arrKsyList = [];
    }

    //每个窗口创建完成后调用
    winCreateOK(opt, result) {
      this.viewWindow = result;
    }

    //激活插件
    activate() {}
    //释放插件
    disable() {
      this.viewWindow = null;
      this.destroyAll();
    }

    openTerrainDepthTest() {
      this._last_depthTestAgainstTerrain = this.map.scene.globe.depthTestAgainstTerrain;
      this.map.scene.globe.depthTestAgainstTerrain = true;
    }
    resetTerrainDepthTest() {
      if (Cesium.defined(this._last_depthTestAgainstTerrain)) {
        this.map.scene.globe.depthTestAgainstTerrain = this._last_depthTestAgainstTerrain;
        delete this._last_depthTestAgainstTerrain;
      }
    }

    destroyAll() {
      this.destroyRZFX(); //日照分析
      this.destroyPDPX(); //坡度坡向
      this.destroyKSY(); //可视域分析

      this.destroyFLFX(); //方量分析
      this.destroyDXKW(); //地形开挖
      this.destroyDBTM(); //地表透明

      this.destroyMXPQ(); //模型剖切
      this.destroyMXYP(); //模型压平
      this.destroyMXCJ(); //模型裁剪
    }

    enableControl(value) {
      if (this.map.popup) {
        this.map.popup.enabled = value;
      }
      if (this.map.tooltip) {
        this.map.tooltip.enabled = value;
      }
      if (this.map.contextmenu) {
        this.map.contextmenu.enabled = value;
      }
    }

    //=========日照分析========
    createRZFX() {
      this.destroyRZFX();

      //日照分析类
      this.shadows = new mars3d.thing.Shadows({
        multiplier: 1600,
        time: this.viewWindow.getCurrTime(),
      });
      this.map.addThing(this.shadows);

      this.shadows.on(mars3d.EventType.change, (event) => {
        this.viewWindow.setRZFXNowTime(this.shadows.time);
      });
    }
    destroyRZFX() {
      if (this.shadows) {
        this.map.removeThing(this.shadows, true);
        delete this.shadows;
      }
    }

    //=========可视域分析========
    createKSY() {
      //不开启抗锯齿，可视域会闪烁
      this.map.scene.postProcessStages.fxaa.enabled = true;

      //不加无法投射到地形上
      this.openTerrainDepthTest();
    }
    destroyKSY() {
      this.clearKSY();
      this.resetTerrainDepthTest();
    }
    clearKSY() {
      for (var i = 0, len = this.arrKsyList.length; i < len; i++) {
        this.map.removeThing(this.arrKsyList[i], true);
      }
      this.arrKsyList = [];
      delete this.lastViewField;
    }
    getLastKSY() {
      return this.lastViewField || {};
    }
    addKSY(options) {
      var thisViewField = new mars3d.thing.ViewShed3D({
        ...options,
        offsetHeight: 1.5, //增加人的升高
      });
      this.map.addThing(thisViewField);

      thisViewField.on(mars3d.EventType.end, (event) => {
        if (this.viewWindow) {
          this.viewWindow.updateKsyDistance(event.distance);
        }
      });
      this.lastViewField = thisViewField;
      this.arrKsyList.push(thisViewField);
    }
    updateKsyDebugFrustum(show) {
      for (var i = 0, len = this.arrKsyList.length; i < len; i++) {
        this.arrKsyList[i].showFrustum = show;
      }
    }

    //=========方量分析========
    createFLFX() {
      if (this.measure) {
        return;
      }

      this.measure = new mars3d.thing.Measure({
        heightLabel: true,
        // offsetLabel: true,
      });
      this.map.addThing(this.measure);

      this.measure.on(mars3d.EventType.start, (e) => {
        haoutil.loading.show({ type: "loader-bar" });
      });
      this.measure.on(mars3d.EventType.end, (e) => {
        haoutil.loading.hide();
        this.viewWindow.showFLFXHeightRg();
      });
    }
    destroyFLFX() {
      if (this.measure) {
        this.map.removeThing(this.measure, true);
        delete this.measure;
      }
      this.measureVolume = null;
    }
    clearFLFX() {
      if (!this.measure) {
        return;
      }
      this.measure.clear();
      this.measureVolume = null;
    }
    startFLFX() {
      this.measureVolume = this.measure.volume({
        splitNum: 6, //面内插值次数，控制精度[注意精度越大，分析时间越长]
        // minHeight: 50  //可以设置一个固定的最低高度
      });
    }

    //=========地形开挖========
    createDXKW() {
      this.openTerrainDepthTest();
    }
    startDrawDXKW() {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "polygon",
        style: {
          color: "#29cf34",
          opacity: 0.5,
        },
        success: (graphic) => {
          //绘制成功后回调
          this.enableControl(true);

          //绘制成功后回调
          var positions = graphic.positionsShow;
          this.map.graphicLayer.clear();

          this.showDXKWTerrainClip(positions);
        },
      });
    }
    startDrawDXKWExtent() {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "rectangle",
        style: {
          color: "#007be6",
          opacity: 0.8,
        },
        success: (graphic) => {
          //绘制成功后回调
          this.enableControl(true);

          var positions = graphic.getOutlinePositions(false);
          this.map.graphicLayer.clear();

          this.showDXKWTerrainClip(positions);
        },
      });
    }
    destroyDXKW() {
      if (this.terrainClip) {
        this.map.removeThing(this.terrainClip, true);
        delete this.terrainClip;
      }

      this.resetTerrainDepthTest();
    }
    clearDXKW() {
      if (this.terrainClip) {
        this.terrainClip.clear(); //清除挖地区域
      }
      //同时有模型时，清除模型裁剪
      this.clearMXCJ();
    }
    showDXKWTerrainClip(positions) {
      var height = this.viewWindow.getDXKWNowHeight();
      if (!this.terrainClip) {
        this.terrainClip = new mars3d.thing.TerrainClip({
          diffHeight: height, //井的深度
          image: this.path + "img/textures/excavationregion_top.jpg",
          imageBottom: this.path + "img/textures/excavationregion_side.jpg",
          splitNum: 50, //井边界插值数
        });
        this.map.addThing(this.terrainClip);
      }

      this.terrainClip.addArea(positions, { diffHeight: height });

      //同时有模型时，进行模型裁剪
      this.addMxcjPoly(positions);
    }
    updateDXKWHeight(nowValue) {
      if (this.terrainClip) {
        this.terrainClip.diffHeight = nowValue;
      }
    }

    //=========地表透明========
    createDBTM() {
      this.underground = new mars3d.thing.Underground({
        alpha: 0.5,
      });
      this.map.addThing(this.underground);
    }
    destroyDBTM() {
      if (this.underground) {
        this.map.removeThing(this.underground, true);
        delete this.underground;
      }
    }
    clearDBTM() {}

    //=========坡度坡向========
    createPDPX() {
      if (this.slope) {
        return;
      }
      //渲染效果
      this.contourLine = new mars3d.thing.ContourLine({
        contourShow: false, //是否显示等高线
        shadingType: "none", //地表渲染效果类型:无nono, 高程 elevation, 坡度slope, 坡向aspect
      });
      this.map.addThing(this.contourLine);

      this.slope = new mars3d.thing.Slope({
        point: {
          pixelSize: 9,
          color: Cesium.Color.RED.withAlpha(0.5),
          //disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        arrow: {
          scale: 0.3, //箭头长度的比例（范围0.1-0.9）
          width: 15, //箭头宽度
          color: Cesium.Color.YELLOW,
        },
      });
      this.map.addThing(this.slope);
    }
    destroyPDPX() {
      this.clearPDPX();
      if (this.slope) {
        this.map.removeThing(this.slope, true);
        delete this.slope;
      }
      if (this.contourLine) {
        this.map.removeThing(this.contourLine, true);
        delete this.contourLine;
      }
    }
    clearPDPX() {
      if (this.slope) {
        this.slope.clear();
      }
      if (this.contourLine) {
        this.contourLine.clear();
      }
      this.map.graphicLayer.clear();
    }
    drawPDPXPoly(splitNum) {
      this.map.graphicLayer.clear();
      this.map.graphicLayer.startDraw({
        type: "polygon",
        style: {
          color: "#29cf34",
          opacity: 0.3,
          outline: true,
          outlineColor: "#ffffff",
          clampToGround: true,
        },
        success: (graphic) => {
          //绘制成功后回调
          var positions = graphic.positionsShow;
          this.map.graphicLayer.clear();

          this.contourLine.positions = positions;

          this.slope.add(positions, {
            splitNum: splitNum, //splitNum插值分割的个数
            radius: 1, //缓冲半径（影响坡度坡向的精度）
            count: 4, //缓冲的数量（影响坡度坡向的精度）会求周边(count*4)个点
          });
        },
      });
    }
    drawPDPXExtent(splitNum) {
      this.map.graphicLayer.clear();
      this.map.graphicLayer.startDraw({
        type: "rectangle",
        style: {
          color: "#007be6",
          opacity: 0.8,
          outline: false,
        },
        success: (graphic) => {
          //绘制成功后回调
          var positions = graphic.getOutlinePositions(false);
          this.map.graphicLayer.clear();

          this.contourLine.positions = positions;

          this.slope.add(positions, {
            splitNum: splitNum, //splitNum插值分割的个数
            radius: 1, //缓冲半径（影响坡度坡向的精度）
            count: 4, //缓冲的数量（影响坡度坡向的精度）会求周边(count*4)个点
          });
        },
      });
    }

    //=========模型剖切========
    selectedPQMX() {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "point",
        style: {
          color: "#007be6",
        },
        success: (graphic) => {
          //绘制成功后回调
          var position = graphic.positionShow;

          this.map.graphicLayer.clear();

          this.enableControl(true);

          var tileset = this.map.pick3DTileset([position]); //拾取绘制返回的模型
          if (!tileset) {
            haoutil.msg("请单击选择模型");
            return;
          }

          var radius = tileset.boundingSphere.radius / 2;
          this.viewWindow.setClipDistanceRange(radius, tileset.name || "未命名");

          this.tilesetPlanClip = new mars3d.thing.TilesetPlanClip({
            tileset: tileset,
          });
          this.map.addThing(this.tilesetPlanClip);
        },
      });
    }
    drawLinePQMX() {
      if (this.tilesetPlanClip) {
        this.tilesetPlanClip.clear();
      }
      this.map.graphicLayer.startDraw({
        type: "polyline",
        maxPointNum: 2,
        style: {
          color: "#007be6",
          opacity: 0.8,
          outline: false,
        },
        success: (graphic) => {
          //绘制成功后回调
          var positions = graphic.positionsShow;
          this.map.graphicLayer.clear();

          if (this.tilesetPlanClip) {
            this.tilesetPlanClip.clear();
          } else {
            var tileset = this.map.pick3DTileset(positions); //拾取绘制返回的模型
            if (!tileset) {
              haoutil.msg("请单击选择模型");
              return;
            }
            this.tilesetPlanClip = new mars3d.thing.TilesetPlanClip({
              tileset: tileset,
            });
            this.map.addThing(this.tilesetPlanClip);
          }

          this.tilesetPlanClip.positions = positions;
        },
      });
    }
    destroyMXPQ() {
      if (this.tilesetPlanClip) {
        this.map.removeThing(this.tilesetPlanClip, true);
        delete this.tilesetPlanClip;
      }
    }
    clearMXPQ() {
      if (!this.tilesetPlanClip) {
        return;
      }

      this.tilesetPlanClip.clear();
    }

    //=========模型压平========
    createMXYP() {}
    destroyMXYP() {
      this.clearMXYP();
      this._mxypTileset = null;
    }
    clearMXYP() {
      if (this.tilesetFlat) {
        this.map.removeThing(this.tilesetFlat, true);
        delete this.tilesetFlat;
      }
    }
    selectedYPMX() {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "point",
        style: {
          color: "#007be6",
        },
        success: (graphic) => {
          //绘制成功后回调
          var position = graphic.positionShow;

          this.map.graphicLayer.clear();

          this.enableControl(true);

          var tileset = this.map.pick3DTileset([position]); //拾取绘制返回的模型
          if (!tileset) {
            haoutil.msg("请单击选择模型");
            return;
          }
          this._mxypTileset = tileset;
          this.viewWindow.setMxpyName(tileset.name || "未命名");
        },
      });
    }
    drawMxypPoly(flatHeight) {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "polygon",
        style: {
          color: "#007be6",
          opacity: 0.5,
        },
        success: (graphic) => {
          //绘制成功后回调
          this.enableControl(true);

          var positions = graphic.positionsShow;
          this.map.graphicLayer.clear();

          this.showMxypTilesetFlat(positions, flatHeight);
        },
      });
    }

    drawMxypPolyExtent(flatHeight) {
      this.enableControl(false);

      this.map.graphicLayer.startDraw({
        type: "rectangle",
        style: {
          color: "#007be6",
          opacity: 0.8,
        },
        success: (graphic) => {
          //绘制成功后回调
          this.enableControl(true);

          var positions = graphic.getOutlinePositions(false);
          this.map.graphicLayer.clear();

          this.showMxypTilesetFlat(positions, flatHeight);
        },
      });
    }

    showMxypTilesetFlat(positions, height) {
      var tileset = this._mxypTileset || this.map.pick3DTileset(positions); //拾取绘制返回的模型
      if (!this.tilesetFlat || this.tilesetFlat.tileset != tileset) {
        if (!tileset) {
          haoutil.msg("请单击选择模型");
          return;
        }
        this.clearMXYP();
        this.tilesetFlat = new mars3d.thing.TilesetFlat({
          tileset: tileset,
          positions: positions,
          height: height,
        });
        this.map.addThing(this.tilesetFlat);
      } else {
        this.tilesetFlat.height = height;
      }

      this.tilesetFlat.addArea(positions);
    }

    //=========模型裁剪========
    createMXCJ() {}
    destroyMXCJ() {
      this.clearMXCJ();

      if (this.tilesetClip) {
        this.map.removeThing(this.tilesetClip, true);
        delete this.tilesetClip;
      }
    }
    clearMXCJ() {
      if (this.tilesClipPlan) {
        this.map.removeThing(this.tilesClipPlan, true);
        delete this.tilesClipPlan;
      }
      if (this.tilesetClip) {
        this.tilesetClip.clear();
      }
    }
    drawMxcjPoly(clipOutSide) {
      this.clearMXCJ();

      this.map.graphicLayer.startDraw({
        type: "rectangle",
        style: {
          color: "#007be6",
          opacity: 0.8,
        },
        success: (graphic) => {
          //绘制成功后回调
          var positions = graphic.getOutlinePositions(false);
          this.map.graphicLayer.clear();

          var isAdd = this.addMxcjPoly(positions, clipOutSide);
          if (!isAdd) {
            haoutil.msg("请单击选择模型");
          }
        },
      });
    }
    addMxcjPoly(positions, clipOutSide) {
      var tileset = this.map.pick3DTileset(positions); //拾取绘制返回的模型
      if (!tileset) {
        return false;
      }

      //模型开挖处理类(Plan围合的)
      this.tilesClipPlan = new mars3d.thing.TilesetPlanClip({
        tileset: tileset,
        positions: positions,
        clipOutSide: clipOutSide,
      });
      this.map.addThing(this.tilesClipPlan);

      //倾斜模型开挖处理类（只适用于部分倾斜模型）
      if (!this.tilesetClip || this.tilesetClip.tileset != tileset) {
        if (this.tilesetClip) {
          this.map.removeThing(this.tilesetClip, true);
          delete this.tilesetClip;
        }
        this.tilesetClip = new mars3d.thing.TilesetClip({
          tileset: tileset,
          positions: positions,
          clipOutSide: clipOutSide,
        });
        this.map.addThing(this.tilesetClip);
      } else {
        this.tilesetClip.addArea(positions);
      }

      return true;
    }
  }

  //注册到widget管理器中。
  mars3d.widget.bindClass(MyWidget);

  //每个widet之间都是直接引入到index.html中，会存在彼此命名冲突，所以闭包处理下。
})(window, mars3d);
