/*
 * @Author: your name
 * @Date: 2022-01-11 13:45:12
 * @LastEditTime: 2022-03-22 10:35:13
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /test/hello-world/src/utils/mapClass.js
 */
import { pipeColor, svgUrl, svgAlarm } from "@/utils/mapClassForBigOld/config.js";

// 编辑类
// 在地图上新增的设备可以直接编辑，
// 已经保存完成的设备需要点编辑才可以编辑
export class EditorMap {
  // 地图的对象实例
  map = null;
  // 外部传进来的中心店
  center = null;
  // 父vue的实例
  vue = null;
  // 操作 新建，编辑，删除，编辑跟删除只对已经在图上的设备有效 默认值：0， 新建：1，编辑：2, 删除: 3。
  // 新建的时候会把未保存的线条清空
  control = 0;
  // 鼠标事件对象，用来将点跟线上图
  mousetool = null;
  // 当前正在手动绘制的对象
  nowMouseTarget = null;
  // 当线mousetool线被按下的时候的flag 当线被按下的时候为true，就不询问是否删除了
  mosueToolPolineDownFlag = false;
  // 绘制marer的时候的配置，在绘制完挂载事件的时候需要使用
  mouseToolMarkerOptions = null;
  // 绘制poline的时候的配置，在绘制完挂载事件的时候需要使用
  mouseToolPolineOptions = null;

  // 存放所有的设备的数组集合，这是一个对象，对象里面是各种设备的数组
  allDevice = {};
  // 存放所有的管道
  pipeArr = {};
  // 报警设备的对象
  alarmObj = {};
  // 当前的infowindow的组件
  infowindowComponent = null;
  // infowindow本身
  infowindow = null;

  constructor(contaienr, config = {}, vue) {
    this.map = new AMap.Map(contaienr, {
      viewMode: "3D",
      center: [114.196007, 38.260288],
      layers: [AMap.createDefaultLayer()], // layers 字段为空或者不赋值将会自动创建默认底图。
      zoom: 14,
      ...config,
    });
    const { center } = config;
    this.center = center;
    this.vue = vue;
    this.init();
  }

  init() {
    // 地图事件
    this.mapEvent();
    // 手动点线上图准备,编辑模式
    this.mouseAddDevice();
    // this.mouseAddMarker();
    // this.mouseAddPipeline();
    // 地图边界
    this.map.getCity((res) => {
      const city = res.district;
      this.mapBound(city);
    }, this.center);
  }
  mapBound(city) {
    var district = new AMap.DistrictSearch({
      extensions: "all", // 返回行政区边界坐标等具体信息
      level: "district", // 设置查询行政区级别为 区
    });
    district.search(city, (status, result) => {
      // 获取朝阳区的边界信息
      var bounds = result.districtList[0].boundaries;
      var polygons = [];
      console.log("boundsboundsboundsboundsbounds", bounds);

      if (bounds) {
        for (var i = 0, l = bounds.length; i < l; i++) {
          //生成行政区划polygon
          // new AMap.Polygon({
          //   map: this.map,
          //   strokeWeight: 2,
          //   path: bounds[i],
          //   fillOpacity: 1,
          //   fillColor: "transparent",
          //   strokeColor: "#09f",
          // });
          new AMap.Polyline({
            map: this.map,
            strokeWeight: 4,
            strokeColor: "#09f",
            path: bounds[i],
          });
          // polygons.push(polygon);
        }
      }
    });
  }
  // map的事件监听
  mapEvent() {
    this.map.on("click", () => {
      // mousetool对象画出的对象的操作
      // 如果有手动绘制对象，要手动清楚一下，因为画线的时候不好清除旧线，这其实是用来清楚旧线的
      // 当画出来的线被mousedown，不删除，但是mouseToolPipeLineFlag要归位，在移出线的时候统一归位
      // 如果对象是marker，直接删除
      if (this.nowMouseTarget?.type == "AMap.Marker") {
        this.mouseToolDrawClear();
      } else {
        // 当地图上已经画了线，并且没有点在线上，询问是否删除
        if (this.nowMouseTarget && !this.mosueToolPolineDownFlag) {
          this.confirm("是否重新绘制管道", { type: "warning" })
            .then(() => {
              // 删除原来的线
              this.mouseToolDrawClear();
              // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
              this.mousetool.polyline(this.mouseToolPolineOptions);
            })
            .catch(() => {});
        }
      }
    });
    this.map.on("moveend", () => {
      console.log("地图停止移动");
      if (this.flag) {
        console.log("弹框");
        this.flag = false;
      }
    });
    window.panTo = () => {
      this.flag = true;
      this.map.panTo([116.428285, 39.886129]);
    };
  }
  // 弹框工具
  confirm(message, obj) {
    return this.vue.$confirm(message, obj);
  }

