(function (window, mars3d) {
  /**
   * 创建widget类，需要继承BaseWidget
   */
  class MyWidget extends mars3d.widget.BaseWidget {
    /**
     *
     *弹窗配置
     * @readonly
     * @memberof MyWidget
     */
    get view() {
      return {
        type: "window",
        url: "view.html",
        windowOptions: {
          width: 250,
          position: {
            top: 50,
            right: 5,
            bottom: 5,
          },
        },
      };
    }

    //初始化[仅执行1次]
    create() {
      this.storageName = "mars3d_roamLine";
      this.arrFlyTable = [];

      this.graphicLayer = new mars3d.layer.GraphicLayer({
        name: this.config.name,
        pid: 99, //图层管理 中使用，父节点id
        hasEdit: true,
      });

      //事件监听
      this.graphicLayer.on(mars3d.EventType.drawCreated, (e) => {
        if (this.viewWindow) {
          this.viewWindow.plotlist.plotEnd();
        }
      });
      this.graphicLayer.on(mars3d.EventType.editStart, (e) => {
        var graphic = e.graphic;
        this.startEditing(graphic);
      });
      this.graphicLayer.on(mars3d.EventType.editMovePoint, (e) => {
        var graphic = e.graphic;
        this.startEditing(graphic);
      });
      this.graphicLayer.on(mars3d.EventType.editRemovePoint, (e) => {
        var graphic = e.graphic;
        this.startEditing(graphic);
      });
      this.graphicLayer.on(mars3d.EventType.editStop, (e) => {
        var graphic = e.graphic;
        this.stopEditing(graphic);
        this.saveGraphic(graphic);
      });
    }
    //每个窗口创建完成后调用
    winCreateOK(opt, result) {
      this.viewWindow = result;
      this.getList();
    }
    //激活插件
    activate() {
      this.graphicLayer.hasEdit = true;
      this.map.addLayer(this.graphicLayer);
    }
    //释放插件
    disable() {
      this.viewWindow = null;
      this.graphicLayer.stopDraw();

      this.map.removeLayer(this.graphicLayer);
    }
    //编辑时只显示本身路线，其他路线隐藏
    hideOtherLine() {
      if (this.lastEditGraphic) {
        this.lastEditGraphic.show = false;
        this.lastEditGraphic = null;
      }
    }

    /**
     * 开始标记
     * @param {Object} defval
     * @memberof MyWidget
     */
    startDraw(defval) {
      this.hideOtherLine();
      this.graphicLayer.startDraw(defval);
    }
    startEditingById(id) {
      var graphic = this.graphicLayer.getGraphicById(id);
      if (graphic == null) {
        return;
      }
      graphic.flyTo();

      this.graphicLayer.startEditing(graphic);
    }
    startEditing(graphic) {
      this.hideOtherLine();
      this.lastEditGraphic = graphic;

      graphic.show = true;
      graphic.options.id = graphic.id;
      this.viewWindow.plotEdit.startEditing(graphic.options, graphic.coordinates);
    }
    stopEditing() {
      if (this.viewWindow) {
        this.viewWindow.plotEdit.stopEditing();
      }
    }
    stopDraw() {
      this.graphicLayer.stopDraw();
    }
    //更新图上的属性
    updateAttr2map(attr) {
      this.lastEditGraphic.setOptions(attr);
    }
    //更新图上的几何形状、坐标等
    updateGeo2map(coords, withHeight) {
      var positions = [];
      if (withHeight) {
        for (let i = 0; i < coords.length; i += 3) {
          let point = Cesium.Cartesian3.fromDegrees(coords[i], coords[i + 1], coords[i + 2]);
          positions.push(point);
        }
      } else {
        for (let i = 0; i < coords.length; i += 2) {
          let point = Cesium.Cartesian3.fromDegrees(coords[i], coords[i + 1], 0);
          positions.push(point);
        }
      }
      this.lastEditGraphic.positions = positions;

      return positions;
    }
    centerCurrentGraphic() {
      this.lastEditGraphic.flyTo();
    }
    //文件处理
    getGeoJson() {
      return this.graphicLayer.toGeoJSON();
    }
    loadGeoJSON(json, isClear, isFly) {
      if (json == null) {
        return;
      }

      return this.graphicLayer.loadGeoJSON(json, {
        mergeDefaultStyle: true,
        clear: isClear,
        flyTo: isFly,
      });
    }
    deleteAll() {
      this.graphicLayer.clear();
      this.deleteAllData();
    }
    deleteGraphic(id) {
      var graphic = this.graphicLayer.getGraphicById(id);
      if (graphic == null) {
        return;
      }

      this.delGraphic(id);
      this.graphicLayer.removeGraphic(graphic);
    }
    deleteCurrentGraphic() {
      var graphic = this.lastEditGraphic;
      if (graphic == null) {
        return;
      }

      this.delGraphic(graphic.id);
      this.graphicLayer.deleteGraphic(graphic);
    }
    hasEdit(val) {
      this.graphicLayer.hasEdit = val;
    }

    //数据保存处理
    getList() {
      if (window.hasServer) {
        //后台接口查询
        // window.sendAjax({
        //   url: 'map/flyroute/list',
        //   data: {
        //     userId: haoutil.storage.get('userId'),
        //   },
        //   type: 'get',
        //   dataType: 'json',
        //   contentType: 'application/x-www-form-urlencoded',
        //   success: (result) => {
        //     for (let i = 0; i < result.length; i++) {
        //       let geojson = JSON.parse(result[i].geojson)
        //       geojson.id = result[i].id
        //       this.arrFlyTable.push(geojson)
        //     }
        //     this.showData(this.arrFlyTable)
        //     if (this.viewWindow) {
        //       this.viewWindow.tableWork.loadData(this.arrFlyTable)
        //     }
        //   },
        // })
      } else {
        //本地缓存
        var laststorage = haoutil.storage.get(this.storageName); //读取localStorage值
        if (laststorage != null) {
          this.arrFlyTable = eval(laststorage);
        }

        if (this.arrFlyTable == null || this.arrFlyTable.length == 0) {
          this.arrFlyTable = [];

          $.getJSON(this.path + "data/fly.json", (result) => {
            this.arrFlyTable = this.arrFlyTable.concat(result);
            this.showData(this.arrFlyTable);
            if (this.viewWindow) {
              this.viewWindow.tableWork.loadData(this.arrFlyTable);
            }
          });
        } else {
          this.showData(this.arrFlyTable);
          if (this.viewWindow) {
            this.viewWindow.tableWork.loadData(this.arrFlyTable);
          }
        }
      }
    }
    showData(arr) {
      this.graphicLayer.clear();

      for (var i = 0; i < arr.length; i++) {
        var item = arr[i];

        let graphic = new mars3d.graphic.PolylineEntity({
          id: item.id,
          positions: item.positions,
          style: item.style,
          attr: item.attr,
          show: false,
        });
        this.graphicLayer.addGraphic(graphic);
      }
    }
    deleteAllData() {
      haoutil.storage.del(this.storageName);

      this.arrFlyTable = [];
      if (this.isActivate && this.viewWindow != null) {
        this.viewWindow.tableWork.loadData(this.arrFlyTable);
      }
    }
    delGraphic(id) {
      this.graphicLayer.stopDraw();
      // if (window.hasServer) {
      //   window.sendAjax({
      //     url: 'v1/map/flyroute/' + id,
      //     type: 'delete',
      //     dataType: 'json',
      //     contentType: 'application/json',
      //     success: function (result) {
      //       console.log('删除漫游路线成功，返回数据：' + JSON.stringify(result))
      //     },
      //     error: function (XMLHttpRequest, textStatus, errorThrown) {
      //       alert('服务出错：' + XMLHttpRequest.statusText + '，代码 ' + XMLHttpRequest.status)
      //     },
      //   })
      // }

      for (var index = this.arrFlyTable.length - 1; index >= 0; index--) {
        if (this.arrFlyTable[index].id == id) {
          this.arrFlyTable.splice(index, 1);
          break;
        }
      }
      haoutil.storage.add(this.storageName, JSON.stringify(this.arrFlyTable));

      if (this.isActivate && this.viewWindow != null) {
        this.viewWindow.tableWork.loadData(this.arrFlyTable);
      }
    }

    saveGraphic(graphic) {
      if (graphic.positionsShow.length < 2) {
        //路线点数小于2个
        return;
      }

      if (graphic.attr.name == null || graphic.attr.name == "") {
        graphic.attr.name = "路线" + new Date().format("MMddHHmmss");
      }

      var item = graphic.toJSON();
      console.log("保存路线", item);

      if (window.hasServer) {
        //后台接口
        // item = JSON.stringify(item)
        // window.sendAjax({
        //   url: 'v1/map/flyroute/update',
        //   data: JSON.stringify({
        //     name: graphic.attr.name, //名称
        //     geojson: item, //genjson
        //     id: graphic.attr.id,
        //     remark: graphic.attr.remark, //备注
        //   }),
        //   type: 'post',
        //   dataType: 'json',
        //   contentType: 'application/json',
        //   success: (result) => {
        //     console.log('修改漫游成功，返回数据：' + JSON.stringify(result))
        //   },
        // })
      } else {
        //保存到本地缓存
        var isFind = false;
        for (var index = this.arrFlyTable.length - 1; index >= 0; index--) {
          if (this.arrFlyTable[index].id == item.id) {
            isFind = true;
            this.arrFlyTable[index] = item;
            break;
          }
        }
        if (!isFind) {
          this.arrFlyTable.push(item);
        }

        haoutil.storage.add(this.storageName, JSON.stringify(this.arrFlyTable));
        if (this.isActivate && this.viewWindow != null) {
          this.viewWindow.tableWork.loadData(this.arrFlyTable);
        }
      }
    }
    toRoamFly(lineData) {
      var data = this.getFormatData(lineData);
      if (!data || !data.positions || data?.positions?.length < 2) {
        haoutil.msg("漫游路线数据有误！");
        return;
      }
      mars3d.widget.activate({
        uri: "widgets/roamFly/widget.js",
        data: data,
      });
    }
    saveForGeoJson(lineData) {
      var data = this.getFormatData(lineData);
      haoutil.file.downloadFile(data.name + ".json", JSON.stringify(data));
      haoutil.msg("下载的Json可以直接用于 mars3d.graphic.RoamLine(options) 传参使用");
    }
    //保存为czml
    saveForCzml(lineData) {
      if (lineData.positions.length < 2) {
        toastr.error("路线无坐标数据，无法生成！");
        return;
      }
      var data = this.getFormatData(lineData);

      let roamLine = new mars3d.graphic.RoamLine(data);
      this.map.graphicLayer.addGraphic(roamLine);

      var czml = JSON.stringify(roamLine.toCZML());
      roamLine.destroy();

      haoutil.file.downloadFile(lineData.attr.name + ".czml", czml);
    }
    //转为flyLine需要的参数格式
    getFormatData(lineData) {
      var attr = lineData.attr;
      var data = {
        id: lineData.id,
        name: attr.name,
        remark: attr.remark,
        clockLoop: attr.clockLoop,
        camera: {
          type: attr.cameraType,
          followedX: attr.followedX,
          followedZ: attr.followedZ,
          offsetZ: attr.offsetZ,
        },
        showGroundHeight: attr.showGroundHeight,
        clampToGround: attr.clampToGround,
        interpolation: attr.interpolation, //setInterpolationOptions插值

        positions: lineData.positions,
        speed: attr.speed,

        model: this.getModelCfg(attr.model),
      };

      if (attr.showLabel) {
        data.label = {
          show: true,
        };
      }
      if (attr.showLine) {
        data.path = lineData.style;
        data.path.show = true;
      }
      if (attr.showShadow) {
        data.shadow = [{ show: true, type: attr.shadowType }];
      }
      return data;
    }
    getModelCfg(model) {
      //漫游对象
      switch (model) {
        default:
          return { show: false };
        case "model_man": //行人模型
          return {
            show: true,
            uri: "//data.mars3d.cn/gltf/mars/man/walk.gltf",
            scale: 1,
            minimumPixelSize: 30,
          };
        case "model_car": //汽车模型
          return {
            show: true,
            uri: "//data.mars3d.cn/gltf/mars/qiche.gltf",
            scale: 0.2,
            minimumPixelSize: 50,
          };
        case "model_air": //民航飞机模型
          return {
            show: true,
            uri: "//data.mars3d.cn/gltf/mars/feiji.glb",
            scale: 0.1,
            minimumPixelSize: 50,
          };
        case "model_zhanji": //军用飞机模型
          return {
            show: true,
            uri: "//data.mars3d.cn/gltf/mars/zhanji.glb",
            scale: 0.01,
            minimumPixelSize: 50,
          };
        case "model_weixin": //卫星模型
          return {
            show: true,
            uri: "//data.mars3d.cn/gltf/mars/weixin.gltf",
            scale: 1,
            minimumPixelSize: 100,
          };
      }
    }
  }

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

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