<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ include file="/jsp/common/include/localemessage.jsp" %>
<script language="javascript"
	src="<c:url value="/js/jexcel-custom.js"/>"></script>
<script language="javascript">
    /*
     * GRID
     */
    var grid;
    var toolbarHtml;
    var onLoadFirst = true;
    
    function hasRowData(data) {
        if (data == undefined || data == null) {
            return false;
        }
        
        if (data.length < 1) {
            return false;
        }  
        
        if (data.length > 1) {
            return true;
        }  
        
        if ($.trim(data[0]['loutItemName']) == '' || $.trim(data[0]['loutItemSerno']) == '') {
            return false;
        }
        
        return true;
    }
    
    function jexcelOnload (instance) {
        if (onLoadFirst) {
            onLoadFirst = false;
        }
    }
    
    function jexelContextMenu(obj, x, y, e, f) {
        var items = [];
        
        var cell = obj.getCell(jexcel.getColumnNameFromId([x, y]));
        if (cell.classList.contains('readonly')) {
            return items;
        }

        if (y == null) {
            // Insert a new column
            if (obj.options.allowInsertColumn == true) {
                items.push({
                    title : obj.options.text.insertANewColumnBefore,
                    onclick : function() {
                        obj.insertColumn(1, parseInt(x), 1);
                    }
                });
            }

            if (obj.options.allowInsertColumn == true) {
                items.push({
                    title : obj.options.text.insertANewColumnAfter,
                    onclick : function() {
                        obj.insertColumn(1, parseInt(x), 0);
                    }
                });
            }

            // Delete a column
            if (obj.options.allowDeleteColumn == true) {
                items.push({
                    title : obj.options.text.deleteSelectedColumns,
                    onclick : function() {
                        obj.deleteColumn(obj.getSelectedColumns().length ? undefined : parseInt(x));
                    }
                });
            }

            // Rename column
            if (obj.options.allowRenameColumn == true) {
                items.push({
                    title : obj.options.text.renameThisColumn,
                    onclick : function() {
                        obj.setHeader(x);
                    }
                });
            }

            // Sorting
            if (obj.options.columnSorting == true) {
                // Line
                items.push({
                    type : 'line'
                });

                items.push({
                    title : obj.options.text.orderAscending,
                    onclick : function() {
                        obj.orderBy(x, 0);
                    }
                });
                items.push({
                    title : obj.options.text.orderDescending,
                    onclick : function() {
                        obj.orderBy(x, 1);
                    }
                });
            }
        } else {
            // Insert new row
            if (obj.options.allowInsertRow == true) {
                items.push({
                    title : '<%=localeMessage.getString("layout.insertRow")%>',
                    onclick : function() {
                        const selectedCell = obj.selectedCell;
                        if (selectedCell == null) {
                            obj.insertRow(1, parseInt(y), 1);
                        } else {
                            const y1 = Number(selectedCell[1]);
                            const y2 = Number(selectedCell[3]);
                            const top = y1 < y2 ? y1 : y2;
                            const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1;
                            obj.insertRow(gap, top, 1);
                        }
                    }
                });

                items.push({
                    title : '<%=localeMessage.getString("layout.addRow")%>',
                    onclick : function() {
                        const selectedCell = obj.selectedCell;
                        if (selectedCell == null) {
                            obj.insertRow(1, parseInt(y), 1);
                        } else {
                            const y1 = Number(selectedCell[1]);
                            const y2 = Number(selectedCell[3]);
                            const bottom = y1 > y2 ? y1 : y2;
                            const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1;
                            obj.insertRow(gap, bottom);
                        }
                    }
                });
            }

            if (obj.options.allowDeleteRow == true) {
                items.push({
                    title : '<%=localeMessage.getString("layout.deleteRow")%>',
                    onclick : function() {
                        itemDel();
                    }
                });
            }
        }

        // Line
        items.push({
            type : 'line'
        });

        // Copy
        items.push({
            title : obj.options.text.copy,
            shortcut : 'Ctrl + C',
            onclick : function() {
                obj.copy();
            }
        });
        // Paste
        items.push({
            title : obj.options.text.paste,
            shortcut : 'Ctrl + V',
            onclick : function() {
                obj.paste();
            }
        });
        // Line
        items.push({
            type : 'line'
        });

        items.push({
            title : '<%=localeMessage.getString("layout.itemType")%>',
            submenu : [ {
                title : 'Field',
                onclick : function() {
                    updateSelectedColumn(obj.getEaColumnIndex('loutItemType'), 'Field');
                }
            }, {
                title : 'Group',
                onclick : function() {
                    updateSelectedColumn(obj.getEaColumnIndex('loutItemType'), 'Group');
                }
            }, {
                title : 'Grid',
                onclick : function() {
                    updateSelectedColumn(obj.getEaColumnIndex('loutItemType'), 'Grid');
                }
            }, ]
        });
        items.push({
            title : '<%=localeMessage.getString("layout.itemDepth")%>',
            submenu : [ {
                title : '<%=localeMessage.getString("layout.plusItemDepth")%>',
                shortcut : 'Alt + →',
                onclick : function() {
                    updateSelectedDepth(true);
                }
            }, {
                title : '<%=localeMessage.getString("layout.minusItemDepth")%>',
                shortcut : 'Alt + ←',
                onclick : function() {
                    updateSelectedDepth(false);
                }
            }, ]
        });
        items.push({
            title : '<%=localeMessage.getString("layout.moveRow")%>',
            submenu : [ {
                title : '<%=localeMessage.getString("layout.moveRowUp")%>',
                shortcut : 'Alt + ↑',
                onclick : function() {
                    moveSelectionRow(true);
                }
            }, {
                title : '<%=localeMessage.getString("layout.moveRowDown")%>',
                shortcut : 'Alt + ↓',
                onclick : function() {
                    moveSelectionRow(false);
                }
            }, ]
        });

        return items;
    }

    const jexcelOnBeforePaste = function(instance, data) {
        console.log('jexcelOnBeforePaste');

        const selectedCell = grid.selectedCell;
        const obj = grid;

        var ax = Number(selectedCell[0]), ay = Number(selectedCell[1]), bx = Number(selectedCell[2]), by = Number(selectedCell[3]);

        // Paste filter
        var x = ax, y = ay, w = bx - x + 1, h = by - y + 1;

        // change paste range if select is from right to left
        if (bx < ax) {
            x = bx;
            w = ax - x + 1;
        }
        // change paste range if select is from down to up
        if (by < ay) {
            y = by;
            h = ay - y + 1;
        }

        // Controls
        var hash = obj.hash(data);
        var style = (hash == obj.hashString) ? obj.style : null;

        // Depending on the behavior
        if (obj.options.copyCompatibility == true && hash == obj.hashString) {
            var data = obj.data;
        }

        // Split new line
        var data = obj.parseCSV(data, "\t");

        //modify data to allow wor extending paste range in multiples of input range
        if (w > 1 & Number.isInteger(w / data[0].length)) {
            style = null;
            repeats = w / data[0].length;

            var arrayB = data.map(function(row, i) {
                var arrayC = Array.apply(null, {
                    length : repeats * row.length
                }).map(function(e, i) {
                    return row[i % row.length]
                });
                return arrayC
            });
            data = arrayB;

        }
        if (h > 1 & Number.isInteger(h / data.length)) {
            style = null;
            var repeats = h / data.length;
            var arrayB = Array.apply(null, {
                length : repeats * data.length
            }).map(function(e, i) {
                return data[i % data.length]
            });
            data = arrayB;
        }

        if (x != null && y != null && data) {
            // Records
            var i = 0;
            var j = 0;
            var records = [];
            var newStyle = {};
            var oldStyle = {};
            var styleIndex = 0;

            // Index
            var colIndex = parseInt(x);
            var rowIndex = parseInt(y);
            var row = null;

            // Go through the columns to get the data
            while (row = data[j]) {
                i = 0;
                var colIndex = parseInt(x);
                while (row[i] != null) {
                    // Update and keep history
                    var record = obj.updateCell(colIndex, rowIndex, row[i]);
                    // Keep history
                    records.push(record);
                    // Style
                    if (style) {
                        var columnName = jexcel.getColumnNameFromId([ colIndex, rowIndex ]);
                        newStyle[columnName] = style[styleIndex];
                        oldStyle[columnName] = obj.getStyle(columnName);
                        obj.records[rowIndex][colIndex].setAttribute('style', style[styleIndex]);
                        styleIndex++
                    }
                    i++;
                    if (row[i] != null) {
                        if (colIndex >= obj.headers.length - 1) {
                            obj.insertColumn();
                        }
                        colIndex = obj.right.get(colIndex, rowIndex);
                    }
                }

                j++;
                if (data[j]) {
                    if (rowIndex >= obj.rows.length - 1) {
                        obj.insertRow();
                    }
                    var rowIndex = obj.down.get(x, rowIndex);
                }

            }

            // Select the new cells
            obj.updateSelectionFromCoords(x, y, colIndex, rowIndex);

            // Update history
            obj.setHistory({
                action : 'setValue',
                records : records,
                selection : obj.selectedCell,
                newStyle : newStyle,
                oldStyle : oldStyle,
            });

            // Update table
            obj.updateTable();
        }
        return false;
    };

    function moveSelectionRow(up) {
        const selectedCell = grid.selectedCell;

        const correction = up ? -1 : 1;
        const selectionCorrection = up ? 0 : 2;

        if (selectedCell != null) {
            const x1 = Number(selectedCell[0]);
            const y1 = Number(selectedCell[1]);
            const x2 = Number(selectedCell[2]);
            const y2 = Number(selectedCell[3]);
            if (up) {
                if (y1 === 0)
                    return;
                grid.moveRow(y1 + correction, y2);
            } else {
                const rowSize = grid.getData().length;
                if (y2 + 1 === rowSize)
                    return;
                grid.moveRow(y2 + correction, y1);
            }

            const CODE_A = 65;
            const x1Code = String.fromCharCode(CODE_A + x1);
            const x2Code = String.fromCharCode(CODE_A + x2);
            const startCellCode = x1Code + (y1 + selectionCorrection);
            const endCellCode = x2Code + (y2 + selectionCorrection);

            grid.updateSelection(grid.getCell(startCellCode), grid.getCell(endCellCode));
        }
    }

    function updateSelectedDepth(increse) {
        const selectedCell = grid.selectedCell;
        const depthColumn = grid.getEaColumnIndex('loutItemDepth');

        if (selectedCell != null) {
            const y1 = Number(selectedCell[1]);
            const y2 = Number(selectedCell[3]);
            const top = y1 < y2 ? y1 : y2;
            const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1;

            const values = [];
            for (let i = 0; i < gap; i++) {
                let value = Number(grid.getEaCellValue(top + i, 'loutItemDepth'));
                value = increse ? value + 1 : (value === 1 ? 1 : value - 1);
                values[i] = String(value);
            }
            updateValues(top, depthColumn, values);
        }
    }

    function updateSelectedColumn(colIndex, value) {
        const selectedCell = grid.selectedCell;
        if (selectedCell != null) {
            const y1 = Number(selectedCell[1]);
            const y2 = Number(selectedCell[3]);
            const top = y1 < y2 ? y1 : y2;
            const gap = (y1 < y2 ? y2 - y1 : y1 - y2) + 1;

            const values = [];
            for (let i = 0; i < gap; i++) {
                values[i] = value;
            }
            updateValues(top, colIndex, values);
        }
    }

    function updateValues(x, y, values) {
        console.log('update values : x=' + x + ", y=" + y + ", values=" + values);
        var records = [];
        for (let i = 0; i < values.length; i++) {
            const rowIndex = x + i;
            // Update and keep history
            var record = grid.updateCell(y, rowIndex, values[i]);
            // Keep history
            records.push(record);
        }

        // Update history
        grid.setHistory({
            action : 'setValue',
            records : records,
            selection : grid.selectedCell,
        });

        // Update table
        grid.updateTable();
    }

    function jexcelUpdateTable(instance, cell, col, row, val, label, cellName) {
        // console.log('jexcelUpdateTable : col :' + col + ", row : " + row);
        if (val != null && val != '' && grid.getEaColumnName(col) == 'loutItemName') {
            var rowData = grid.getRowData(Number(row));
            if (rowData.length > 1) {
                const itemLenIndex = grid.getEaColumnIndex('loutItemDepth');
                const depth = Number(rowData[itemLenIndex]);
                cell.style.textAlign = 'left';
                const padding = depth == 1 ? 5 : (depth * 10);
                cell.style.paddingLeft = padding + 'px';
            }
        }
    }
    
    /*
     * 값이 변경 될 경우 메타 검색
     */
    function jexcelOnBeforeChange(instance, cell, x, y, value) {
        if (metaCheckYn == "Y") {
	        console.log('jexcelOnBeforeChange : ' + value);
        	// return processMetaCheck(x, y, value);
        }
    }
    
    function jexcelOnEditionEnd(instance, cell, x, y, value) {
        console.log('jexcelOnEditionEnd : ' + value);
    }

    $(document).ready(function() {
        $('#grid').on("keydown", function(e) {
            console.log('keydown :' + e.keyCode)
            if (e.altKey) {
                if (e.keyCode == 39) {
                    updateSelectedDepth(true);
                    return false;
                }
                if (e.keyCode == 37) {
                    updateSelectedDepth(false);
                    return false;
                }
                if (e.keyCode == 38) {
                    moveSelectionRow(true);
                    return false;
                }
                if (e.keyCode == 40) {
                    moveSelectionRow(false);
                    return false;
                }
            }
            if (!e.shiftKey && e.keyCode == 9) {
                onTabKey(e);
            }
            
            if (e.keyCode == 13) {
                jexcelOnEnterKey(e);
            }
        });
    });
    
    function newAddRow(args) {
        // 추가 row count가 없으면 newAddRow 함수 종료.
        // 추가 row count가 없으면 newAddRow 함수 종료.
        if (this.returnValue != undefined)
            cnt = this.returnValue;
        else {
            cnt = args.returnValue;
        }
        if (cnt == "" || cnt == undefined)
            return;

        const ncnt = Number(cnt);
        grid.insertRow(ncnt);
    }

    /*
     * META
     */
    const reservedSuffix = [ '_DATAGRID', '_DATAGROUP', '_PAGENO', '_PAGEPERCNT', '_PAGENOCNT', '_DATACNT', '_ROWCNT', '_PAGEDVSN' ];
    const columnSourceYn = [ '', 'Y', 'N' ];

    function isMetaskip(loutItemId) {
        if (isExternalAndJsonOrXml()) {
        	return true;
        }
        
        if (isReserved(loutItemId)) {
        	return true;
        }
        
        return false;
    }
    
    function isReserved(loutItemId) {
        for (var i = 0; i < reservedSuffix.length; i++) {
            if (loutItemId.match(reservedSuffix[i] + "$")) {
                // 예약어로 종료 하면 메타 검색을 하지 않음
                return true;
            }
        }
        return false;
    }
    
    function isExternalAndJsonOrXml() {
        const useSystemCode = $('#useSystemCode').val();
        const loutPtrnName = $('#loutPtrnName').val();
        const ioCode_ECI = $('#ioCode_ECI').val();
        
        console.debug(useSystemCode + ", " + loutPtrnName);
        
        if (useSystemCode == "ECI" 
                && (loutPtrnName == "JSON" || loutPtrnName == "XML") && ioCode_ECI == "O") {
        	return true;
        }
        return false;
    }

    function getMetaDataByContextMenu(rowId, row) {
    	const metaUrlView = '<c:url value="/iim/layout/layoutMan.view" />';

        const loutItemName = row['LOUTITEMNAME'];

        // 예약어 확인
        const loutItemId = row["LOUTITEMID"];
        
        if (isMetaskip(loutItemId)) {
            console.debug('isMetaskip loutItemId : ' + loutItemId);
            row["CHECKMETADATA"] = "Y";
            grid.setEaRowData(rowId, row);
            return row;
        }

        var url2 = metaUrlView;
        url2 = url2 + "?cmd=Meta";
        var args = new Object();
        args['loutItemName'] = loutItemName;
        args['searchType'] = '3';
        args['rowId'] = rowId;
        var returnRow = showModal(url2, args, 610, 690, functionReturnValue);
        
        console.log('returnRow');
        console.log(returnRow);
        
        if (returnRow == undefined) {
        	console.log('returnRow == undefined')
            row["CHECKMETADATA"] = "N";
            grid.setEaRowData(rowId, row);
        } else if (returnRow === "skip") {
        	console.log('returnRow === "skip"')
            alert("<%=localeMessage.getString("layout.noHaveMeta")%>");
            row["CHECKMETADATA"] = "N";
            grid.setEaRowData(rowId, row);
        } else {
        	console.log(loutItemName);
            setMetaValues(rowId, returnRow);
            return returnRow;
        }
    }

    function isValidRowCnt(dataArray) {
        if (dataArray.length == 0) {
            alert("<%=localeMessage.getString("layout.noHaveData")%>");
            return false;
        }
        return true;
    }
    
    function isVField() {
    	return $('#loutPtrnName').val() == 'VFIELD';
    }

    // 값 정형화
    function setValidValue() {
        var rowData = grid.getJson();

        if (!isValidRowCnt(rowData)) {
            return;
        }

        for (var i = 0; i < rowData.length; i++) {
        	// ISO8583 sub fields parsing 지원하기 위해 아래 주석처리
            //if (rowData[i]["LOUTITEMNODEPTRNIDDESC"] == "Group" || rowData[i]["LOUTITEMNODEPTRNIDDESC"] == "Grid") {
            //    // Group,  Grid일경우 필요없는 칼럼초기화
            //    rowData[i]["LOUTITEMDATATYPE"] = null;
            //    rowData[i]["LOUTITEMDEFAULT"] = null;
            //    rowData[i]["LOUTITEMLENGTH"] = null;
            //    rowData[i]["LOUTITEMDECIMAL"] = null;
            //    rowData[i]["LOUTITEMSCREEN"] = null;
            //    rowData[i]["LOUTITEMMASK"] = null;
            //    rowData[i]["LOUTITEMPOINTYN"] = null;
            //    rowData[i]["LOUTITEMRECYN"] = null;
            //    rowData[i]["LOUTITEMRECVALUE"] = null;
            //    rowData[i]["CHECKMETADATA"] = "Y";
            //}

            // 항목명(한글/영문)에 _ROWCNT가 있으면 CHECKMETADATA 'Y'로 셋팅.
            // 데이터 길이 / 소수점 길이 항목에 입력값이 없으면 default 0으로 셋팅
            if (isMetaskip(rowData[i]["LOUTITEMID"])) {
                rowData[i]["LOUTITEMLENGTH"] = rowData[i]["LOUTITEMLENGTH"] == "" ? "0" : rowData[i]["LOUTITEMLENGTH"];
                rowData[i]["LOUTITEMDECIMAL"] = rowData[i]["LOUTITEMDECIMAL"] == "" ? "0" : rowData[i]["LOUTITEMDECIMAL"];
                rowData[i]["CHECKMETADATA"] = 'Y';
            }

            //깊이
            if (rowData[i]["LOUTITEMNODEPTRNIDDESC"] != null && rowData[i]["LOUTDPTCNT"] != "") {
                if (isNaN(rowData[i]["LOUTDPTCNT"])) {
                    rowData[i]["LOUTDPTCNT"] = null;
                }
            }

            //데이터길이
            if (rowData[i]["LOUTITEMLENGTH"] != "") {
                if (isNaN(rowData[i]["LOUTITEMLENGTH"])) {
                    rowData[i]["LOUTITEMLENGTH"] = null;
                }
            }
            //소수점길이
            if (rowData[i]["LOUTITEMDECIMAL"] != "") {
                if (isNaN(rowData[i]["LOUTITEMDECIMAL"])) {
                    rowData[i]["LOUTITEMDECIMAL"] = null;
                }
            }
            
            // 반복 횟수는 0이 될 수 없음
            if (rowData[i]["LOUTITEMOCCCNT"] == "0") {
                rowData[i]["LOUTITEMOCCCNT"] = null;
            }
        }

        grid.setData(rowData);
    }

    function isValidGrid() {

        var dataRow = grid.getJson();
        
        if (!hasRowData(dataRow)) {
            return true;
        }

        for (var i = 0; i < dataRow.length; i++) {
        	
        	const currentRow = dataRow[i];
        	// 항목명
            if (currentRow["LOUTITEMNAME"] == undefined || currentRow["LOUTITEMNAME"] == null || currentRow["LOUTITEMNAME"] == "") {
                alert("<%=localeMessage.getString("layoutExcel.exception01")%>".formatLocale(i + 1));
                return false;
            }
            // 영문명
            if (currentRow["LOUTITEMID"] == undefined || currentRow["LOUTITEMID"] == null || currentRow["LOUTITEMID"] == "") {
            	alert("<%=localeMessage.getString("layoutExcel.exception02")%>".formatLocale(i + 1));
                return false;
            }
            // 항목유형
            if (currentRow["LOUTITEMNODEPTRNIDDESC"] == undefined || currentRow["LOUTITEMNODEPTRNIDDESC"] == null || currentRow["LOUTITEMNODEPTRNIDDESC"] == "") {
            	alert("<%=localeMessage.getString("layoutExcel.exception03")%>".formatLocale(i + 1));
                return false;
            }
            
            if (currentRow["LOUTDPTCNT"] == undefined || currentRow["LOUTDPTCNT"] == null || currentRow["LOUTDPTCNT"] == "") {
            	alert("<%=localeMessage.getString("layoutExcel.exception05")%>".formatLocale(i + 1));
                return false;
            }

            console.log("metaCheckYn : " + metaCheckYn);
            if (metaCheckYn == "Y") {
                if (currentRow["CHECKMETADATA"] == undefined || currentRow["CHECKMETADATA"] == null || currentRow["CHECKMETADATA"] == "N"
                        || currentRow["CHECKMETADATA"] == "") {
                    alert("<%=localeMessage.getString("layout.alert01")%>".formatLocale(i + 1));
                    return false;
                }
            }
            
            if (currentRow["LOUTITEMNODEPTRNIDDESC"] == "Field" && isVField() && currentRow["LOUTITEMOCCREF"] != "") {
                // VField의 Field가 참조 정보 값을 가질 때 
                var isValidLOUTITEMOCCREF = false;
                for (var j = i -1; j > -1; j--) {
                    // 항목의 역순으로 조회
                    if (dataRow[j]["LOUTDPTCNT"] != currentRow["LOUTDPTCNT"]) {
                    	// 같은 단계가 아니면 종료
                        break;
                    }
                    
                    if (dataRow[j]["LOUTITEMID"] == currentRow["LOUTITEMOCCREF"]) {
                        // 같은 단계에 참조 정보 필드가 있음.
                        isValidLOUTITEMOCCREF = true;
                        break;
                    }
                }

                if (!isValidLOUTITEMOCCREF) {
                    alert("<%=localeMessage.getString("layout.alert02")%>".formatLocale(i + 1));
                    return false;
                }
            }
            
            if (currentRow["LOUTITEMNODEPTRNIDDESC"] == "Grid") {

            	// 하나캐피탈 POC준비로 validation 임시로 주석처리함
            	/*
                if (!isExternalAndJsonOrXml()) {
                	if (!currentRow["LOUTITEMID"].match("_DATAGRID$")) {
                        alert((i + 1) + "번째 row의 영문명은 _DATAGRID로 종료 되어야 합니다.");
                        return false;
                    }

                    var gridName = currentRow["LOUTITEMID"].substring(0, currentRow["LOUTITEMID"].indexOf("_DATAGRID"));

                    if (currentRow["LOUTITEMOCCREF"] != "" && currentRow["LOUTITEMOCCREF"] != gridName + "_ROWCNT") {
                        // 반복 횟수 참조에 입력된 데이터는 _ROWCNT 로 종료
                        alert((i + 1) + "번째 row의 반복횟수 참조정보의 값은" + gridName + "_ROWCNT 이여야 합니다.");
                        return false;
                    }
                }
            	*/

                if (currentRow["LOUTITEMOCCREF"] != "") {
                	var isValidLOUTITEMOCCREF = false;
                	for (var j = i -1; j > -1; j--) {
                		
                		if (dataRow[j]["LOUTDPTCNT"] != currentRow["LOUTDPTCNT"]) {
                			// 단계가 변경 되면 오류
                			// console.log('depth' : dataRow[j]["LOUTDPTCNT"] + " : " + currentRow["LOUTDPTCNT"]);
                			break;
                		}
                		
                		if (dataRow[j]["LOUTITEMID"] == currentRow["LOUTITEMOCCREF"]) {
                			// 같은 단계에 참조 정보 필드가 있음.
                			isValidLOUTITEMOCCREF = true;
                			break;
                		}
                	}

                	if (!isValidLOUTITEMOCCREF) {
                	    alert("<%=localeMessage.getString("layout.alert02")%>".formatLocale(i + 1));
                	    return false;
                	}
                }
            }

            // 반복 횟수 참조 값은 GRID에만 지정
            if (currentRow["LOUTITEMOCCREF"] != "" && currentRow["LOUTITEMNODEPTRNIDDESC"] != "Grid" && !isVField()) {
                    alert("<%=localeMessage.getString("layout.alert03")%>".formatLocale(i + 1));
                    return false;
            }

         	// 하나캐피탈 POC준비로 validation 임시로 주석처리함
         	/*
            if (currentRow["LOUTITEMNODEPTRNIDDESC"] == "Group") {
                if (!isExternalAndJsonOrXml()) {
                	if (!currentRow["LOUTITEMID"].match("_DATAGROUP$")) {
                        alert((i + 1) + "번째 row의 영문명은 _DATAGROUP으로 종료 되어야 합니다.");
                        return false;
                    }
                }
            }
         	*/
            
            // 반복 횟수는 0이 될 수 없음
            if (currentRow["LOUTITEMOCCCNT"] == "0") {
                alert("<%=localeMessage.getString("layout.alert04")%>".formatLocale(i + 1));
                return false;
            }
            
            if (currentRow["LOUTITEMNODEPTRNIDDESC"] == "Field" || currentRow["LOUTITEMNODEPTRNIDDESC"] == "Column") {
                // 데이터 타입 확인
                if (currentRow["LOUTITEMDATATYPE"] == undefined || currentRow["LOUTITEMDATATYPE"] == null 
                        || currentRow["LOUTITEMDATATYPE"] == "") {
//                        || (currentRow["LOUTITEMDATATYPE"] != "String" && currentRow["LOUTITEMDATATYPE"] != "BigDecimal"
//                            && currentRow["LOUTITEMDATATYPE"] != "Long"
//                            && currentRow["LOUTITEMDATATYPE"] != "Int")) {
                    alert("<%=localeMessage.getString("layout.alert05")%>".formatLocale(i + 1));
                    return false;
                }
            }
            
            if (i == 0 && currentRow['LOUTDPTCNT'] > 1) {
            	alert("<%=localeMessage.getString("layout.alert06")%>".formatLocale(i + 1));
            	return false;
            }
            
            if (i == 0) {
            	continue;
            }
            
            const previousRow = dataRow[i -1];
            if (previousRow['LOUTDPTCNT'] < currentRow['LOUTDPTCNT'] && previousRow['LOUTITEMNODEPTRNIDDESC'] == 'Field') {
            	alert("<%=localeMessage.getString("layout.alert07")%>".formatLocale(i + 1));
            	return false;
            } 
        }

        return true;

    }

    function loutItemOccRefChck(data, loutItemOccRef, prefix) {
        for (var i = 0; i < data.length; i++) {
            if (loutItemOccRef.indexOf("::") > -1) {
                return false;
            }
            if (data[i][prefix] == loutItemOccRef) {
                return false;
            }
        }
        return true;
    }

    function setIndex() {
        var data = grid.getJson();
        var index = 1;

        if (data.length == 0) {
            return;
        }
        console.log(data[0]['loutItemSerno']);

        if (data[0]['loutItemSerno'] == undefined) {
            // alert("인덱스를 생성할 필요가 없습니다.");
            return;
        }
        for (var i = 0; i < data.length; i++) {
            data[i]['loutItemSerno'] = index;
            index++;
        }
        grid.setData(data);
    }

    function setMetaValues(rowId, metaValues) {
        var rows = grid.getJson();
        var currentRow = rows[rowId];

        if (metaValues == undefined || $.trim(metaValues["LOUTITEMNAME"]) == '') {
            try {
                currentRow["checkMetadata"] = "N";
                grid.setEaRowData(rowId, currentRow);
            } catch (e) {
            }
            return;
        }
        
        var suffixNumberRegexp = /[0-9]+$/;
        
        const loutItemNameSuffixs = suffixNumberRegexp.exec(metaValues["LOUTITEMNAME"]);
        const loutItemIdSuffixs = suffixNumberRegexp.exec(metaValues["LOUTITEMID"]);
        
        if (loutItemNameSuffixs != null) {
        	// console.log(loutItemNameSuffix)
        	// console.log(metaValues["LOUTITEMID"].replace(/[0-9]+$/, loutItemNameSuffix));
        	
        	// metaValues["LOUTITEMID"] = metaValues["LOUTITEMID"].replace(/[0-9]+$/, loutItemNameSuffix);
        	
        	// 한글명이 숫자로 끝나면 
        	if (loutItemIdSuffixs == null) {
        		// 영문명이 숫자로 끝나지 않으면 한글명의 숫자를 영문명에 추가 
        		metaValues["LOUTITEMID"] = metaValues["LOUTITEMID"] + loutItemNameSuffixs[0];
        	}
        }
        

        var currentLoutItemDepth = currentRow["LOUTDPTCNT"];
        if (rowId > 0) {
            var previousRow = rows[rowId - 1];
            var previousLoutItemType = previousRow["LOUTITEMNODEPTRNIDDESC"];
            var previousLoutItemDepth = previousRow["LOUTDPTCNT"];
            if (previousLoutItemType == "Group" || previousLoutItemType == "Grid") {
                currentLoutItemDepth = parseInt(previousLoutItemDepth) + 1;
            } else {
                if (currentLoutItemDepth == "")
                    currentLoutItemDepth = previousLoutItemDepth;
            }
        } else {
            currentLoutItemDepth = 1;
        }
        currentLoutItemType = "Field";

        currentRow["LOUTITEMNAME"] = metaValues["LOUTITEMNAME"];
        currentRow["LOUTITEMID"] = metaValues["LOUTITEMID"];
        currentRow["LOUTITEMDATATYPE"] = metaValues["LOUTITEMDATATYPE"];
        currentRow["LOUTITEMLENGTH"] = metaValues["LOUTITEMLENGTH"];
        currentRow["LOUTITEMDECIMAL"] = metaValues["LOUTITEMDECIMAL"];
        currentRow["CHECKMETADATA"] = "Y";
        currentRow["LOUTITEMNODEPTRNIDDESC"] = "Field";
        currentRow["LOUTDPTCNT"] = currentLoutItemDepth;

        console.log('setMetaValues : ');
        console.log(currentRow);
        grid.setEaRowData(rowId, currentRow);
    }

    function getMetaData(rowId, columnName) {

        var metaUrl = '<c:url value="/iim/layout/layoutMan.json" />';
        var metaUrlView = '<c:url value="/iim/layout/layoutMan.view" />';

        var args = new Object();
        
        var sheetRow = grid.getJson()[rowId];

        var searchType = $("input[name=searchType]:checked").val();
        var loutItemName = sheetRow[columnName];

        var loutItemId = sheetRow["LOUTITEMID"];
        
        if (isMetaskip(loutItemId)) {
            sheetRow["CHECKMETADATA"] = "Y";
            grid.setEaRowData(rowId, sheetRow);
            return true;
        }
        
        var metaValues;
        var returnRows;
        
        $.ajax({
            type : "POST",
            url : metaUrl,
            dataType : "json",
            async : false,
            data : {
                cmd : 'DETAIL_META',
                loutItemName : loutItemName,
                searchType : searchType
            },
            success : function(json) {
                returnRows = json.rows;
            }
        });
        
        if (searchType == "1" && returnRows.length > 1) {
            alert("<%=localeMessage.getString("layout.alert08")%>");
        }
        
        if (returnRows.length == 1) {
            // 포함 값이 1개 이면 해당 포함 값을 사용
            console.log('포함 값이 1개');
            metaValues = returnRows[0];
            metaValues['LOUTITEMNAME'] =  loutItemName;
        } else if (returnRows.length > 1) {
            var url2 = metaUrlView;
            url2 = url2 + "?cmd=Meta";
            args['loutItemName'] = loutItemName;
            args['searchType'] = searchType;
            args['rowId'] = rowId;
            
            // 포함 값이 1개 이상이면 선택 창을 오픈
            console.log('포함 값이 1개 이상');
            metaValues = showModal(url2, args, 610, 690, functionReturnValue);
            console.log(metaValues);
        } else {
            // 포함 값이 없으면
            var r = confirm("<%=localeMessage.getString("layout.confirm01")%>".formatLocale(i + 1));
            if (r == false) {
                return false;
            }
            
            sheetRow["CHECKMETADATA"] = "N";
            grid.setEaRowData(rowId, sheetRow);
        }
        
        if (metaValues != undefined && $.trim(metaValues["LOUTITEMNAME"]) != '') {
            setMetaValues(rowId, metaValues);
            return metaValues["LOUTITEMNAME"];
        }
    }

    //항목추가 popup
    function itemAdd() {
        var args = new Object();
        var url2 = '<c:url value="/iim/layout/layoutMan.view" />';
        url2 = url2 + "?cmd=Item";
        if (isIE()) {
            showModal(url2, args, 250, 10, newAddRow);
        } else {
            showModal(url2, args, 300, 180, newAddRow);
        }
    }

    function itemDel() {   	
    
        const selectionRows = grid.getSelectedRows();
        console.log('selectionRows : ' + selectionRows);
        
        if (selectionRows == "" || selectionRows == undefined ) {
        	alert("please select a row.");
        } else {
            const idx = selectionRows[0].rowIndex - 1;
            const len = selectionRows.length;

            var deleteAll = (len == grid.getData().length);
            grid.deleteRow(idx, len);
            if (deleteAll) {
                grid.setData([ {} ]);
            }
        }
    }

    function onTabKey(event) {
        const selectedCell = grid.selectedCell;
        const x = Number(selectedCell[0]) + 1;
        const y = Number(selectedCell[1]) + 1;
        const rowSize = grid.getData().length;
        let colSize = 0;
        
        for (var i =0; i < grid.options.columns.length; i++) {
            if (grid.options.columns[i].type != 'hidden') {
                colSize++;
            }
        }

        if (x === colSize) {
            if (y === rowSize) {
                grid.insertRow();
            }
            const cellNum = 'A' + (y + 1);
            grid.updateSelection(grid.getCell(cellNum));
            event.preventDefault();
            event.stopPropagation();
        }
        console.log(x + ',' + y + ',' + rowSize + ',' + colSize);
    }
    
    //메타일괄적용
    function getAllMetaData() {
        var data = grid.getJson();

        if (!isValidRowCnt(data)) {
            return;
        }

        for (var i = 0; i < data.length; i++) {
            var itemType = data[i]['LOUTITEMNODEPTRNIDDESC'];
            var columnName = "LOUTITEMNAME";
            if (columnName == "") {
                continue;
            }
            var result = getMetaData(i, columnName);
            if (result == false) {
                alert("<%=localeMessage.getString("layout.alert09")%>");
                return;
            }
        }
        alert("<%=localeMessage.getString("layout.alert10")%>");
    }
    
    function functionReturnValue(args) {
        if (args != undefined) {
        	console.log('functionReturnValue');
        	console.log(args['returnValue']);
            setMetaValues(args['rowId'], args['returnValue']);
        } else {
            setMetaValues(this['dialogArguments']['rowId'], this['returnValue']);
        }
    }
    
    function MetaCheckCell(x, y, value) {
        this.x = x;
        this.y = y;
        this.value = value;
        this.equals = function (metaCheckCell) {
            return (this.x == metaCheckCell.x 
                    && this.y == metaCheckCell.y 
                    && this.value == metaCheckCell.value);
        }
    };
    
    var lastMetaCheckCell = new MetaCheckCell();
    
    function jexcelOnEnterKey(e) {
        // const selectedCell = grid.selectedCell;
        // const x = Number(selectedCell[0]);
        // const y = Number(selectedCell[1]);
        //
        // var cell = grid.getCell(jexcel.getColumnNameFromId([x, y]));
        // if (cell.classList.contains('editor')) {
        //     // editor 모드 일 경우에는 에디트 종료 이벤트에서 메타 검색
        //     return;
        // }
        //
        // if ('LOUTITEMNAME' != grid.getEaColumnName(x)) {
        //     // 한글명에서만 메타 검색 실행
        //     return;
        // }

        // const cellValue = grid.getEaCellValue(y, 'LOUTITEMNAME');
        // if (metaCheckYn == "Y") {
        // 	return processMetaCheck(x, y, cellValue);
        // }
    }
    
</script>