/**
 *  监听页面动作，维护数据映射及数据集
 *  使用该方式，始终保持 java 对象的完整性。
 *  最终只返回需要持久化的数据集合， 包含 Object， Array
 *  当前主要使用遍历实现。
 *  后期优化项目， window.dataSet.newData.backColors.compares 需要向外抛出、并且单独维护。
 *  @createDate 2019-04-12
 */


/**
 * 构建映射
 * @param dataMapping   映射配置
 * @param rawData   源数据：&nbsp;&nbsp;&nbsp;&nbsp;若有此输入，将认为当前是更新动作、&nbsp;&nbsp;无此输入则认为当前是插入动作
 */
function buildMapping(dataMapping, rawData) {
    window.dataSet = {};
    window.dataSet.tempId = 950366;
    window.dataSet.original = JSON.parse(JSON.stringify(rawData));
    if(Object.entries(rawData).length / Object.entries(window.dataMapping).length < 0.5) {
        window.dataSet.isInsert = true;
        var rawData = {};
    }else {
        window.dataSet.isInsert = false;
    }
    return mapping(rawData);
}

/**
 * 刷新映射, 数据非初始化时存在，需要调用此方法刷新映射
 * @param dataMapping   映射配置
 * @param beanName      需要刷新的 bean 名称
 * @param data          该 bean 对应的数据
 * @returns {{}}
 */
function refreshMapping(dataMapping, beanName, data) {
    let rawData = window.dataSet.original, newData = window.dataSet.newData;
    rawData[beanName] = data;
    let currentData = newData[beanName];
    data.forEach(item => {
        let currentMapping = window.dataMapping[beanName];
        if(!currentMapping) {
            console.error('找不到该映射,请检查映射配置是否存在该配置: ' + beanName);
            return;
        }
        let idProperty = currentMapping.id;
        let id = item[idProperty];
        if(!currentData.compares) { currentData.compares = {}; }
        currentData.compares[id] = item;
        if(!currentData.ids) { currentData.ids = [] }
        currentData.ids.push(id)
    })

    window.dataSet.original = JSON.parse(JSON.stringify(rawData));
    let returnData = mapping(rawData);
    window.dataSet.newData = JSON.parse(JSON.stringify(newData));
    return returnData;
}

/**
 * 遍历映射配置，构建映射关系
 * @param rawData
 * @returns {{}}
 */
function mapping(rawData) {
    let mapper = {}, returnData = {};
    delete dataMapping.mapper;
    Object.entries(dataMapping).forEach((entity) => {
        let beanName = entity[0], propertyNames = entity[1], entityData = rawData[beanName];
        if(!isExist(rawData, beanName)) { return; }
        if(!entityData) { entityData = {}; }
        if(propertyNames instanceof  Array) {
            // Form 时执行此逻辑
            tryForEach(propertyNames,(item) => {
                if(typeof item === "string") {
                    if(!isExist(entityData, item, beanName)) { return; }
                    associate(entityData, item, item, beanName,mapper, returnData);
                    return;
                }  else if(item instanceof Object) {
                    let entry = Object.entries(item)[0];
                    let property = entry[0], alias = entry[1];
                    if(!isExist(entityData, property, beanName)) { return; }
                    associate(entityData, property, alias, beanName,mapper, returnData)
                } else {
                    console.error('The configuration of "'+item+'" in "'+beanName+'" is not recognized,  and the required,' +
                        ' parameters are ( "propertyName" or "{ propertyName: alias }" ).');
                    throw {};
                }
            });
        } else if(propertyNames instanceof Object) {
            // Grid 时执行此逻辑
            if(window.dataSet.isInsert) {
                rawData[beanName] = {};
                rawData[beanName].raw = {};
                rawData[beanName].compares = {};
                rawData[beanName].ids = [];
                return;
            }
            let listMap = {}, ids = [], rowId = ''; //tryForEach 变量作用域注意
            if(!entityData instanceof Array) {
                console.error("映射配置的是 Grid， 传入数据类型是 Form。 请检查： " + beanName);
                return;
            }
            entityData.forEach(rowData => {
                rowId = rowData[propertyNames.id];
                rowData['rowIndex'] = rowId;
                listMap[rowId] = rowData;
                ids.push(rowId);
                settingGridMapper(propertyNames.columns, mapper, rowId, beanName);
            })
            rawData[beanName] = {};
            rawData[beanName].raw = entityData;
            rawData[beanName].compares = listMap;
            rawData[beanName].ids = ids;
            return;
        }
    });
    dataMapping.mapper = mapper;
    // ---------------- 暂不处理无法执行到此处的情况 ----------------
    // 这里写死 映射对象为：‘dataMapping’
    window.dataMapping = dataMapping;
    // 这里写死 数据集：‘dataSet: { rawData: {}, newData: {} }’
    window.dataSet.rawData = rawData;
    window.dataSet.newData = JSON.parse(JSON.stringify(dataSet.rawData));
    return returnData;
}

