<script>
    import comPro from './formcompro';
    export default {
        name: 'baseform',
        mixins: [comPro],
        data () {
            return {
                form:{},
                oldForm:{},
                initForm:{},
                items:[],
                formRules: {
                },
                updateConfig:[],
                errorFlag: false,
                style:'',
                myConfig:{
                    lineNum:1,
                    itemSpan: 8,
                    labelWidth: 80,
                    labelPosition:'right',
                    showLabel:true,
                    inline:true,
                    isFull:true
                },
            };
        },
        methods:{
            initFormItemCol(index) {
                   // 处理占列
                let span = this.myConfig.itemSpan;
                let el = this.items[index];
                if (el.type === 'Divider') {
                    span = 24;
                } else {
                    if (el.colNum  !== undefined) {
                        if (Number(el.colNum) > Number(this.myConfig.lineNum)) {
                            span = this.myConfig.itemSpan * Number(this.myConfig.lineNum);
                        } else {
                            span = this.myConfig.itemSpan * Number(el.colNum);
                        }
                    } 
                }
                if (span > 24) {
                    span = 24;
                }
                return span;
            },
            initFormItem(el) {
                el.status = true;
                // 处理事件
                if (el.valueChanged) {
                    el.valueChanged = this.valueChanged;
                }

                if (el.searchBefore) {
                    el.searchBefore = this.searchBefore;
                }

                if (el.setDataBefore) {
                    el.setDataBefore = this.setDataBefore;
                }
                if (el.onAddTag) {
                    el.onAddTag = this.onAddTag;
                }
                if (el.onDelTag) {
                    el.onDelTag = this.onDelTag;
                }
                if (el.onSearch) {
                    el.onSearch = this.onSearch;
                }
                if (el.onLinkTo) {
                    el.onLinkTo = this.onLinkTo;
                }

                // 处理字典
                if (this.dictData) {
                    let dictkey = '';
                    if (el.dictkey) {
                        dictkey = el.dictkey;
                    }
                    if (el.customDictkey) {
                        dictkey = el.customDictkey;
                    }
                    if (dictkey) {
                        if (el.data === undefined) {
                            el.data = this.dictData[dictkey];
                        }
                    }
                } 
                // 处理共同属性
                this.setFormItemCommonPro(el);
                return el;
            },
            init() {
                let config = this.$Method.copy(this.config);
                this.myConfig = Object.assign({},this.myConfig,config);
                //处理表单一行排列几项，默认1项
                let itemSpan = 24/Number(this.myConfig.lineNum);
                this.myConfig.itemSpan= Number(itemSpan.toFixed(0));
                if (this.myConfig.itemSpan === 24) {
                    this.myConfig.inline = false;
                }
                this.initForm = {};
                if (this.myConfig.items) {
                    this.myConfig.items.forEach(el => {
                        let item = this.initFormItem(el);
                        this.items.push(item);
                    });
                }
               
                if (this.customInit){
                    this.customInit();
                }
                Object.assign(this.form , this.initForm);
                Object.assign(this.oldForm , this.form);  
            },
           
            setData(obj) {
                if (obj) { 
                    this.$refs.form.resetFields();
                    if (obj.flag === 'I') {
                        this.form = Object.assign({}, this.initForm, obj);
                    } else {
                        this.items.forEach(el => {
                            if (el.name) {
                                if (obj[el.name] === undefined) {
                                    obj[el.name] = '';
                                }
                            }
                            if (el.sname) {
                                if (obj[el.sname] === undefined) {
                                    obj[el.sname] = '';
                                }
                            }
                            if (el.ename) {
                                if (obj[el.ename] === undefined) {
                                    obj[el.ename] = '';
                                }
                            }
                            if (el.textName) {
                                if (obj[el.textName] === undefined) {
                                    obj[el.textName] = '';
                                }
                            }
                        });
                        this.form = Object.assign({}, {}, obj);
                    }
                    this.oldForm = this.$Method.copy(this.form);
                }
            },  
            isChange () {
                if (JSON.stringify(this.form) !== JSON.stringify(this.oldForm)) {
                    return true;
                } else {
                    if (this.form.flag && (this.form.flag === 'I' || this.form.flag === 'U')) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            input(obj) {
                let temp = {};
                if (obj.name) {
                    temp[obj.name] = obj.value;
                }

                if (obj.textName) {
                    temp[obj.textName] = obj.text;
                }
                if (obj.sname) {
                    temp[obj.sname] = obj.svalue;
                } 
                if (obj.ename) {
                    temp[obj.ename] = obj.evalue;
                }  
                this.form = Object.assign({}, this.form, temp);
                this.$emit('inputValue', obj);   
            },
            validatorIsNull(rule, value, callbacks) {
                if (this.isArrayFn(this.form[rule.field])) {
                    if (this.form[rule.field].length === 0) {
                        callbacks(new Error(''));
                    } else {
                        callbacks();
                    }
                } else {
                    if (!this.form[rule.field] && this.form[rule.field] !== 0) {
                        callbacks(new Error(''));
                    } else {
                        callbacks();
                    }
                }
            },
            isArrayFn (value) {
                if (typeof Array.isArray === 'function') {
                    return Array.isArray(value);
                } else {
                    return Object.prototype.toString.call(value) === '[object Array]';
                }
            },
            GetConfigIndex (name) {
                return this.config.items.findIndex(item => item.name === name || item.sname === name || item.ename === name);
            },
            valueChanged(obj) {
                obj.form = this.$Method.copy(this.form);
                obj.formObject = this;
                if (obj.sname) {
                    const items = this.config.items.find(el => {return el.sname === obj.sname;});
                    return items.valueChanged(obj);
                } else {
                    const items = this.config.items.find(el => {return el.name === obj.name;});
                    return items.valueChanged(obj);
                }
            },
            searchBefore(that) {
                that.form = this.$Method.copy(this.form);
                that.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.myConfig.name;});
                return items.searchBefore(that);
            },
            onAddTag(that) {
                that.form = this.$Method.copy(this.form);
                that.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.name;});
                return items.onAddTag(that);
            },
            onDelTag(that) {
                that.form = this.$Method.copy(this.form);
                that.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.name;});
                return items.onDelTag(that);
            },
            onSearch(that) {
                that.form = this.$Method.copy(this.form);
                that.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.name;});
                return items.onSearch(that);
            },
            onLinkTo(that) {
                that.form = this.$Method.copy(this.form);
                that.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.name;});
                return items.onLinkTo(that);
            },
            setDataBefore(obj,that) {
                let temp = {};
                temp.data = obj;
                temp.form = this.$Method.copy(this.form);
                temp.formObject = this;
                const items = this.config.items.find(el => {return el.name === that.myConfig.name;});
                return items.setDataBefore(temp,that);
            },
            checkValidate() {
                if(this.$refs.form[0]) {
                    this.$refs.form.forEach(el => {
                        if(el.validate) {
                            this.errorFlag = false;
                        } else {
                            this.errorFlag = true;
                        }
                    });
                } else {
                    this.$refs.form.validate(valid => {
                        if (valid) {
                            this.errorFlag = false;
                        } else {
                            this.errorFlag = true;
                        }
                    });
                }
                
                
            },
            isError() {
                return this.errorFlag;
            },
            getTrigger(type) {
                let trigger = 'blur';
                if (type) {
                    type = type.toLowerCase();
                }
                switch(type) {
                    case 'combobox':
                        trigger = 'change';
                        break;
                    case 'tagbox':
                        trigger = 'change';
                        break;
                    case 'daterangebox':
                        trigger = 'change';
                        break;
                }
                return trigger; 
            },
            getValue(name) {
                return this.form[name];
            },
            setValue(name,value) {
                let para ={};
                if (value === undefined) {
                    para[name] = '';
                } else {
                    para[name] = value;
                }
                this.form= Object.assign({}, this.form, para);
            },
            setValues(para) {
                for (let pro in para) {
                    if (para[pro] === undefined) {
                        para[pro] = '';
                    }
                }
                this.form= Object.assign({}, this.form, para);
            },
            setFormReadOnly(value) {
                if (!this.myConfig.items || this.myConfig.items.length === 0) {
                    return false;
                }
                this.myConfig.items.forEach(el => {
                    let name = '';
                    if (el.name) {
                        name = el.name;
                    } else if (el.sname) {
                        name = el.sname;
                    }
                    if (!value) {
                        if (this.myConfig.cellbeginedit) {
                            let obj = {};
                            obj.name = name;
                            obj.form = this.$Method.copy(this.form);
                            let flag = this.myConfig.cellbeginedit(obj);
                            if (flag) {
                                this.setReadOnly(name,value);
                            } else {
                                this.setReadOnly(name,!value);
                            }
                        } else {
                            this.setReadOnly(name,value);
                        }
                    } else {
                        this.setReadOnly(name,value);
                    }
                 
                });
            },
            setPro(name,value) {
                if (this.$refs[name] && this.$refs[name][0]) {
                    this.$refs[name][0].setPro(value);
                }
            },
            getPro(name,pro) {
                if (this.$refs[name] && this.$refs[name][0]) {
                    return this.$refs[name][0].getPro(pro);
                }
            },
            setReadOnly(name,value) {
                if (this.$refs[name] && this.$refs[name][0]) {
                    if (this.$refs[name][0].setReadOnly) {
                        this.$refs[name][0].setReadOnly(value);
                    }
                }
            },
            getData(){
                const form = this.$Method.copy(this.form);
                return this.doDetialItem(form);
            },
            doDetialItem(form) {
                if (this.myConfig.items && this.myConfig.items.length > 0) {
                    this.myConfig.items.forEach(el =>{
                        if (el.type === 'PopTagBox' ){
                            let updateData = [];
                            let oldData = this.oldForm[el.name];
                            let newData = this.$Method.copy(form[el.name]); 
                            if (oldData && oldData.length > 0) {
                                oldData.forEach(el2 =>{
                                    if (el2.ph_key) {
                                        if (newData && newData.length > 0) {
                                            let index = newData.findIndex(el3 => el3.ph_key === el2.ph_key);
                                            if (index > -1) {
                                                newData.splice(index, 1);
                                            } else {
                                                let temp = this.$Method.copy(el2);
                                                temp.flag = 'D';
                                                updateData.push(temp);
                                            }
                                        } else {
                                            let temp = this.$Method.copy(el2);
                                            temp.flag = 'D';
                                            updateData.push(temp);
                                        }
                                    }
                                });
                            }
                            if (newData && newData.length > 0)  {
                                newData.forEach(el => {
                                    el.flag = 'I';
                                    updateData.push(el);
                                });
                            }
                            form[el.name] = updateData;                         
                        }
                      
                    });
                }
                return form;
                 
            },
            setCommonRequired(name,value,config) {
                let ename = '';
                if (config.ename) {
                    ename = config.ename;
                }
                if (ename) {
                    if (this.formRules[ename] === undefined) {
                        if (value === true) {
                            this.formRules[ename] = [{
                                required: true,
                                validator: this.validatorIsNull,  
                                trigger: this.getTrigger(config.type)  
                            }];
                        } 
                    } else {
                        if (!value) {
                            delete this.formRules[ename];
                        }
                    }
                }
                
                if (this.formRules[name] === undefined)  {
                    if (value === true) {
                        this.formRules[name] = [{
                            required: true,
                            validator: this.validatorIsNull,  
                            trigger: this.getTrigger(config.type)  
                        }];
                        return true;
                    } 
                } else {
                    if (!value) {
                        delete this.formRules[name];
                        return true;
                    }
                }
                return false;
            },
            setRequired(name,value) {
                let flag = false;
                const index = this.items.findIndex(item => item.name === name || item.sname === name);
                if (index > -1) {
                    flag = this.setCommonRequired(name,value,this.items[index]);
                    if (flag) {
                        let tempConfig = Object.assign({},this.items[index],  {'required':value,status:false});
                        this.items.splice(index,1,tempConfig);
                        this.$nextTick(() => {
                            this.items[index].status = true;
                        });
                    }
                    
                }
            },
            updateCommonConfig(name, config) {
                let obj = {};
                let index = this.items.findIndex(item => item.name === name || item.sname === name);
                if (index > -1) {
                    let flag = false;
                    for (let pro in config) {
                        if (config[pro] !== this.items[index][pro]) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        config.status = false;
                        obj.index = index;
                        obj.name = name;
                        let item = this.$Method.copy(this.items[index]);
                        obj.config = Object.assign({}, item, config);
                        this.setCommonRequired(name,config.required,obj.config);
                    }
                }
                return obj;
            },
            updateItemConfig(name,config) {
                let obj = this.updateCommonConfig(name,config);
                if (obj && (obj.index > -1)) {
                    let temp = [];
                    temp.push(obj);
                    this.updateConfigReset(0,temp);
                }
            },
            updateConfigReset(index,obj) {
                let tempIndex = obj[index].index;
                this.items.splice(tempIndex,1,obj[index].config);
                if (index + 1 < obj.length) {
                    this.$nextTick(() => {
                        this.items[tempIndex].status = true;
                        this.$nextTick(() =>{
                            if (this.$refs[obj[index].name] && this.$refs[obj[index].name].length > 0) {
                                this.$refs[obj[index].name][0].reset();
                            }
                            this.updateConfigReset(index+1,obj);
                        });  
                    });
                } else {
                    this.$nextTick(() => {
                        this.items[tempIndex].status = true;
                        this.$nextTick(() =>{
                            if (this.$refs[obj[index].name] && this.$refs[obj[index].name].length > 0) {
                                this.$refs[obj[index].name][0].reset();
                            }
                        });  
                    });
                   
                }
            },
            updateItemsConfig(obj) {
                let updateConfig = [];
                if (obj) {
                    obj.forEach(el =>{
                        let temp = this.updateCommonConfig(el.name,el);
                        if (temp && (temp.index > -1)) {
                            updateConfig.push(temp);
                        }
                    });
                    
                    if (updateConfig.length > 0) {
                        this.updateConfigReset(0,updateConfig);
                    }
                   
                }
            },
            clearData() {
                //清空主表的数据与检验
                this.$refs.form.resetFields();
                this.form=Object.assign({}, {}, this.initForm);
                this.oldForm = this.$Method.copy(this.form);
            },
            getFormItemStyle(item) {
                let style = {};
                let isFull = this.myConfig.isFull;
                if (item.isFull !== undefined) {
                    isFull = item.isFull;
                }
                if (isFull) {
                    style.width = '100%';
                } else {
                    let minWidth =  this.myConfig.labelWidth + 100;
                    style['min-width'] = minWidth + 'px';
                }
                if (item.style !== undefined) {
                    style = Object.assign({}, style, item.style);
                }
                return style;
            },
            setFormItemCommonPro(el) {
                if (el.isFull === undefined) {
                    el.isFull = true;
                }
                if (el.name) {
                    this.setFormItemValue(el.name, el, true);
                }
                if (el.sname) {
                    this.setFormItemValue(el.sname, el, true);
                }
                if (el.ename) {
                    this.setFormItemValue(el.ename, el, true);
                }
                if (el.textName) {
                    this.setFormItemValue(el.textName, el, false);
                }
            },
            setFormItemValue(name, el, flag) {
                 // 值设定
                if (el.defaultValue !== undefined) {
                    this.initForm[name] = el.defaultValue;
                } else {
                    if (el.type === 'NumberBox' || el.type === 'NumberRangeBox') {
                        let min = '';
                        if (el.min !== undefined) {
                            min = el.min;
                        } 
                        if (el.smin !== undefined) {
                            min = el.smin;
                        }
                        if (el.smin === undefined && el.emin !== undefined) {
                            min = el.emin;
                        }
                        this.initForm[name] = min;
                        el.defaultValue = min;
                        if(el.boundaryValue === false) {
                            this.initForm[name] = '';
                            el.defaultValue = '';
                        }
                    } else {
                        if (el.type === 'PopTagBox') {
                            this.initForm[name] = [];
                        } else {
                            this.initForm[name] = '';
                        }
                    }
                }
                if (flag) {
                    // 处理必填check;
                    if (el.required) {
                        if (this.formRules[name] === undefined) {
                            this.formRules[name] = [{
                                required: true,
                                validator: this.validatorIsNull,  
                                trigger: this.getTrigger(el.type)  
                            }];
                        }
                    } else {
                        delete this.formRules[name];
                    }
                }
            },
            doAction(obj) {
                if (this[obj.name]) {
                    this[obj.name](obj);
                }
            },
            enterKeyDown(obj) {
                let nextName = this.findNextItems(obj.controlName);
                this.setFoucs(obj.controlName, false);
                this.$nextTick(() => {
                    let self = this;
                    setTimeout(() => {
                        self.setFoucs(nextName, true);
                    },200);
                });
            },
            setFoucs(name,value) {
                if (this.$refs[name] && this.$refs[name][0]) {
                    if (this.$refs[name][0].setFocus) {
                        this.$refs[name][0].setFocus(value);
                    }
                }
            },
            setHideDividerValue(value) {
                if (this.$refs.hidedivider && this.$refs.hidedivider[0]) {
                    this.$refs.hidedivider[0].setHide(value)
                }
            },
            findNextItems(curlName) {
                let fristName = '';
                let nextName = '';
                let flag = false;
                this.myConfig.items.some(el => {
                    let name = el.name;
                    if (el.sname) {
                        name = el.sname;
                    }
                    if (el.type !== 'wRichTextBox' && el.type !== 'RichTextBox' && el.type !== 'PictureBox' && el.type !== 'VideoBox' && this.$refs[name] &&  this.$refs[name][0] && this.$refs[name][0].getPro('visible') !== false) {
                        if (this.$refs[name][0].getPro('readOnly') !== true) {
                            if (!fristName) {
                                fristName = name;
                            }
                            if (flag) {
                                nextName = name;
                                return true;
                            }
                        }
                    }
                    if (curlName === name) {
                        flag = true;
                    }
                });
                if (!nextName) {
                    nextName = fristName;
                }
                return nextName;
            },
        }
    };
</script>