  // 改变操作状态
  changeControl(num) {
    this.control = num;
  }

  // 点线编辑上图准备
  mouseAddDevice() {
    this.map.plugin(["AMap.MouseTool"], () => {
      this.mousetool = new AMap.MouseTool(this.map);
    });
    // 挂载绘制结束的事件
    this.mouseDrawEvent();
  }

  // 点或者线上图结束后触发的事件
  mouseDrawEvent() {
    this.mousetool.on("draw", (e) => {
      const target = e.obj;
      // console.log([target._position.lng, target._position.lat]);
      const { type: targetType } = target;
      // 当这个点是marker的时候
      if (targetType == "AMap.Marker") {
        this.mouseToolMarkerEvent(target);
      } else {
        // 如果是线,挂上编辑
        this.lineEditor(target);
        this.mousetool.close();
        this.mouseToolPolineEvent(target);
        console.log(targetType, "当前对象是管道");
      }
      this.nowMouseTarget = target;
    });
  }

  // 绘制marker结束后，在marker身上添加的事件
  mouseToolMarkerEvent(target) {
    // 由于画出来的marker点击会换位置，所以当移入的时候删除绘制事件，移出去在增加绘制事件
    target.on("mouseover", (e) => {
      // 鼠标事件关闭
      this.mousetool.close(false);
    });
    target.on("mouseout", (e) => {
      // 这里不方便获取原来的属性，因为position不好解决，还是设置一个值吧
      // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
      this.mousetool.marker(this.mouseToolMarkerOptions);
    });
    // 点
    target.on("click", (e) => {
      // 弹框
    });
  }
  // 挂上线以及线的事件
  lineEditor(line) {
    // line.editor && line.editor.close();
    // 当前点击次数，1次为编辑，2次为弹框
    line.editorNum = 0;
    line.editor = new AMap.PolyEditor(this.map, line);
  }
  // 绘制管道的时候，挂载的事件
  mouseToolPolineEvent(target) {
    // 线按下的时候会变成编辑，mousetool事件会清空 移出线的时候 在把polyline事件加上
    target.on("mouseover", (e) => {
      // 鼠标事件关闭
      // this.mousetool.close(false);
    });
    target.on("mouseout", (e) => {
      // 有时候按在线上移动地图，map点击事件中mosueToolPolineDownFlag无法归位，在这里归位
      this.mosueToolPolineDownFlag = false;
      // 鼠标事件开启，并且赋值原来的属性，this.mouseToolMarkerOptions是开启绘制的时候记录的
      // this.mousetool.polyline(this.mouseToolPolineOptions);
    });
    // 线
    target.on("mousedown", (e) => {
      const line = e.target;
      // mosueTool按下的flag,按在线上，不询问是否删除
      this.mosueToolPolineDownFlag = true;
      // 按下的时候要关闭事件
      this.mousetool.close(false);
      // 如果当前状态不是编辑，则进入编辑状态
      if (line.editorNum < 1) {
        // 打开并且++
        line.editor.open();
        line.editorNum++;
      } else {
        // 这里就要弹框了
        console.log(line.getPath());
      }
    });
  }
  // 设备点击上图开启
  mouseAddMarker(markerObj = {}) {
    // 清空已经绘制完的对象
    this.mousetoolClose(true);
    // 记录一下配置项，在挂载点击的时候，需要使用
    this.mouseToolMarkerOptions = {
      draggable: true,
      ...markerObj,
    };
    this.mousetool.marker(this.mouseToolMarkerOptions);
  }
  // 管线点击上图开启
  mouseAddPipeline(pipeObj = {}) {
    this.mousetoolClose(true);
    // 开始画线
    this.mosuetoolPolineFlag = true;
    this.mouseToolPolineOptions = {
      strokeWeight: 5,
      ...pipeObj,
    };
    this.mousetool.polyline(this.mouseToolPolineOptions);
  }