/**
 * 设置 Grid 映射关系，若是添加行，则需要构建属性
 * @param propertyNames
 * @param mapper
 * @param rowId
 * @param beanName
 * @param data  若是添加行，需要传入 data 构建属性
 */
function settingGridMapper(propertyNames, mapper, rowId, beanName, data) {
    propertyNames.forEach(property => {
        if(!mapper[property]) {
            mapper[property] = {};
        }
        if(!mapper[property][beanName]) {
            mapper[property][beanName] = {};
        }
        mapper[property][beanName][rowId] = {};
        if(data) {
            data[property] = '';
        }
    });
}

/**
 *  映射关系 => elementName(alias): { objName: property }
 * @param data  数据源
 * @param property  属性
 * @param alias 别名
 * @param objName   对象名
 * @param mapper    返回值: 映射关系
 * @param returnData    返回值: 页面显示数据集
 */
function associate(data, property, alias, objName, mapper, returnData) {
    mapper[alias] = {};
    mapper[alias][objName] = property;
    returnData[alias] = data[property];
}

function testTryForEach() {
    // 直接修改原型属性， 会导致当前UI grid 组件 input 不可用，未知原因。
    Array.prototype.tryForEach = function (callback) {
        try {
            this.forEach(callback);
        } catch { }
    }
}

/**
 * 若期望 forEach 可以直接跳出遍历 使用该方法。
 * @param arrayObj
 * @param callback
 */
const tryForEach = function(arrayObj, callback) {
    try {
        arrayObj.forEach(callback);
    } catch(error) {
        console.error(error);
    }
}

/**
 * 检测数据中是否存在对应属性
 * @param obj   需要检测数据
 * @param property  需要检测的属性
 * @param objName   检测的对象名
 * @returns {boolean}
 */
function isExist(obj, property, objName) {
    if(window.dataSet.isInsert) {
        obj[property] = {};
        return true;
    } else {
        if(!objName) { objName = 'rawData'; }
        // 这里注意，后端返回的类名是否与映射配置一致
        if(obj[property] === undefined) {
            console.error('No data for name of ' + property + ' in ' + objName + ' !');
            return false;
        }
    }
    return true;
}

/**
 * 检查是否存在此 Grid 的映射 返回匹配到的映射
 * @param str   Grid Id
 * @returns {{}}
 */
function checkArrayMapper(str) {
    let retrunData = {};
    Object.entries(window.dataMapping).forEach(entry => {
        let beanName = entry[0], property = entry[1];
        if(str.indexOf(beanName) >= 0) {
            retrunData['beanName'] = beanName;
            retrunData['property'] = property;
        }
    });
    return retrunData;
}

