<template>
    <div class="h100b" :class="getLayoutClass" ref="layoutCtlDiv">
        <div class="goLayout" :style="goLayoutStyle" :id="layoutId" async="async">
            <slot></slot>
        </div>
    </div>
</template>

<script>
    import dhtmlXLayoutObject from '../../dx/dxSource/components/dhtmlXLayoutObject';
    import {GoingUtils, AssertUtils} from "goingutils";
    import {findComponentDownward} from "../../common/assist";

    export default {
        name: "go-layout",
        data: function () {
            return {
                changeSize: false,
                layoutId: GoingUtils.getUUid(12),
                recordRows: [],
                mainLayOut: null,
                baseMargin: 1,
            };
        },
        props: {
            //是否存在面包屑
            hasBread: {
                type: Boolean,
                default: false
            },
            //是否异步 其实就是稍微晚点渲染
            async: {
                type: Boolean,
                default: false
            },
            //离顶部的高度
            topHeight: {
                type: Number,
                default: 0
            },
            //容器的宽度
            width: {
                type: [Number, String],
                default: 0
            },
            //容器的高度
            height: {
                type: [Number, String],
                default: 0
            },
            //间距
            padding: {
                type: Boolean,
                default: true
            },
            //布局格式
            pattern: {
                type: String
            }
        },
        beforeMount() {
        },
        computed: {
            //初始化layout的样式
            goLayoutStyle() {
                let sty = {};
                if (AssertUtils.isNotNull(this.height) && this.height > 0) {
                    sty["height"] = this.height + "px";
                }
                if (AssertUtils.isNotNull(this.width) && this.width > 0) {
                    sty["width"] = this.width + "px";
                }
                return sty;
            },
            // 设置间隔 5像素
            getLayoutClass() {
                if (this.padding) {
                    return "margin-5";
                }
                return "";
            }
        },
        methods: {
            //隐藏更多查询
            hideMoreQueryForm() {
                $(".go-more-query")
                    .removeClass("fadeInRight")
                    .addClass("fadeOutRight");
                $(".more-query-cover").remove();
            },
            onPanelResizeFinish(cellNameAray) {
                //如果界面存在更多查询 则要隐藏了
                this.hideMoreQueryForm();
                //如果单元格 不为空
                if (
                    AssertUtils.isNotEmpty(cellNameAray) &&
                    AssertUtils.isArray(cellNameAray)
                ) {

                    //如果存在grid 则调用gird 的resize方法
                    this.$children&&this.$children.forEach((sonItem)=>{
                        let gridObjItem = findComponentDownward(sonItem, "go-single-grid");
                        gridObjItem&&gridObjItem.resize();
                    });
                    cellNameAray.forEach((item) => {
                        let cellObj = this.mainLayOut.cells(item);
                        if (cellObj != null) {
                            $(cellObj.cell).attr("layoutSizeChange", "true");

                            this.$store && this.$store.commit("setParentSizeChange", {
                                width: $(cellObj.cell).width(),
                                height: $(cellObj.cell).height()
                            });
                        }

                    });
                }
            },
            initCell(mainLayOut, cellConfig, cellObj) {
                let vueObj = this;
                let {
                    rightIcons = [],
                    fixSize = false,
                    headerText = "",
                    width,
                    height,
                    attachObject = "",
                    headerStyle,
                    bgColor,
                    moreQuery = true,
                    searchFieldAry = [],
                    searchFun = function () {
                    }
                } = cellConfig;
                let rightToolBarId = GoingUtils.getUUid(12);
                //判断是否需要设置标题
                if (AssertUtils.isNotEmpty(headerText)) {
                    cellObj.setText(
                        `<div class="pull-left">${headerText}</div><div class='pull-right right-tool-bar' style="margin-top:-3px;" id='${rightToolBarId}'></div>`
                    );
                } else {
                    cellObj.hideHeader();
                }
                //判断是否需要设置宽度。
                if (AssertUtils.isNotEmpty(width)) {
                    cellObj.setWidth(width);
                }
                //设置layout不能进行拖拽
                if (fixSize) {
                    cellObj.fixSize(true, true);
                }
                //判断是否需要设置高度。
                if (AssertUtils.isNotEmpty(height)) {
                    cellObj.setHeight(height);
                }

                //判断是否需要激活div对象。
                if (AssertUtils.isNotEmpty(attachObject)) {
                    cellObj.attachObject(attachObject);
                }

                if (AssertUtils.isNotEmpty(bgColor)) {
                    $(cellObj.cell).css("backgroundColor", bgColor);
                }

                if (AssertUtils.isNotEmpty(headerStyle)) {
                    $(cellObj.cell)
                        .closest(".dhx_cell_layout")
                        .find(".dhx_cell_hdr")
                        .get(0).style = headerStyle;
                }
                //判断是否存在右边的图标
                if (AssertUtils.isNotNull(rightIcons) && rightIcons.length > 0) {
                    $("#" + rightToolBarId)
                        .closest(".dhx_cell_hdr_text")
                        .next()
                        .hide();
                    //循环生成右侧图标
                    for (let num = 0; num < rightIcons.length; num++) {
                        let {id, icon, label} = rightIcons[num];
                        $(`<i id="${id}"  title="${label}" class="right_icon ${icon}"/>`).appendTo($("#" + rightToolBarId));
                    }
                }
                //注册图标点击事件事件
                $("#" + rightToolBarId).find(".right_icon").click(function () {
                    let id = $(this).attr("id");
                    vueObj.$emit('iconClick', {id});
                })
                //判断查询内容数组
                if (
                    AssertUtils.isNotNull(searchFieldAry) &&
                    AssertUtils.isObject(searchFieldAry)
                ) {
                    if (
                        searchFieldAry["fieldAry"] != null &&
                        AssertUtils.isArray(searchFieldAry["fieldAry"])
                    ) {
                        searchFieldAry = searchFieldAry["fieldAry"];
                    }
                }

                //是否需要查询区域。
                if (
                    AssertUtils.isArray(searchFieldAry) &&
                    searchFieldAry.length > 0 &&
                    AssertUtils.isNotEmpty(headerText)
                ) {
                    $("#" + rightToolBarId)
                        .closest(".dhx_cell_hdr_text")
                        .next()
                        .hide();
                    //添加单条件查询控件
                    cellObj.addSingleQueryCtl(
                        rightToolBarId,
                        searchFieldAry,
                        vueObj,
                        searchFun
                    );
                    if (moreQuery) {
                        //添加多条件查询控件
                        cellObj.addMoreQueryCtl(
                            rightToolBarId,
                            searchFieldAry,
                            vueObj,
                            searchFun
                        );
                    }
                }
            },
            getLayCells() {
                return this.$children.filter(
                    item => item.$options.name === "go-layout-panel"
                );
            },
            getResizeLayoutAry(cellName) {
                if (this.pattern === "3W") {
                    return {c: ['b', 'c']}[cellName];
                }
                if (this.pattern === "2U") {
                    return ['a', 'b'];
                }
            },
            //获取layout对象
            getObj() {
                return this.mainLayOut;
            },
            //初始化layout控件
            initLayoutCtl() {
                let mainLayOut = null;
                mainLayOut = new dhtmlXLayoutObject(this.layoutId, this.pattern);
                this.mainLayOut = mainLayOut;
                //如果panel的宽高进行了变更 会触发该事件
                mainLayOut.attachEvent("onPanelResizeFinish", (names) => {
                    this.onPanelResizeFinish(names);
                });
                //如果panel进行缩小
                mainLayOut.attachEvent("onCollapse", (names) => {
                    setTimeout(() => {
                        this.onPanelResizeFinish(this.getResizeLayoutAry(names));
                    }, GoingUtils.timeOutTime.layoutTime);
                });
                //如果panel进行 放大
                mainLayOut.attachEvent("onExpand", () => {
                    setTimeout(() => {
                        this.onPanelResizeFinish(['b', 'c']);
                    }, GoingUtils.timeOutTime.layoutTime);
                });
                let cellCounts = this.getLayCells();
                if (cellCounts.length > 0) {
                    cellCounts.forEach((item) => {
                        let cellConfig = {
                            ...item.$attrs,
                            searchFieldAry: item["searchFieldAry"],
                            searchFun: item["searchFun"],
                            attachObject: item.$el.getAttribute("id")
                        };
                        this.initCell(
                            mainLayOut,
                            cellConfig,
                            mainLayOut.cells(item.$attrs.cellId)
                        );
                    });
                } else {
                    //初始化所有cell对象
                    mainLayOut.forEachItem((item) => {
                        //如果配置信息不为空
                        if (AssertUtils.isNotNull(this[item.getId() + "Cell"])) {
                            this.initCell(mainLayOut, this[item.getId() + "Cell"], item);
                        }
                    });
                }
            },
            //通过父节点去初始化子节点
            initChildren() {
                this.$children.forEach(item => {
                    if (item.$options.name === "go-layout-panel") {
                        item.$children.forEach(function (sonItems) {
                            if (AssertUtils.isFunction(sonItems["initAsyncCtl"])) {
                                sonItems["initAsyncCtl"]();
                            }
                        });
                    }
                });
            },
            getOtherHeight() {
                return 0;
            },
            setPanelBodyHeight() {
                this.$children.forEach(item => {
                    if (item.$options.name === "go-layout-panel") {
                        $(item.$el).css(
                            "height",
                            parseFloat(
                                $(item.$el)
                                    .closest(".dhx_cell_cont_layout")
                                    .css("height")
                            ) - this.getOtherHeight()
                        );
                    }
                });
            },
            //初始化控件的高度
            initCtlHeight() {
                if (this.height === 0) {
                    let layoutHeight = 0;
                    //如果父容器存在宽高
                    if (this.$refs.layoutCtlDiv && this.$refs.layoutCtlDiv.parentNode != null && parseFloat($(this.$refs.layoutCtlDiv.parentNode).css("width")) > 0) {
                        $("#" + this.layoutId).css("width", parseFloat($(this.$refs.layoutCtlDiv.parentNode).css("width")) - this.baseMargin * 2);
                        layoutHeight = parseFloat($(this.$refs.layoutCtlDiv.parentNode).css("height"));
                    } else {
                        //设置layout的宽度
                        if ($(".content-frame").get(0) != null) {
                            $("#" + this.layoutId).css("width", parseFloat($(".content-frame").css("width")) - this.baseMargin * 2);
                        }
                        layoutHeight = parseFloat(GoingUtils.mainHeight);
                    }
                    //存在顶部高度 则减去多余的高度
                    this.topHeight > 0 ? layoutHeight = layoutHeight - this.topHeight - 4 : '';

                    //如果存在面包屑  则需要减去面包屑的高度
                    if (this.hasBread) {
                        layoutHeight = layoutHeight - 40;
                    }
                    //设置控件的高度
                    $("#" + this.layoutId).css("height", layoutHeight);
                } else {
                    //如果用户未传入高度
                    $("#" + this.layoutId).css("height", parseFloat(this.height));
                    //如果传入了宽度 则设置用户传入的
                    if (this.width != null) {
                        $("#" + this.layoutId).css("width", parseFloat(this.width));
                    }
                }
            },
            //初始化layout控件
            initLayoutCtlObj() {
                this.initCtlHeight();
                //判断是否需要异步加载
                if (this.async) {
                    this.$nextTick(function () {
                        //如果layout的父亲控件是tabset控件 则需要dom加载完了再进行渲染
                        this.initLayoutCtl();
                        this.setPanelBodyHeight();
                        this.initChildren();
                    });
                } else {
                    //如果layout的父亲控件是tabset控件 则需要dom加载完了再进行渲染
                    this.initLayoutCtl();
                    this.setPanelBodyHeight();
                    this.initChildren();
                }
            },
            //改变layout的宽高
            resizeLayout() {
                let vueObj = this;
                //如果对象已经销毁 则不需要继续执行
                if (vueObj.mainLayOut != null) {
                    //如果存在timeout则清空当前timeout
                    if (vueObj.layoutTimeout != null) {
                        clearTimeout(vueObj.layoutTimeout);
                    }
                    //刷新控件的宽高信息
                    vueObj.layoutTimeout = setTimeout(function () {
                        //修改layout的高度
                        vueObj.initCtlHeight();
                        //先实现layout的变化 再实现grid 的变化
                        if (vueObj.mainLayOut != null) {
                            vueObj.mainLayOut.setSizes();
                        }
                        //修改直接子节点 panel的高度信息
                        $("#" + vueObj.layoutId + " .go-layout-panel").each(function (index, item) {
                            $(item).css("height", parseFloat($(item).closest(".dhx_cell_cont_layout").css("height")) - vueObj.getOtherHeight());
                        });
                        //对设置过宽度的cell进行还原
                        vueObj.initCellWidth();
                        setTimeout(() => {
                            //对部分子容器进行还原
                            vueObj.resizeSonChildren();
                        }, 10);
                    }, GoingUtils.timeOutTime.layoutTime);
                }
            },
            //对部分常用对子容器进行还原
            resizeSonChildren() {
                let cellCounts = this.getLayCells();
                if (cellCounts.length > 0) {
                    cellCounts.forEach((item) => {
                        item.$children.forEach(sonItem => {
                            sonItem.resize && sonItem.resize();
                        });
                    });
                }
            },
            //初始化单元格的宽度
            initCellWidth() {
                let cellCounts = this.getLayCells();
                if (cellCounts.length > 0) {
                    AssertUtils.isArray(cellCounts) && cellCounts.forEach((item) => {
                        //只有设置了宽度的cell对象 才需要进行重新设置
                        let {width} = {
                            ...item.$attrs,
                            attachObject: item.$el.getAttribute("id")
                        };
                        if (AssertUtils.isNotNull(width) && AssertUtils.isNumber(width)) {
                            this.mainLayOut.cells(item.$attrs.cellId).setWidth(width);
                        }
                    });
                }
            }
        },
        mounted() {
            let vueObj = this;
            this.initLayoutCtlObj();
            //如果大小变化 触发tabset的resize方法
            $(window).resize(function () {
                vueObj.resizeLayout();
            });
        },
        watch: {},
        beforeDestroy() {
            try {
                if (this.mainLayOut != null) {
                    //销毁相应单元格
                    let cellCounts = this.getLayCells();
                    if (cellCounts.length > 0) {
                        cellCounts.forEach((item) => {
                            this.mainLayOut.cells(item.$attrs.cellId).detachObject();
                        });
                    }
                    //如果布局对象存在 则先要销毁对象
                    this.mainLayOut.unload();
                }
                this.mainLayOut = null;
            } catch (e) {
                console.log(e);
            }
        }
    };
</script>