  // 手动清除map上绘制的对象
  mouseToolDrawClear() {
    if (this.nowMouseTarget) {
      this.map.remove(this.nowMouseTarget);
      // 如果有editor,则关闭
      this.nowMouseTarget.editor && this.nowMouseTarget.editor.close();
      this.nowMouseTarget = null;
    }
  }
  // 关闭点击上图事件 true清除之前绘制的图像，false 仅关闭上图事件
  mousetoolClose(boolean) {
    //  清空地图上的绘制对象的同时,也要清楚这个nowMouseTarget控制对象
    if (this.nowMouseTarget) {
      // 如果有editor,则关闭
      this.nowMouseTarget.editor && this.nowMouseTarget.editor.close();
      this.nowMouseTarget = null;
    }
    this.mousetool.close(boolean);
  }

  /**
   *
   *
   *
   *
   *
   *
   * 地图上add设备
   *
   *
   * @description:
   * @param {*} deviceData marker的数据
   * @param {*} compontent marker点击弹出的infowindow的组件
   * @return {*}
   */
  addDevice(deviceData, compontent) {
    const { longitude: lng, latitude: lat, iconType } = deviceData;
    const icon = svgUrl[iconType];
    console.log("icon", icon);
    let device = this.createMarker({
      map: this.map,
      anchor: "bottom-center",
      icon,
      position: [lng, lat],
      extData: deviceData,
      // label:{
      //   content:123,
      //   direction:"top",
      // }
    });
    // device.hide();
    // 如果没有有这个公司的数组，就创建，有就直接push
    if (!Array.isArray(this.allDevice[iconType])) {
      this.allDevice[iconType] = [];
    }
    this.allDevice[iconType].push(device);
    // 设备的事件函数
    this.deviceEvent(device, compontent);
  }
  deviceEvent(device, compontent) {
    device.on("click", (e) => {
      const target = e.target;
      // 如果control==0就是默认值，没有使用123功能，就显示infowindow
      if (this.control == 0) {
        this.markerClick(target, compontent);
      } else if (this.control == 2) {
        // 2是已经上图的设备拥有的编辑功能
      } else if (this.control == 3) {
        // 3是删除操作
      }
    });
    device.on("mouseover", (e) => {
      const target = e.target;
      const data = target.getExtData();
      console.log(data);
      const name =
        data.nickName ||
        data.deviceName ||
        data.videoName ||
        data.stationName ||
        data.time;
      target.setLabel({ content: name, direction: "top" });
    });
    device.on("mouseout", (e) => {
      const target = e.target;
      const data = target.getExtData();
      target.setLabel({ content: "" });
    });
  }
  /** 点击marker出现infowindow
   * @description:
   * @param {*} target 点击的对象
   * @param {*} compontent marker点击弹出的infowindow的组件
   * @return {*}
   */
  markerClick(target, compontent) {
    const deviceExtData = target.getExtData();

    const { longitude: lng, latitude: lat } = deviceExtData;

    // 创建一个可以控制的组件，将其dom插入infowindow
    this.infowindowComponent = this.createInfowindowDom(
      this.vue,
      this,
      deviceExtData,
      compontent
    );

    // 没恩么用，控制台测试的时候用着玩的
    window.func = () => {
      const { longitude: lng, latitude: lat } = target.getExtData();
      const cd = {
        id: 1,
        name: "9",
        lng,
        lat,
      };
      this.infowindowComponentChange(cd);
      target.setExtData(cd);
    };
    this.infowindow = new AMap.InfoWindow({
      isCustom: true,
      content: this.infowindowComponent.$el,
      position: [lng, lat],
      // anchor: "top-left",
      // offset: [20, -45],
      anchor: "middle-left",
      offset: [20, -10],
    });

    this.infowindow.open(this.map);
  }
  // 创建要加入到infowindow里的
  createInfowindowDom(vueRoot, mapClass, deviceData, compontent) {
    const Component = this.vue.$Vue.extend(compontent, {});
    return new Component({
      data() {
        return {
          // 当前vue实例
          vueRoot,
          // 自己写的map类
          mapClass,
          // 数据
          deviceData,
        };
      },
    }).$mount();
  }
  // 当前显示的infowindow内部的数据发生变化，一般在socket传回数据的时候使用
  infowindowComponentChange(data) {
    this.infowindowComponent.deviceData = data;
  }
  // 创建marker
  createMarker(MarkerOptions) {
    return new AMap.Marker(MarkerOptions);
  }