/**
 * &nbsp;&nbsp;&nbsp;&nbsp;
 * Grid 编辑前触发。 这里记录当前编辑框 对应的 Grid 行 rowIndex 和列 property                <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * 这里根据 UI ID生成规则封装。 需要根据此规则维护。                                         <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * 编辑前，根据 UI 生成的编辑框命名规则，定位到当前编辑栏目。修改数据时以此栏目位置为定位标准修改对应数据集。只记录当前栏目，使用完后需要清除。
 * @param options
 * @private
 */
function onBeforeEdit_(options) {
    const originalOnBeforeEdit = options.onBeforeEdit;
    options.onBeforeEdit = function(editParm, gg){
        let domIds = editParm.column.__domid.split('|'), colName = editParm.column.name;
        let mapper = window.dataMapping.mapper;
        let rowIndex = editParm.record.rowIndex;
        let mapperEntry =  mapper[colName];
        let currentMapping = checkArrayMapper(domIds[0]);

        if(currentMapping.hasOwnProperty("beanName")) {
            if(mapperEntry[currentMapping.beanName]) {
                mapperEntry[currentMapping.beanName]['rowIndex'] = rowIndex;
                mapperEntry[currentMapping.beanName]['colName'] = colName;
                mapperEntry[currentMapping.beanName][rowIndex] = editParm.rowindex; // input 框定位
            } else {
                console.error("dataMapping 中，无法找到该 DOMId 的映射。请检查！ :" + domIds[0]);
            }
        }
        originalOnBeforeEdit.call(this, editParm, '11');

        let recordId = editParm.record.__id;
        let targetDomId = domIds[0]+'|'+2+'|'+recordId +'|'+domIds[2];
        let cellDOM;
        if(!(cellDOM = document.getElementById(targetDomId))) {
            targetDomId = domIds[0]+'|'+1+'|'+recordId +'|'+domIds[2];
            cellDOM = document.getElementById(targetDomId)
        }
        let width = cellDOM.style.width;
        settingEditDomStyle(domIds[0], editParm.value, width);
    }
}

/**
 * 设置 Grid 编辑框栏目的样式
 * @param eleId
 * @param inputVal
 * @param width
 */
function settingEditDomStyle(eleId, inputVal, width) {
    let editor = window.dataGrid[eleId].editor;
    if(!editor.editing) {
        setTimeout(function() {
            settingEditDomStyle(eleId, inputVal, width);
        }, 150);
    } else {
        let currentDom = editor.container[0];
        if(currentDom) {
            currentDom.style.width = width;
        }
        if(currentDom.childNodes[1]) {
            // 下拉框时 添加点击事件。
            let editInputDom = currentDom.childNodes[1].childNodes[0];
            if(editInputDom) {
                editInputDom.value = inputVal;
                editInputDom.click();
            }
        }
    }
}

/**
 * 监听 下拉框初始化 ，使选中值时维护 dataSet。显示值需要自己处理。
 * @param elId  需要渲染的下拉框的 DOMId
 * @param options
 */
function listeningSearchbox(elId, options, gridId) {
    const originalOnChange = options.onChange;
    options.onChange = function(value, data, gridManager) {
        let eleName = this.element[0].name, beanName = '';
        let currentMapper =  window.dataMapping.mapper[eleName];
        if(!currentMapper) {
            console.error("找不到该映射,请检查映射配置是否存在该配置: "+ eleName);
        }
        Object.entries(currentMapper).forEach(mapper => {
            let property = "";
            if(eleName.split('_').length > 1) {
                property = eleName.split('_')[1];
            } else {
                beanName = mapper[0];
                property = mapper[1];
                if(typeof property== 'string') {
                    // ------------------ Form 下拉框执行此逻辑 ------------------
                    window.dataSet.newData[beanName][property] = data[property];
                    gridManager = window.dataGrid[gridId];
                } else if(property instanceof Object) {
                    // ------------------ Grid 下拉框执行此逻辑 ------------------
                    //debugger;
                    if(property.rowIndex) {
                        let rowIndex = property.rowIndex;
                        let propertyName = property.colName;
                        let gridEdit = window.dataGrid[gridId].editor;
                        if(!gridEdit.editParm.column) {
                            //debugger;
                        }
                        if(gridEdit.editParm.column.editor.type === 'select') {
                            let fillProperty = gridEdit.editParm.column.editor.fillProperty
                            window.dataSet.newData[beanName].compares[rowIndex][fillProperty] = data[fillProperty];//更新数据
                            window.dataGrid[gridId].editor.editParm.record[propertyName] = data[propertyName]; //更新显示
                            // ------------------ 结束编辑时销毁此下拉框 ------------------
                            if(!window.combox) { window.combox = {}; }
                            window.combox[gridEdit.input[0].id] = {};
                            window.combox[gridEdit.input[0].id].isCreate = true;
                            window.combox[gridEdit.input[0].id].object = this;
                        }
                        gridManager = window.dataGrid[gridId];
                        property.rowIndex = null;
                        property.colName = null;
                    }

                }

            }
        })
        originalOnChange.call(this, value, data, gridManager);
    }
    $(elId).searchbox(options);
}

