<template>
  <div id="baseEditer" ref="graphy">
    <div id="fengMap"></div>
    <div class="canvas-container">
      <canvas id="canvas" :width="canvasWidth" :height="canvasHeight" ref="canvas" tabindex="0"></canvas>
    </div>
  </div>
</template>
<script>
import { SFengParser } from "@saga-web/feng-map";
import { SFloorParser,SItemStatus } from "@saga-web/big";
import { FloorView } from "./../lib/FloorView";
import { EditScence } from "./mapClass/EditScence";
import bus from "@/bus";
import {
  saveGroup,
  readGroup,
  queryTypeGraph,
  publishGraph
} from "@/api/editer.js";
import { STopologyParser } from "./../lib/parsers/STopologyParser";
import { uuid } from "@/components/mapClass/until";
import { SImageItem } from "@saga-web/graph/lib";
import { SPainter, SColor, SFont, SPoint } from "@saga-web/draw";
import { SImageLegendItem } from "@/lib/items/SImageLegendItem";
import store from "../store";
import { Loading } from "element-ui";
import { Message } from "element-ui";
import { SCircleItem } from "@/lib/items/SCircleItem"
window.FENGMAP = null;
//// 底图空间增加字段 isExtracted:boolean true 已被提取过
export default {
  props: {
    cmdType: {
      type: String,
      default: "choice",
      required: false
    },
    changeTextMsg: {
      type: String,
      default: "",
      required: false
    }
  },
  data() {
    return {
      appName: "万达可视化系统",
      key: "23f30a832a862c58637a4aadbf50a566",
      mapServerURL: "http://map.wanda.cn/editor",
      mapthemeUrl: `http://map.wanda.cn/editor/webtheme`,
      canvasWidth: 700,
      canvasHeight: 800,
      fParser: null,
      scene: null,
      view: null,
      floorList: {},
      urlMsg: {},
      chiceItemList: [], //选中itemlist
      hasTypeList: [], // 当前类型下包含的typeid(提取)
      graphId: "",
      initScale: 1, //加载好底图之后的，初始缩放比例
      changeScaleByClick: false, //区分 滚轮，点击 事件改变的缩放比例
      autoSave: null
    };
  },
  mounted() {
    this.canvasWidth = this.$refs.graphy.offsetWidth;
    this.canvasHeight = this.$refs.graphy.offsetHeight - 10;
    this.init();
    // 挂在bus
    this.getBus();
    store.dispatch("getGraphElement", { PageSize: 1000 });
    window.vm = this;
    const that = this;
    document.onkeydown = function(event) {
      const e = event || window.event || arguments.callee.caller.arguments[0];
      if (e && e.key == "Control") {
        // 按 ctrl
        that.scene.isDownCtrl = true;
      }
    };
    document.onkeyup = function(event) {
      const e = event || window.event || arguments.callee.caller.arguments[0];
      if (e && e.key == "Control") {
        // 按 ctrl
        that.scene.isDownCtrl = false;
        this.scene.setCmd = "choice";
      }
    };
    // 自动保存(时间差为一分钟)
    this.autoSave = setInterval(() => {
      this.saveMsgNoMessage();
    }, 60000);
  },
  methods: {
    init() {
      const loadings = Loading.service({
        lock: true,
        text: "Loading",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)"
      });
      document.getElementById(`canvas`).focus();
      this.clearGraphy();
      this.scene = new EditScence();
      window.FENGMAP = new SFengParser(
        "fengMap",
        this.mapServerURL + "/fmap/" + this.urlMsg.fmapID,
        this.key,
        this.appName,
        null,
        this.mapthemeUrl
      );
      const floorid = this.urlMsg.FloorID;
      window.FENGMAP.loadMap(this.urlMsg.fmapID, resp => {
        this.floorList = resp;
        window.FENGMAP
          .loadTheme(
            `${this.mapServerURL}/webtheme/${this.urlMsg.fmapID}/${this.urlMsg.fmapID}.theme`
          )
          .then(response => {
            console.log("获取rf成功", response);
            this.parserData(floorid);
            this.readGraph();
            loadings.close();
          });
        this.view.fitSceneToView();
      });
      // 获取typeid
      this.getTypeId();
      this.scene.emitChange = this.emitChange;
      this.scene.scenceUpdate = this.scenceUpdate;
    },
    parserData(floor) {
      if (floor == "g80") {
        // 屋顶
        if (window.FENGMAP.frImg) {
          const imgItem = new SImageItem(
            null,
            `${this.mapServerURL}/webtheme/${this.urlMsg.fmapID}/${window.FENGMAP.frImg}`
          );
          this.scene.addItem(imgItem);
          this.view.scene = this.scene;
          this.view.fitSceneToView();
          this.loading = false;
          this.isQuerying = false;
        }
      } else {
        if (this.floorList[floor]) {
          window.FENGMAP.parseData(this.floorList[floor], res => {
            if (res.err) {
              console.log(res.err);
              return;
            }
            this.fParser = new SFloorParser(null);
            this.fParser.parseData(res);
            this.scene.fidToItem = {};
            this.fParser.spaceList.forEach(t => {
              t.zOrder = t.zOrder + t.data.Height;
              t.selectable = true;
              this.scene.fidToItem[t.data.SourceId] = t;
              this.scene.addItem(t);
            });
            this.scene.spaceList = this.fParser.spaceList;
            this.fParser.wallList.forEach(t => this.scene.addItem(t));
            this.fParser.virtualWallList.forEach(t => this.scene.addItem(t));
            this.fParser.doorList.forEach(t => this.scene.addItem(t));
            this.fParser.columnList.forEach(t => this.scene.addItem(t));
            this.fParser.casementList.forEach(t => this.scene.addItem(t));
            this.fParser.pList = [];
            res.PList.forEach(t => {
              const item = new SCircleItem(null, t);
              this.fParser.pList.push(item);
              this.scene.fidToItem[t.SourceId] = item;
              this.scene.addItem(item);
            })
            this.view.scene = this.scene;
            this.view.fitSceneToView();
            this.loading = false;
            this.isQuerying = false;
            console.log("success");
          });
        } else {
          console.log("楼层不正确");
        }
      }
    },
    // 读取绘制数据
    readGraph() {
      this.readGroup().then(data => {
        this.graphId = data.Data[0].ID;
        bus.$emit("setGraphId", this.graphId);
        if (data.Data) {
          const parserData = new STopologyParser(null);
          const itemMap = {};
          parserData.parseData(data.Data[0].Elements);
          // 多边形(此item需在直线item添加之前添加)
          parserData.zoneLegendList.forEach(t => {
            this.scene.addItem(t);
            // 记录提取
            if (t.data.Properties && t.data.Properties.FID) {
              this.scene.fidToItem[t.data.Properties.FID].isExtracted = true;
            }
            this.scene.Nodes.push(t);
            itemMap[t.id] = t;
          });
          // 增加文字(此item需在直线item添加之前添加)
          parserData.textMarkerList.forEach(t => {
            this.scene.addItem(t);
            this.scene.Markers.push(t);
            itemMap[t.id] = t;
          });
          // 增加图片(此item需在直线item添加之前添加)
          parserData.imageMarkerList.forEach(t => {
            this.scene.addItem(t);
            this.scene.Markers.push(t);
            itemMap[t.id] = t;
          });
          // 增加图标类图例(此item需在管线item添加之前添加)
          parserData.imageLegendList.forEach(t => {
            this.scene.addItem(t);
            // 记录提取
            if (t.data.Properties && t.data.Properties.FID) {
              this.scene.fidToItem[t.data.Properties.FID].isExtracted = true;
            }
            this.scene.Nodes.push(t);
            if (t.anchorList && t.anchorList.length) {
              t.anchorList.forEach(anc => {
                itemMap[anc.id] = anc;
              });
            }
          });
          // 增加直线
          parserData.lineMarkerList.forEach(t => {
            this.scene.addItem(t);
            this.scene.Markers.push(t);
            // 设置关联Item
            if (t.data.Properties && t.data.Properties.StartItemId) {
              const startItem = itemMap[t.data.Properties.StartItemId];
              startItem?.connect("onMove", t, t.changePos);
              t.startItem = startItem || null;
            }
            if (t.data.Properties && t.data.Properties.EndItemId) {
              const endItem = itemMap[t.data.Properties.EndItemId];
              endItem?.connect("onMove", t, t.changePos);
              t.endItem = endItem || null;
            }
          });
          // 增加管线类(需在图标类图例添加后添加)
          parserData.relationList.forEach(t => {
            this.scene.addItem(t);
            this.scene.Relations.push(t);
            // 设置锚点
            if (t.anchor1ID) {
              const startAnc = itemMap[t.anchor1ID];
              startAnc.isConnected = true;
              startAnc.parent?.connect("changePos", t, t.changePos);
              t.startAnchor = startAnc || null;
            }
            if (t.anchor2ID) {
              const endAnc = itemMap[t.anchor2ID];
              endAnc.isConnected = true;
              endAnc.parent?.connect("changePos", t, t.changePos);
              t.endAnchor = endAnc || null;
            }
          });
          this.view.fitSceneToView();
            // 设置初始化缩放比例
          this.initScale = this.view.scale;
          this.view.maxScale = this.initScale * 10;
          this.view.minScale = this.initScale / 10;
          bus.$emit("initScale", this.view.scale);
          bus.$emit("elementDataChange", this.scene);
        }
      });
    },
    // 监听变化
    emitChange(itemMsg) {
      this.chiceItemList = itemMsg.itemList;
      this.$emit("changeFocusItem", itemMsg);
      bus.$emit("FocusItemChanged", itemMsg);
    },
    // 监听场景元素数据变化
    scenceUpdate(scence) {
      bus.$emit("elementDataChange", scence);
    },
    clearGraphy() {
      if (this.view) {
        this.view.scene = null;
        return;
      }
      this.view = new FloorView("canvas");
      document.getElementById("canvas").focus();
    },
    getBus() {
      bus.$on("changeText", val => {
        this.scene.updatedText(val);
      });
      bus.$on("changeFont", val => {
        this.scene.updatedFontSize(val);
      });
      bus.$on("changeLineWidth", val => {
        this.scene.updatedLineWidth(val);
      });
      bus.$on("changeBorderColor", val => {
        this.scene.updatedBorderColor(val);
      });
      bus.$on("changeFontColor", val => {
        this.scene.updatedFontColor(val);
      });
      bus.$on("itemWidth", val => {
        this.scene.updatedWidth(Number(val));
      });
      bus.$on("itemHeight", val => {
        this.scene.updatedHeight(Number(val));
      });
      bus.$on("itemPositon", (x, y) => {
        this.scene.updatedPosition(Number(x), Number(y));
      });
      bus.$on("changebackColor", val => {
        this.scene.updatedbackColor(val);
      });
      bus.$on("deleiteItem", () => {
        this.scene.deleiteItem();
      });
      bus.$on("changeAlignItem", val => {
        this.scene.changeAlignItem(val);
      });
      bus.$on("extractItem", () => {
        const map = {},type={};
        this.fParser.spaceList.forEach(t => {
          if (this.hasTypeList.indexOf(t.data.Type) > -1) {
            type[t.data.Type] = 'Zone'
            if (map[t.data.Type]) {
              map[t.data.Type]++;
            } else {
              map[t.data.Type] = 1;
            }
          }
        });
        this.fParser.pList.forEach(t => {
          if (this.hasTypeList.indexOf(t.data.Type) > -1) {
            type[t.data.Type] = 'Image'
            if (map[t.data.Type]) {
              map[t.data.Type]++;
            } else {
              map[t.data.Type] = 1;
            }
          }
        });
        const data = [];
        for (const key in map) {
          data.push({
            key: key,
            name: key,
            age: "",
            number: map[key],
            type: type[key],
            address: "提取"
          });
        }
        bus.$emit("exportItem", data);
      });
      bus.$on("saveMsgItem", () => {
        const loading = Message({
          message: "保存中，切勿关闭窗口！",
          type: "warning"
        });
        this.saveMsg()
          .then(() => {
            loading.close();
          })
          .catch(() => {
            loading.close();
          });
      });
      bus.$on("exportByKey", val => {
        if (val.type == "Image") {
          const list = this.fParser.pList.map(t => {
            if (t.data.Type == val.key && val.age.Url) {
                if (!t.isExtracted) {
                  t.isExtracted = true;
                  const data = {
                    ID: uuid(),
                    Name: val.age.Name,
                    GraphElementType: val.age.Type,
                    Num: 1,
                    GraphElementId: val.age.Id,
                    AttachObjectIds: [],
                    Pos: { X: t.data.Pos.X, Y: -t.data.Pos.Y },
                    Scale: { X: 1, Y: 1, Z: 1 },          // 缩放
                    Rolate: { X: 0, Y: 0, Z: 0 },
                    Size: { Width: 0, Height: 0 },         // 大小
                    Type: val.age.Type,
                    Properties: {
                        IconUrl: '/serve/topology-wanda/Picture/query/' + val.age.Url,
                        Url: '/serve/topology-wanda/Picture/query/' + val.age.Url,
                        Num: 1, // 此num与信息工程化得num无关
                        sWidth: 32,  //icon 的宽
                        sHeight: 32,   //icon 的高
                        font: 14,    //font
                        color: '',  //字体颜色
                        GraphCategoryId: val.age.GraphCategoryId,
                        InfoSystemId: val.age.InfoSystemId?val.age.InfoSystemId:'',   //信息工程话分类ID分类
                        FID: t.data.SourceId,
                        InfoTypeId:val.age.InfoTypeId.length? val.age.InfoTypeId :[],
                        InfoLocal:val.age.InfoLocal.length ?val.age.InfoLocal :[]
                    },
                  };
                  const item = new SImageLegendItem(null, data)
                  item.selectable = true;
                  item.moveable = true;
                  this.scene.addItem(item);
                  this.scene.Nodes.push(item);
                  return item
                }
              }
          }).filter(item => item);
          this.scene.AddListCommand(list);
          bus.$emit("elementDataChange", this.scene);
        } else if (val.type == "Zone") {
          const list = this.fParser.spaceList
            .map(t => {
              if (t.data.Type == val.key && val.age.Url) {
                if (!t.isExtracted) {
                  t.isExtracted = true;
                  return {
                    ID: uuid(),
                    Name: val.age.Name,
                    GraphElementType: val.age.Type,
                    GraphElementId: val.age.Id,
                    AttachObjectIds: [],
                    Pos: { x: t.x, y: t.y },
                    OutLine: t.pointArr[0],
                    SubType: "",
                    Properties: {
                      IconUrl: '/serve/topology-wanda/Picture/query/' + val.age.Url,
                      InfoSystemId: val.age.InfoSystemId?val.age.InfoSystemId:'',   //信息工程话分类ID分类
                      StrokeColor: val.age.Color,
                      FillColor: val.age.FillColor,
                      LineDash: val.age.LineDash,
                      font: 14,
                      color: "",
                      TextPos: { X: 0, Y: 0},
                      FID: t.data.SourceId,
                      InfoTypeId:val.age.InfoTypeId.length? val.age.InfoTypeId :[],
                      InfoLocal:val.age.InfoLocal.length ?val.age.InfoLocal :[]
                    },
                    Num: 1
                  };
                }
              }
            })
            .filter(item => item);
          const parserData = new STopologyParser(null);
          parserData.parseData({ Nodes: list });
          parserData.zoneLegendList.forEach(t => {
            t.$emit('finishCreated')
            this.scene.addItem(t);
            this.scene.Nodes.push(t);
          });
          // undo/redo事件
          this.scene.AddListCommand(parserData.zoneLegendList);
          bus.$emit("elementDataChange", this.scene);
        }
      });
      // 设备图例样式对象
      bus.$on("setLenged", obj => {
        this.scene.setlegend = obj;
      });
      //  修改图片url
      bus.$on("upadataImageUrl", val => {
        this.scene.upadataImageUrl(val);
      });
      // 改变边框样式
      bus.$on("changeBorder", val => {
        this.scene.upadataBorder(val);
      });
      // 改变图例名称
      bus.$on("changeLengedName", val => {
        this.scene.upadataLengedName(val);
      });
      // 改变图例名称
      bus.$on("changeImageNum", val => {
        this.scene.upadatImageNum(val);
      });
      // 修改填充色
      bus.$on("changefillColor", val => {
        this.scene.upadatfillColor(val);
      });
      // 修改当前得状态是否为编辑状态
      bus.$on("OpenEditStatus", () => {
        ` `; // 获取焦点item (必须选中且仅选中一个)
        if (
          this.chiceItemList &&
          this.chiceItemList.length &&
          this.chiceItemList.length == 1
        ) {
          if (this.scene.grabItem) {
            this.view.tryDbclick();
          } else {
            this.scene.grabItem = this.chiceItemList[0];
            this.view.tryDbclick();
          }
        }
      });
      //修改图例说明
      bus.$on("changeitemExplain", val => {
        this.scene.upadatitemExplain(val);
      });
      //发布图
      bus.$on("publishGraph", val => {
        publishGraph({ graphId: this.graphId, pubUser: "" }).then(res => {
          if (res.Result == "success") {
            this.$message.success(res.Message);
          } else {
            this.$message.error(res.Message);
          }
        });
      });
      //创建区域是否点选
      bus.$on("changeDrawType", val => {
        this.scene.isSelecting = val == "select";
      }),
        //发布图
        bus.$on("publishMap", () => {
          const loading = Message({
            message: "保存中，切勿关闭窗口！",
            type: "warning"
          });
          // 发布信息时必须保存数据
          this.saveMsg()
            .then(res => {
              loading.close();
              if (res) {
                this.publishBtn();
              }
            })
            .catch(() => {
              loading.close();
            });
        });
      /**
       * @name changeScale缩放底图
       * @param { Number } zoom 缩放比例
       *
       */
      // TODO: changeScale缩放底图
      bus.$on("changeScale", zoom => {
        if (zoom == 1) {
          this.view.fitSceneToView();
          return;
        }
        const { scale } = this.view;
        this.changeScaleByClick = true;
        this.view.scaleByPoint(
          zoom,
          this.canvasWidth / 2,
          this.canvasHeight / 2
        );
        this.changeScaleByClick = false;
      });
      // 更改图例数据工程化数据
      bus.$on("changeAttachObjectIds", arr => {
        this.scene.upadatAttachObjectIds(arr);
      });
      // redo
      bus.$on("changeRedo", () => {
        this.scene.redo();
      });

      // uodo/
      bus.$on("changeUndo", () => {
        this.scene.undo();
      });
         // 选中状态
      bus.$on("toggleItem", (item) => {
        this.scene.toggleItem(item);
      });
    },
    // 读取数据
    readGroup() {
      const data = {
        categoryId: this.urlMsg.categoryId,
        projectId: this.urlMsg.projectId,
        BuildingID: this.urlMsg.BuildingID, // 建筑ID
        FloorID: this.urlMsg.FloorID // 楼层id
      };
      return readGroup(data);
    },
    //发布
    publishBtn() {
      const loadings = Loading.service({
        lock: true,
        text: "Loading",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)"
      });
      const data = {
        BuildingID: this.urlMsg.BuildingID,
        CategoryID: this.urlMsg.categoryId,
        FloorID: this.urlMsg.FloorID,
        GraphId: this.graphId,
        ProjectID: this.urlMsg.projectId,
        PubUser: ""
      };
      publishGraph(data).then(res => {
        loadings.close();
        if (res.Result == "success") {
          Message({
            message: "发布成功！",
            type: "success"
          });
          setTimeout(() => {
            const token = this.$store.getters["token"];
            const data = `categoryId=${this.urlMsg.categoryId}&projectId=${this.urlMsg.projectId}&BuildingID=${this.urlMsg.BuildingID}&FloorID=${this.urlMsg.FloorID}&fmapID=${this.urlMsg.fmapID}&token=${token}`;
            const url =
              window.location.origin +
              "/wandaEditer/drafts?" +
              encodeURIComponent(data);
            window.open(url, true);
            // // 发布成功跳转草稿箱
            // const token = this.$store.getters["token"];
            // this.$router.push({ path: 'drafts', query: { projectId:this.urlMsg.projectId,BuildingID:this.urlMsg.BuildingID,fmapID:this.urlMsg.fmapID,token:token}})
          }, 2000);
        } else {
          Message({
            message: res.Message,
            type: "error"
          });
        }
      });
    },
    // 获取typeid
    getTypeId() {
      const data = {
        categoryId: this.urlMsg.categoryId
      };
      queryTypeGraph(data).then(res => {
        this.hasTypeList = res.Data.map(t => Number(t));
      });
    },
    saveMsg() {
      const Elements = this.scene.saveMsgItem();
      const Seq = Number(this.urlMsg.seq);
      const data = {
        Elements,
        Name: this.appName, // 名称
        CategoryId: this.urlMsg.categoryId,
        ProjectID: this.urlMsg.projectId, // 项目ID
        BuildingID: this.urlMsg.BuildingID, // 建筑ID
        FloorID: this.urlMsg.FloorID, // 楼层id
        Seq // 楼层id
      };
      return new Promise(resolve => {
        saveGroup(data)
          .then(res => {
            if (res.Result == "success") {
              this.graphId = res.Data;
              Message({
                message: "保存成功！",
                type: "success"
              });
              resolve(true);
            } else {
              Message({
                message: "保存失败！",
                type: "error"
              });
              resolve(false);
            }
          })
          .catch(err => {
            Message({
              message: "保存失败！",
              type: "error"
            });
            resolve(false);
          });
      });
    },
    // 自动保存接口
    saveMsgNoMessage() {
      const Elements = this.scene.saveMsgItem();
      const Seq = Number(this.urlMsg.seq);
      const data = {
        Elements,
        Name: this.appName, // 名称
        CategoryId: this.urlMsg.categoryId,
        ProjectID: this.urlMsg.projectId, // 项目ID
        BuildingID: this.urlMsg.BuildingID, // 建筑ID
        FloorID: this.urlMsg.FloorID, // 楼层id
        Seq // 楼层id
      };
      saveGroup(data)
        .then(res => {
          if (res.Result == "success") {
            this.graphId = res.Data;
            console.log("自动保存成功");
          } else {
            console.log("自动保存失败");
          }
        })
        .catch(err => {
          console.log("自动保存失败");
        });
    }
  },
  watch: {
    cmdType: {
      handler(cmd) {
        if (cmd == null || cmd == "") {
          cmd = "choice";
        }
        this.scene.setCmd = cmd;
      },
      deep: true
    },
    "scene.cmd": {
      handler(cmd) {
        this.$emit("setCmdType", cmd);
      },
      deep: true
    },
    // 监听scale的变化
    "view.scale": {
      handler(scale) {
        // 滚轮触发的缩放
        if (!this.changeScaleByClick) {
          bus.$emit("mouseScale", scale / this.initScale);
        }
      }
    }
  },
  created() {
    const href = window.location.href;
    // 路由
    // const route = href.split("?")[0];
    // 参数处理
    let params = href.split("?")[1];
    if (!params) {
      // 参数有问题
      return false;
    }
    params = decodeURIComponent(params);
    // params = "categoryId=NTXT&ProjectID=5&BuildingID=1&FloorID=1"; // mock 参数
    const paramsArr = params.split("&");
    console.log("paramsArr", paramsArr);
    const obj = {};
    paramsArr.map(item => {
      const arr = item.split("=");
      obj[arr[0]] = arr[1];
    });
    this.urlMsg = obj;
  },
  beforeDestroy() {
    // 销毁自动保存
    clearInterval(this.autoSave);
  }
};
</script>
<style lang="less" scoped>
#baseEditer {
  background: #f7f9fa;
  width: 100%;
  height: 100%;
  // overflow: hidden;
  // position: relative;
  #fengMap {
    position: absolute;
    width: 100px;
    height: 100px;
    z-index: -1;
  }
  .canvas-container {
    width: 100%;
    height: 100%;
  }
}
</style>