  // 地图上add管道
  addPipeLine(objData, component) {
    const { path, pipePressure, iconType } = objData;
    // 根据压力获取颜色
    const color = pipeColor[pipePressure + 1];
    const pipe = this.createPipeLine({
      path: eval(path),
      strokeWeight: 4,
      strokeColor: color,
      extData: objData,
      cursor: "pointer",
    });

    this.map.add(pipe);
    // pipe.hide();
    if (!Array.isArray(this.pipeArr[iconType])) {
      this.pipeArr[iconType] = [];
    }
    this.pipeArr[iconType].push(pipe);
    // console.log(this.pipeArr);
    // this.map.panTo([path[0][0], path[0][1]]);
    this.pipeEvent(pipe, component);
  }
  createPipeLine(pipeLineOptions) {
    return new AMap.Polyline(pipeLineOptions);
  }
  pipeEvent(pipe, compontent) {
    pipe.on("mouseover", (e) => {
      const target = e.target;
      // 获取当前颜色
      const options = target.getOptions();
      options.strokeColor = "blue";
      target.setOptions(options);
    });

    pipe.on("mouseout", (e) => {
      const target = e.target;
      // 根据管道压力获取颜色
      const { pipePressure } = target.getExtData();
      const color = pipeColor[pipePressure + 1];
      // 获取当前颜色
      const options = target.getOptions();
      options.strokeColor = color;
      target.setOptions(options);
    });
    pipe.on("click", (e) => {
      const target = e.target;
      target.lnglat = e.lnglat;
      // 如果control==0就是默认值，没有使用123功能，就显示infowindow
      if (this.control == 0) {
        this.pipeClick(target, compontent);
      } else if (this.control == 2) {
        // 2是已经上图的设备拥有的编辑功能
      } else if (this.control == 3) {
        // 3是删除操作
      }
    });
  }