/**
 * Gria 中的下拉框 用此方式初始化。           <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * 实际值需要在 Grid 初始化配置中 columns 栏目里配置  editor: { type: 'select', fillProperty: 'colorId'} 。<br> &nbsp;&nbsp;&nbsp;&nbsp;
 * fillProperty 即为该下拉框期望改变的属性。
 * @param propertyName  GridId_propertyName,需要以此定位到需要展开下拉框的栏目（临时）
 * @param options
 */
function listeningGridSearchbox(propertyName, options) {
    if(!window.gridSearchboxOptions) {
        window.gridSearchboxOptions = {};
    }
    window.gridSearchboxOptions[propertyName] = options;
}

function DropdownTrigger(node) {
    let nodeId = node.id;
    let tempId = nodeId.slice(0, nodeId.lastIndexOf('_'));
    if(node.getAttribute('select')) {
        if(!window.combox || !window.combox[nodeId]){
            listeningSearchbox('#'+nodeId, window.gridSearchboxOptions[tempId], nodeId.split('_')[0]);
        } else if(window.combox[nodeId]) {
            //  避免重复创建
            $('#'+nodeId).searchbox(window.gridSearchboxOptions[tempId]);
        }
    }
}

/**
 *  若需要监听 Grid 数据，必须在此调用组件初始化，此处获取元素 ID
 * @param elId
 * @param options
 * @returns {*}
 */
function listeningGrid(elId, options) {
    let currentMapper = checkArrayMapper(elId);

    if(!currentMapper.property) {
        console.error("若需要监听 GridData ,必须在映射配置指定 ID ！请检查。");
        return;
    }
    options.columns.unshift({ name: 'rowIndex', hide: true });
    let data = {};
    if(!options.data){
        console.error('listeningGrid 必须传入 Data ！请检查');
        data.Rows = '';
    } else { data.Rows = options.data.raw; }
    options.data = data;
    // ------------------ 编辑前 记录当前 cell ------------------
    onBeforeEdit_(options);

    const toolbar = options.toolbar;
    if(toolbar) {
        toolbar.items
        tryForEach(toolbar.items, but => {
            // ------------------ Grid 新增行时，设置 mapper、 newData -----------------
            if(but.id === "menuAdd") {
                // 使用 gridManager 对象 可以省略 页面监听操作。需要修改。
                const originalOnClick = but.click;
                but.click = function() {
                    let currentMapper = checkArrayMapper(elId);
                    let beanName = currentMapper.beanName;
                    let idProperty = currentMapper.property.id;
                    if(!idProperty) {
                        console.error("若需要监听 GridData ,必须在映射配置指定 ID ！请检查。");
                        throw {};
                    }
                    let mapper = window.dataMapping.mapper;
                    let rowId = window.dataSet.tempId += 1
                    let data = {}, mapperData = {};
                    // ------------- 设置 mapper -------------
                    settingGridMapper(currentMapper.property.columns, mapper, rowId, beanName, data);

                    // data[idProperty] = rowId;
                    data['rowIndex'] = rowId
                    // ------------- 设置 compares -------------
                    if(!window.dataSet.newData[beanName]) {
                        window.dataSet.newData[beanName] = {};
                    }
                    if(!window.dataSet.newData[beanName].compares){
                        window.dataSet.newData[beanName].compares = {};
                    }
                    window.dataSet.newData[beanName].compares[rowId] = data;
                    // ------------- 设置 ids -------------
                    if(!window.dataSet.newData[beanName].ids) {
                        window.dataSet.newData[beanName].ids = [];
                    }
                    window.dataSet.newData[beanName].ids.push(rowId);
                    UICtrl.addGridRow(gridManager, data);
                    originalOnClick.call(this, data, gridManager);
                }
            }
            if(but.id === "menuDelete") {
                const originalOnClick = but.click;
                but.click = function() {
                    let selectRows = gridManager.getSelectedRows();
                    selectRows.forEach(row => {
                        let currentMapper = checkArrayMapper(gridManager.id);
                        let beanName = currentMapper.beanName;
                        let currentData = window.dataSet.newData[beanName];
                        let rowIndex = row.rowIndex + '';
                        delete currentData.compares[rowIndex];
                        currentData.ids = currentData.ids.filter(x => !rowIndex.includes(x));
                        currentMapper.property.columns.forEach(property => {
                            delete window.dataMapping.mapper[property][beanName][rowIndex];
                        });
                        gridManager.deleteRow(row);
                    })
                    originalOnClick.call(this, selectRows, gridManager);
                }
            }
        })
    }
    addObserver(elId);
    var gridManager = UICtrl.grid(elId,  options);
    if(!window.dataGrid){
        window.dataGrid = {};
    }
    window.dataGrid[elId.slice(1)] = gridManager;
    return gridManager;
}

/**
 * 监听 input 管理页面显示的 Data。需要在控件初始化完成后调用
 */
function inputEventListener() {
    const inputElements = document.querySelectorAll('input');
    inputElements.forEach(item => {
        item.addEventListener('input', (event) => {
            listenerContent(event);
        });
    });
    const textareaElements = document.querySelectorAll('textarea');
    textareaElements.forEach(item => {
        item.addEventListener('input', (event) => {
            listenerContent(event);
        });
    });
}

/**
 * 监听器动作： 根据 保存的映射关系，将页面元素值填入到 newData
 * @param event
 */
function  listenerContent(event) {
    const property = event.target.getAttribute('name'), editId = event.target.id;
    const beanMapping = window.dataMapping.mapper[property];
    if(!beanMapping) {
        console.error("The configuration was not found in the 'dataMapping' : '"+property+"'")
    }
    let control;
    let inputIds = event.target.id.split('_');
    let currentMapper = checkArrayMapper(inputIds[0]);
    if (currentMapper.property) {
        control = 'grid';
    } else {
        control = 'form';
    }
    // Grid 时执行此逻辑
    if(control === 'grid') {
        //debugger;
        Object.entries(beanMapping).forEach(mapperEntry => {
            let mapperKey = mapperEntry[0], mapperVal = mapperEntry[1];
            Object.entries(mapperEntry[1]).forEach(rowEntry => {
                let rowId = rowEntry[0];
                if(rowEntry[1] !== undefined) {
                    if(rowEntry[1] === inputIds[2] * 1) {
                        window.dataSet.newData[mapperKey].compares[rowId][inputIds[1]] = event.target.value;
                        console.log('Input value changed:', event.target.value);
                    }
                }
            })
        })
        return;
    }
    // Form 时执行此逻辑
    if(control === 'form') {
        let mappings = Object.entries(beanMapping);
        tryForEach(mappings, (entry) => {
            let beanName = entry[0];
            let property = entry[1];
            if(event.target.type === 'checkbox') {
                window.dataSet.newData[beanName][property] = event.target.checked ? 1 : 0;
                console.log('checked value changed:', event.target.checked);
            } else {
                window.dataSet.newData[beanName][property] = event.target.value;
                console.log('Input value changed:', event.target.value);
            }
        })
    }
}