  pipeClick(target, compontent) {
    const deviceExtData = target.getExtData();
    const { lng, lat } = target.lnglat;
    // 创建一个可以控制的组件，将其dom插入infowindow
    this.infowindowComponent = this.createInfowindowDom(
      this.vue,
      this,
      deviceExtData,
      compontent
    );
    // 没恩么用，控制台测试的时候用着玩的
    // window.func = () => {
    //   const { lng, lat } = target.getExtData();
    //   const cd = {
    //     id: 1,
    //     name: "9",
    //     lng,
    //     lat,
    //   };
    //   this.infowindowComponentChange(cd);
    //   target.setExtData(cd);
    // };
    this.infowindow = new AMap.InfoWindow({
      isCustom: true,
      content: this.infowindowComponent.$el,
      position: [lng, lat],
      // anchor: "top-left",
      // offset: [20, -15],
      anchor: "middle-left",
      offset: [20, 0],
    });
    this.infowindow.open(this.map);
  }
  infowindowClose() {
    if (!this.infowindow) return;
    this.infowindow.close();
  }
  // 设备以及公司过滤
  allfilter(companyArr, typeArr) {
    for (let pipeItem in this.pipeArr) {
      this.pipeArr[pipeItem].forEach((pipe) => {
        const data = pipe.getExtData();
        if (companyArr.indexOf(data.companyType + "") >= 0) {
          pipe.show();
        } else {
          pipe.hide();
        }
      });
    }
    for (let deviceItem in this.allDevice) {
      this.allDevice[deviceItem].forEach((device) => {
        const data = device.getExtData();
        // 设备过滤受到bigwindow页面的的两种制约，companyArr, typeArr 两个数组制约显示隐藏
        // 燃气没有公司，所以没有device.companyType不收到公司的控制
        const companyHas = companyArr.indexOf(data.companyType + "") >= 0;
        // 设备存在 受到设备按钮限制
        const deviceHas = typeArr.indexOf(+data.iconType) >= 0;
        // 如果是燃气公司的话，不受按钮限制
        const enterprise = data.iconType == 7 || data.iconType == 8;
        // 必须设备存在数组里，才会显示设备 !data.companyType代表用户不受公司制约
        if (enterprise || (deviceHas && (companyHas || !data.companyType))) {
          device.show();
        } else {
          device.hide();
        }
      });
    }
  }
  // 普通调用方法
  // 设备报警
  deviceAlarm(obj) {
    // 设备的类型
    const { iconType } = obj;
    const publicId = obj.userId || obj.deviceId;
    // 找到这个设备所属的空间
    const device = this.allDevice[iconType].filter(
      (item) =>
        (item.getExtData().userId || item.getExtData().deviceId) == publicId
    )[0];
    // 更改的icon
    const icon = svgAlarm[iconType];
    device.setIcon(icon);
    device.setzIndex(13);
    // 将旧的值缓存一下
    // device.oldData = device.getExtData();
    // device.setExtData(obj);
    // 可能出现infoWindow数据变化
    this.alarmInfowindowChange(obj);
    if (!this.alarmObj[iconType]) {
      this.alarmObj[iconType] = [];
    }
    const ind = this.alarmObj[iconType].indexOf(publicId);
    if (ind < 0) {
      this.alarmObj[iconType].push(publicId);
    }
  }
  // 报警时候，可能发生infowindowComponent存在，也要变化
  alarmInfowindowChange(obj) {
    if (!this.infowindowComponent) return;
    // 如果infowindow是打开的，就改变里面的数据 必须是  调压箱2 阀门3 用户6 才会发生变化电话
    const infowindowDeviceType = [2, 3, 6].includes(
      this.infowindowComponent.deviceData.iconType
    );
    // 如果存在userId就用userId，如果存在deviceId就用deviceId
    const infowindowDeviceId =
      this.infowindowComponent.deviceData.userId ||
      this.infowindowComponent.deviceData.deviceId;
    // 如果存在userId就用userId，如果存在deviceId就用deviceId
    const objId = obj.userId || obj.deviceId;
    // 如果两个值匹配,才可以改变infowindow身上的组件
    const infowindowComponentHas = infowindowDeviceId == objId;
    if (
      this.infowindowComponent &&
      infowindowDeviceType &&
      infowindowComponentHas
    ) {
      // this.infowindowComponentChange(obj);
      if (this.infowindowComponent.http) {
        this.infowindowComponent.myHttp();
      }
    }
  }
  //如果传过来的报警设备中，有不在deviceAlarm中，就是恢复的设备恢复
  relieveAlarm(alarmObj) {
    // 把报警数组改变结构,如果有userId就是用户，如果有deviceId就是其他设备
    const httpObj = {};
    alarmObj.forEach((item) => {
      const publicId = item.userId || item.deviceId;
      if (!Array.isArray(httpObj[item.iconType])) {
        httpObj[item.iconType] = [];
      }
      httpObj[item.iconType].push(publicId);
    });
    // 循环现有报警设备
    for (let iconType in this.alarmObj) {
      const arr = this.alarmObj[iconType];
      // 循环现有报警设备
      for (let i = 0; i < arr.length; i++) {
        // 看看现有报警设备中有没有不在 报警数组中的值，有就恢复可能是userId，也可能是deviceId
        const publicId = arr[i];
        // 看看接口传来的数据中还有没有这些Id，如果没有了，就是修好了
        const hasId = httpObj[iconType]?.includes(publicId);
        // 如果已经不在报警数组中,就要去大数组中找他,利用userId
        // 如果id不存在了，说明不报警了
        if (!hasId) {
          // 过滤出来这个要恢复的设备
          const device = this.allDevice[iconType].filter(
            (item) =>
              (item.getExtData().userId || item.getExtData().deviceId) ==
              publicId
          )[0];
          // 恢复
          const icon = svgUrl[iconType];
          device.setIcon(icon);
          // 赋值
          // const deviceData = { ...device.oldData };
          // device.setExtData(deviceData);
          // device.oldData = null;
          // 如果infowindow是打开的
          this.alarmInfowindowChange(device.getExtData());
          // 在arr中删掉
          arr.splice(i, 1);
          // 由于删掉了当前，所以要--恢复位置
          i--;
        }
      }
    }
  }