/**
 * 添加 DOM 监听
 * @param eleId 监听的 root 元素 ID
 */
function addObserver(eleId) {
    observer.observe(document.querySelector(eleId), mutationConfig);
}

/**
 * 监听 DOM ，为编辑框添加 Input 监听
 * @type {MutationObserver}
 */
const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        if(mutation.type === 'childList') {
            let addNodes = mutation.addedNodes;
            if(addNodes.length === 1 && addNodes[0].nodeName === 'DIV') {
                let childNodes = addNodes[0].childNodes;
                if(childNodes.length === 1 && childNodes[0].nodeName === 'INPUT') {
                    let node = childNodes[0];
                    node.addEventListener('input', gridEditor);
                    DropdownTrigger(node);
                }
            }
            let removeNodes = mutation.removedNodes;
            if(removeNodes.length === 1 && removeNodes[0].nodeName === 'INPUT') {
                let node = removeNodes[0];
                node.removeEventListener('input', gridEditor);
            }
        }
    })
})

const gridEditor = function(event) {
    listenerContent(event);
}
// console.log('属性变化节点 ： ' + mutation.target);
// console.log('变化属性名 ： ' + mutation.attributeName);
// console.log('变化属性值 ： ' + mutation.target.value);
const mutationConfig = { attributes: true, childList: true, subtree: true}

/**
 * 检查页面数据集，返回需要持久化的集合。包含：               <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * form 中做过修改的栏目，返回该栏目所映射的对象。           <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * grid 中做过修改的行，返回映射的对象集合。               <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * grid 中新增的行，返回映射的对象集合。                  <br> &nbsp;&nbsp;&nbsp;&nbsp;
 * grid 中删除的行，返回映射的对象集合。
 * @returns {*|{}}  { aEntity: {}, bArray: { add: [ bEntity: {} ] }, up: [ bEntity: {} ], del: [ bEntity: {} ] }
 */
function checkUpdata() {
    let dataSet = window.dataSet;
    let rawData = dataSet.rawData, newData = dataSet.newData;
    window.dataSet.upData = {};
    let rawEntry = Object.entries(rawData);
    tryForEach(rawEntry, entry => {
        let beanName = entry[0];
        // console.log(beanName);
        let mapping = window.dataMapping[beanName], raw = rawData[beanName], now = newData[beanName];
        if(mapping instanceof Array) {
            // Form 时 执行此逻辑
            if(!(getHashCode(JSON.stringify(raw)) === getHashCode(JSON.stringify(now)))) {
                dataSet.upData[beanName] = newData[beanName];
            }
            return;
        } else if (mapping instanceof Object) {
            // Grid 时 执行此逻辑
            let rawCompares = raw.compares, nowCompares = now.compares;
            if(!rawCompares) { rawCompares = {}; }
            if(!nowCompares) { nowCompares = {}; }
            if(!(getHashCode(JSON.stringify(rawCompares)) === getHashCode(JSON.stringify(nowCompares)))) {
                let rawIds = raw.ids, nowIds = now.ids;
                dataSet.upData[beanName] = {};
                dataSet.upData[beanName].del = [];
                let delIds = rawIds.filter(x => !nowIds.includes(x));
                delIds.forEach(rowIndex => {
                    dataSet.upData[beanName].del.push(rawCompares[rowIndex]);
                });
                dataSet.upData[beanName].add = []
                let addIds = nowIds.filter(x => !rawIds.includes(x));
                addIds.forEach(rowIndex => {
                    dataSet.upData[beanName].add.push(nowCompares[rowIndex]);
                });
                dataSet.upData[beanName].up = []
                Object.entries(nowCompares).forEach(row => {
                    let key = row[0], rowNow = row[1];
                    if(rawCompares[key]) {
                        if(!(getHashCode(JSON.stringify(rawCompares[key])) === getHashCode(JSON.stringify(rowNow)))) {
                            dataSet.upData[beanName].up.push(rowNow);
                        }
                    }
                });
            }
            return;
        }
    })
    return dataSet.upData;
}

/**
 * 用于判断字符串是否更改
 * @param str
 * @param caseSensitive 是否区分大小写 Default: true
 * @returns {number}
 */
function getHashCode (str, caseSensitive) {
    if(caseSensitive === undefined) { caseSensitive = true;}
    if(!caseSensitive) {
        str = str.toLowerCase();
    }
    if (str.length === 0) return 0;
    var len = str.length;
    var hash = 1315423911, i, ch;
    for (i = len - 1; i >= 0; i--) {
        ch = str.charCodeAt(i);
        hash = (hash << 5) + ch + (hash >> 2);
    }
    var hash2 = hash ^ (hash << 7) ^ (hash >> 6);
    var hash3 = hash2 ^ (hash2 << 1) ^ (hash2 >> 13);
    if (len < 50) {
        var hash4 = this.getHashCode(str + str + str, caseSensitive);
        return (hash ^ hash2 ^ hash3  ^ hash4) & 0x7FFFFFFF;
    } else {
        return (hash ^ hash2 ^ hash3 >> 3 ) & 0x7FFFFFFF;
    }
}


// function onAfterEdit_(options) {
//     options.onAfterEdit = function(editParm) {
//         let gridId = editParm.column.__domid.split('|')[0], colName = editParm.column.columnname, rowNum = editParm.rowindex;
//         let editId = gridId + '_' + colName + '_' + rowNum;
//         debugger;
//         this.options.onBeforeCancelEdit.call(this, editParm)
//         window.combox[editId].object.element = null;
//         window.combox[editId].object.options = null;
//     }
// }

//
// function onBeforeEdit_(options) {
//     const originalOnBeforeEdit = options.onBeforeEdit;
//     options.onBeforeEdit = function(editParm, gg){
//         let domIds = editParm.column.__domid.split('|'), recordId = editParm.record.__id, colName = editParm.column.name;
//         let parentDomId = domIds[0]+'|'+2+'|'+recordId; // +'|'+domIds[2];
//         let rowDOM;
//         if(!(rowDOM = document.getElementById(parentDomId))) {
//             parentDomId = domIds[0]+'|'+1+'|'+recordId;
//             rowDOM = document.getElementById(parentDomId)
//         }
//         let mapper = window.dataMapping.mapper;
//         // let rowIndex = rowDOM.childNodes[0].childNodes[0].innerText;
//         let rowIndex = editParm.record.rowIndex;
//         let mapperEntry =  mapper[colName];
//         let currentMapper = checkArrayMapper(domIds[0]);
//         debugger;
//         if(currentMapper.hasOwnProperty("beanName")) {
//             if(mapperEntry[currentMapper.beanName]) {
//                 mapperEntry[currentMapper.beanName]['rowIndex'] = rowIndex;
//                 mapperEntry[currentMapper.beanName]['colName'] = colName;
//                 mapperEntry[currentMapper.beanName][rowIndex] = editParm.rowindex; // input 框定位
//             } else {
//                 // mapperEntry[currentMapper.beanName][rowIndex] = colName;
//                 // console.error("dataMapping 中，无法找到该 DOMId 的映射。请检查！");
//             }
//         }
//         originalOnBeforeEdit.call(this, editParm, '11');
//     }
// }


// function getControlType(beanMapping) {
//     let control;
//     //  这里根据 grid 与 form 的 mapper 数据结构差异判定。 需要优化
//     debugger;
//     if(Object.entries(beanMapping)[0][1]['listeningKey']) {
//         control = 'grid';
//     } else {
//         control = 'form';
//     }
//     return control;
// }