  // ws协议方法
  wsAlarm(obj) {
    const { iconType, userId, userStatus } = obj;
    const decice = this.allDevice[iconType].filter(
      (item) => item.getExtData().userId == userId
    )[0];
    let icon = null;
    // 2报警，1恢复
    if (userStatus == 2) {
      icon = svgAlarm[iconType];
      device.oldData = device.getExtData();
      device.setExtData(obj);
    } else if (userStatus == 1) {
      icon = svgUrl[iconType];
      const oldData = device.oldData;
      device.setExtData(oldData);
      device.oldData = null;
    }
    decice.setIcon(icon);
  }
  // 卫星图切换
  satellite = null;
  changeMap(bool) {
    // 卫星,
    if (!bool) {
      if (this.satellite) return;
      this.satellite = new AMap.TileLayer.Satellite();
      this.map.addLayer(this.satellite);
    } else {
      if (this.satellite) {
        this.map.removeLayer(this.satellite);
        this.satellite = null;
      }
    }
  }
  // 轨迹回放
  /**
   * @description:
   * @param {*} vehicleId 设备id
   * @param {*} path 轨迹回访率丼
   * @return {*}
   */
  backTrack(vehicleId, path, times,component) {
    this.infowindowClose();

    AMap.plugin("AMap.MoveAnimation", () => {
      let marker = this.allDevice[9].filter(
        (item) => item.getExtData().vehicleId == vehicleId
      )[0];

      // 绘制轨迹
      marker.polyline = new AMap.Polyline({
        map: this.map,
        path,
        showDir: true,
        strokeColor: "#28F", //线颜色
        // strokeOpacity: 1,     //线透明度
        strokeWeight: 6, //线宽
        // strokeStyle: "solid"  //线样式
      });
      marker.passedPolyline = new AMap.Polyline({
        map: this.map,
        strokeColor: "#AF5", //线颜色
        strokeWeight: 6, //线宽
      });
      marker.on("moving", (e) => {
        marker.passedPolyline.setPath(e.passedPath);
        // this.map.setCenter(e.target.getPosition(), true);
        // console.log(getPosition());
      });

      // 每个path的点
      // marker.pointArr = [];
      // carTarget

      //点击的时候，先传进来一个点
      const carPathData = { ...marker.getExtData(), time: times[0] };
      carPathData.iconType = 14;
      this.addDevice(carPathData,component);
      // marker.pointArr.push(point);

      marker.on("moveend", (e) => {
        // this.addDevice(carPathData,carBackComponent);
        // 如果不是最后一个点，就创建一个新的worderpoint，如果是就不创建，并且把自身删除

        let z = {
          longitude: e.pos[0],
          latitude: e.pos[1],
          iconType: 14,
          time: times[e.index],
        };
        // if (e.index == path.length - 1) {
        //  point = this.addDevice(z, null);
        // } else {
        this.addDevice(z,component);
        // workPoint.infoWindow.open(map,e.passedPos);
        // }
        console.log("定点", e);
      });

      marker.moveAlong(path, {
        // 每一段的时长
        duration: 8000, //可根据实际采集时间间隔设置
        // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
        autoRotation: true,
      });
    });
  }

  clearbackTrack(vehicleId) {
    // let marker = this.allDevice[9].filter(
    //   (item) => item.getExtData().vehicleId == vehicleId
    // )[0];
    this.allDevice["9"]?.forEach((item) => {
      if (item) {
        // 停止运动
        item.stopMove();
        // 删除每个点
        console.log(item.pointArr);

        if (item.polyline) {
          this.map.remove(item.polyline);
        }
        if (item.passedPolyline) {
          this.map.remove(item.passedPolyline);
        }
        this.map.remove(item);
      }
    });
    // 最后把数组清空
    this.allDevice["9"] = [];
    // 把car的路径点也清空
    this.allDevice["14"]?.forEach((iten) => {
      this.map.remove(iten);
    });
    this.allDevice["14"] = [];
    this.infowindowClose();
  }
}
