<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ page session="false" %>
<!doctype html>
<html lang="ko" style="min-width:300px !important;overflow:hidden">
<head>
    <%@ include file="/WEB-INF/jsp/common.jsp" %>
    <meta name="_csrf" content="${_csrf.token}">
    <meta name="_csrf_header" content="${_csrf.headerName}">
    <link rel="stylesheet" type="text/css" href="/css/common.css">
    <link rel="stylesheet" type="text/css" href="/css/main.css">
    <link rel="stylesheet" href="/css/themes/default/style.css">
    <title>교차로 목록</title>
</head>
<body class="sang" style="min-width:305px !important;overflow:hidden">
<div class="leftMenu">
    <ul class="tabs">
        <li class="on" onclick="goIntMenu()"><div id="tab1"><img src="/images/int_icon.png" width="17px" alt="교차로 아이콘">교차로</div></li>
        <li onclick="goEvpMenu()"><div id="tab2"><img src="/images/evp_icon.png" width="17px" alt="긴급차량우선신호 아이콘">긴급차량우선신호</div></li>
<%--        <li><a href="javascript:goIntMenu()" class="tab" id="tab1"><img src="images/tab01_on.png" alt="교차로메뉴"/></a></li>--%>
<%--        <li><a href="javascript:goEvpMenu()" class="tab" id="tab2"><img src="images/tab02_off.png" alt="긴급차량우선신호메뉴"/></a></li>--%>
<%--        <div style="position: absolute; left: 95px; top: 5px;"><img src="images/map/btn_alert_A.gif" style="width: 22px"></div>--%>
    </ul>
    <div id="onOffTree"></div>
    <div class="searchBox">
        <input type="text" id="searchText" placeholder="검색어를 입력해주세요" autocomplete="false" onkeyup="searchTreeData(event)"><label for="searchText" style="display: none;"></label>
        <div class="search-button" onclick="searchTreeData()">검색</div>
    </div>
    <div class="evp-cur">
        <div class="title">긴급차량우선신호 서비스 현황</div>
        <div id="evp-cur-list">
            <table>
                <thead>
                    <tr>
                        <th width="23%">발생시각</th>
                        <th width="40%">서비스 ID</th>
                        <th width="37%">서비스명</th>
                    </tr>
                </thead>
                <tbody class="evp-table">
                    <tr>
                        <td colspan="3" class="empty-evp">조회된 내용이 없습니다.</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
    <div class="historyBox">
        <div class="title">긴급차량우선신호 서비스 이력</div>
        <div>
            <div>
                <div>지역센터</div>
                <label style="display: none;" for="region"></label>
                <select id="region">
                    <option value="ALL" selected>전체</option>
                    <c:if test="${fn:length(center) != 0}">
                        <c:forEach var="item" items="${center}">
                            <option value="${item.centerId}">${item.centerNm}</option>
                        </c:forEach>
                    </c:if>
                </select>
            </div>
            <div>
                <div>검색시작</div>
                <input type="date" id="start" autocomplete="false"><input type="time" id="start_time">
                <label style="display: none;" for="start"></label>
                <label style="display: none;" for="start_time"></label>
            </div>
            <div>
                <div>검색종료</div>
                <input type="date" id="end" autocomplete="false" ><input type="time" id="end_time">
                <label style="display: none;" for="end"></label>
                <label style="display: none;" for="end_time"></label>
            </div>
        </div>
        <div class="history-btn" onclick="searchHistoryData()">검색</div>
    </div>
    <div id="intTree"></div>
    <div id="historyList">
        <table>
            <thead>
                <tr>
                    <th width="23%">발생시각</th>
                    <th width="40%">서비스 ID</th>
                    <th width="37%">서비스명</th>
                </tr>
            </thead>
            <tbody class="history-table"></tbody>
        </table>
        <div class="empty-history">조회된 내용이 없습니다.</div>
        <div class="history-loading"><img src="/css/themes/classic/throbber.gif" alt="로딩 이미지"></div>
    </div>
    <div class="play-box">
        <div>
            <div>시뮬레이션 재생/멈춤</div>
            <img id="play" onclick="playSimulation()" src="/images/play.png" alt="시뮬레이션 재생버튼" width="24px">
            <img id="pause" onclick="pauseSimulation()" src="/images/pause.png" alt="시뮬레이션 멈춤버튼" width="24px">
            <img id="stop" onclick="stopSimulation()" src="/images/stop.png" alt="시뮬레이션 초기화버튼" width="24px">
        </div>
    </div>
    <div class="treeLoading"><img src="/css/themes/classic/throbber.gif" alt="로딩 이미지"></div>
</div>
<script src="/js/common/moment.js"></script>
<script src="/js/common/common-all.js"></script>
<script src="/js/signalInfo.js"></script>
<script src="/js/common/jstree.min.js"></script>

<script>

    var treeJson = null;
    var groupTreeJson = null;
    var treeCtrl;
    var onlineCenterStatusCheckId;
    var offlineCenterStatusCheckId;
    var onlineIntStatusCheckId;
    var offlineIntStatusCheckId;
    var _RegionCdArr = [];
    var _GroupNoArr = [];
    var intGroupLineArr = [];
    var intGroupCircleArr = [];
    var _groupTreeListCallBackData;

    var onlineCenterStatusData;
    var offlineCenterStatusData;
    var onlineIntStatusData;
    var offlineIntStatusData;
    let _regionMap = new Map();
    var _searchText = "";
    let timeout = null;
    const $start     = $('#start');
    const $startTime = $('#start_time');
    const $end       = $('#end');
    const $endTime   = $('#end_time');
    var _historyMap = new Map();

    var interval = null;
    var cnt = 0;

    $start.val(getDateToStr(new Date()));
    $end.val(getDateToStr(new Date()));

    $startTime.val('00:00');
    $endTime.val('23:59');

    function getDateToStr(date){
        const year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();
        if (month < 10){
            month = '0' + month;
        }
        if (day < 10) {
            day = '0' + day;
        }
        return year.toString() + '-' + month.toString() + '-' + day.toString();
    }
    function getDateTimeToStr(date) {
        let str = getDateToStr(date);
        let hour = date.getHours();
        let minute = date.getMinutes();
        let seconds = date.getSeconds();
        if (hour < 10){
            hour = '0' + hour;
        }
        if (minute < 10){
            minute = '0' + minute;
        }
        if (seconds < 10){
            seconds = '0' + seconds;
        }
        str += ' ';
        str += hour + ':' + minute + ':' + seconds;
        return str;
    }

    function setAddrMap(data) {

        _regionMap.clear();
        for (let ii = 0; ii < data.length; ii++) {
            if (data[ii].addr1 == null || data[ii].addr1 == '-') {
                continue;
            }
            _regionMap.set(data[ii].addr1, data[ii].regionid);
        }
    }

    function getAddrSi() {
        return Array.from(_regionMap.keys());
    }
    function getEngAddr(addr){
        let region_id = _regionMap.get(addr);
        if (region_id === null || region_id === undefined) {
            return "U99"
        }
        return region_id;
    }

    setTreeList();
    getIntTreeList();
    controllerOnOffFuc();

    function searchTreeData(el) {
        if (el && el.code !== "Enter") {
            return;
        }

        const $searchText = $('#searchText');
        _searchText = $searchText.val();
        const oldTree = $('#intTree').jstree(true);
        if (oldTree) {
            oldTree.destroy();
        }
        setTreeList();
        getIntTreeList();
        $('#intTree').jstree("refresh");
    }
    /*
    * 신호 제어기 상태 정보
    * 1 : 정상, 2: 교차로 시각 오류 0: 마지막통신 시간 3초이상 지연시
     */

    function controllerOnOffFuc() {
        if (timeout) clearTimeout(timeout);
        const start = new Date();
        var addrArr = getAddrSi();
        for(var ll = 0; ll < addrArr.length; ll++) {

            var ctnlCount =0;
            var errorCount=0;
            var now = new Date();
            var preDate = moment(now.getTime()).add("-30", "s").format("YYYY-MM-DD HH:mm:ss");
            var nxtDate = moment(now.getTime()).add("30", "s").format("YYYY-MM-DD HH:mm:ss");

           // console.log( window.parent._signalInfoArr);
            window.parent._signalInfoArr.forEach(function (el, idx) {
                if (el.addr1 == addrArr[ll]) {
                    ctnlCount++;
                    if (!el.commStatus) {
                        el.status = 0;  // 데이터 없음(현재 통신하고 있지 않음)
                        errorCount++;
                    }
                    else {
                        el.status = 1;
                        // if (now.getTime() - el.commDate.getTime() > 3000 ) {
                        //     console.log(el);
                        // }
                        // if ((now.getSeconds() - el.commDate.getSeconds()) <= 3) {
                        // let cmmnDate = null;
                        // if (el.date) {
                        //     cmmnDate = new Date(el.date);
                        // }
                        // if (cmmnDate && (el.commDate.getTime() - cmmnDate.getTime()) <= 3000) {
                        //     // 마지막 통신시각이 현재시각보다 3초 이내이면 통신 정상
                        //     el.status = 1;
                        //     // 로컬시각이 현재시각과 차이날 경우 아이콘의 색을 노랑색으로 변경하도록 한다.
                        //     var localDate = moment(el.date).format('YYYY-MM-DD HH:mm:ss');
                        //     if (localDate < preDate || localDate > nxtDate) { //시간이 null거나 3초전이거나
                        //         el.status = 2; // 교차로 시각 오류 (노랑색 아이콘으로 표출)
                        //     }
                        // }
                        // else {
                        //     // 마지막 통신시각이 현재시각보다 3초 이후이면 통신 Off Line 으로 판단
                        //     el.status = 0;
                        //     errorCount++;
                        // } //
                    }

                    // var commOnOffImg = 'background-image:url("images/intStatus_' + el.status + '.png");background-position:center center';
                    /*if (el.status == 1) {
                        commOnOffImg = 'background-image:url("images/intStatusOn.png");background-position:center center';
                    } else if(el.status == 2) {
                        //errorCount++;
                        commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
                    }else{
                        //errorCount++;
                        commOnOffImg = 'background-image:url("images/intStatusNull.png");background-position:center center';
                    }*/
                    //$('#' + el.nodeId + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
                    $('#' + el.nodeId + ' .jstree-anchor .jstree-icon').css({backgroundImage: 'url("images/intStatus_' + el.status + '.png")',
                        backgroundPosition: 'center center'});
                }
            });
            $('#intErrCnt_'+getEngAddr(addrArr[ll])).text(errorCount);
            $('#intTotal_'+getEngAddr(addrArr[ll])).text(ctnlCount);
        }
        const end = new Date();
        let diff = end.getTime() - start.getTime();
        if (diff >= 1000) {
            diff = 1000;
        }

        timeout = setTimeout(()=>controllerOnOffFuc(), 1000 - diff);
    }

    function setTreeList() {
        /**
         ** ****************************************************
         ** 레이어 리스트 Tree 생성
         ** ****************************************************
         */
        treeCtrl = treeCtrl || (function () {

            var Node = function (nodeName, data, id, icon) {
                return {
                    id: id,
                    icon: icon,
                    text: nodeName,
                    state: {'opened': false, 'selected': false},
                    data: data,         // @type: ol.Layer
                    children: []
                };
            };

            var _root = new Node('ROOT', 'item');

            var findChild = function (parent, nodeName) {
                for (var i = 0; i < parent.children.length; i++) {
                    var child = parent.children[i];
                    if (child.text == nodeName) {
                        return child;
                    }
                }

                return null;
            };

            // find parent which save item
            var getParent = function (parent, group, data, id, icon, opt_make) {
                opt_make = (typeof opt_make === 'undefined') ? true : false;

                for (var i = 0; i < group.length; i++) {
                    var child = findChild(parent, group[i]);
                    // 없으면 Node 생성
                    if (!child) {
                        if (!opt_make) return null;
                        child = new Node(group[i], data);
                        parent.children.push(child);
                    }
                    parent = child;
                }

                return parent;
            }

            // group에 layer 아이템 저장
            var _set = function (key, item) {
                key.forEach(function (el) {
                    var group = el.split('-');
                    var parent = getParent(_root, group, item.data, item.id, item.icon);
                    var child = new Node(item.name, item.data, item.id, item.icon);
                    parent.children.push(child);
                    return child;
                });
            };

            // item인 node들만 반환 (=layer)
            var _get = function (key) {
                var group = key.split('-');
                var parent = getParent(_root, group);
                return parent.children.filter(function (node) {
                    return node.type == 'item'
                });
            };

            var _clear = function () {
                _root.children = [];
            };

            var _setState = function (key, state) {
                var group = key.split('-');
                var node = getParent(_root, group, false);
                if (!node) return false;

                node['state'] = state;
                return true;
            };

            var _toTreeJson = function () {
                return _root.children;
            };

            return {
                'root': _root,
                'set': _set,
                'get': _get,
                'setState': _setState,
                'toTreeJson': _toTreeJson,
                'clear': _clear,
            };

        })(treeCtrl);
    }

    function getIntTreeList() {
        $('.treeLoading').show();
        var url = 'getIntTreeList.do';
        requestService(url, '', getIntTreeListCallback);
    }
    function nameSort(a, b) {
        const aA = a.addr1;
        const bA = b.addr1;
        const x = a.name.toLowerCase();
		const y = b.name.toLowerCase();
        return aA > bA ? 1 : aA === bA ? (x > y ? 1 : x === y ? 0 : -1) : -1;
        //return x < y ? -1 : x > y ? 1 : 0;
    }


    function getIntTreeListCallback(data) {
        treeCtrl.clear();

        var nodeId;
        var name;
        var lat;
        var lng;
        var addr1;
        var addr2;
        var addr3;
        var ipAddr;

        var nameCntOn;
        data.sort(nameSort);

        //TODO: 20230221
        setAddrMap(data);
        window.parent._signalInfoArr.length = 0;
        for (var i = 0; i < data.length; i++) {
            if (data[i].addr1 == null || data[i].addr1 == '-') {
                continue;
            }

            nodeId = data[i].nodeid;
            name = data[i].name;
            lat = data[i].lat;
            lng = data[i].lng;
            addr1 = data[i].addr1;
            addr2 = data[i].addr2;
            addr3 = data[i].addr3;
            ipAddr = data[i].ipaddr;

            //console.log('nodeid :'+nodeId+' , name : '+name+', lat : '+lat+', lng : '+lng+', addr1 : '+addr1);
            var signal = new SignalInfo(nodeId, name, lat, lng, addr1, addr2, addr3);
            //부모 변수에 저장
            //iframe이라서 직접 접근이 안됨
            window.parent._signalInfoArr.push(signal);

            var engAddr = getEngAddr(addr1);

            nameCntOn = '&nbsp;<strong class="centerNm_' + engAddr + '">' + addr1 +
                      // '</strong>&nbsp;( 전체 : <span class="intTotal" id="intTotal_'+engAddr+'" style="color:#0000FF"></span> / 이상 : '+
                      '</strong>&nbsp;( 전체 : <span class="intTotal" id="intTotal_'+engAddr+'" style="color:#3396ff"></span> / 이상 : '+
					  // '<span class="intErrCnt" id="intErrCnt_'+engAddr+'" style="color:#FF0000"></span> )';
					  '<span class="intErrCnt" id="intErrCnt_'+engAddr+'" style="color:#ef6060"></span> )';

            //guTitleOff = nameCntOn + '-' + addr2 + '&nbsp;';

            var intNm = nodeId + '_' + name;
            var intStatus = getStatus(signal.status);

            function getStatus(stts){
                if(stts == 1){
                    return "On"; //정상
                }else if( stts == 2){
                    return "Off"; //교차로시각이상
                }else{
                    return "Null"; // 통신시간 3초이상
                }

            }

            let searchX = null;
            let searchY = null;
            let searchText = null;
            if (_searchText) {
                if (_searchText.indexOf(',') > -1) {
                    const coordArr = _searchText.split(',');
                    if (coordArr.length === 2) {
                        searchX = coordArr[0].trim();
                        searchY = coordArr[1].trim();
                        if (lat.toString() !== searchX.toString() || lng.toString() !== searchY.toString()) {
                            continue;
                        }
                    }
                }
                else {
                    searchText = _searchText;
                    if (nodeId.indexOf(searchText) === -1 &&
                        name.indexOf(searchText) === -1
                    ) {
                        continue;
                    }
                }
            }
            treeCtrl.set([nameCntOn], {
                name: name+" ("+nodeId+")",
                id: nodeId,
                icon: "images/comm" + intStatus + ".png",
                data: {
                    'line': 'offline',
                    'intNo': nodeId, 'intNm': name,
                    'lat': lat, 'lng': lng,
                }
            });

        }


        treeJson = treeCtrl.toTreeJson();


        $('#intTree').jstree({
            'core': {
                'data': treeJson,
                "themes": {"stripes": true},
            },
            "plugins": ["wholerow"]
        });


        // jsTree 클릭 이벤트 : 레이어 setVisible
        $('#intTree').bind('select_node.jstree', function (event, data) {

            var parentNd = data.node.parent;
            var children = data.node.children;

            //parent._RegionCd = data.node.data.regionCd;

            if (parentNd == '#') //시도 선택
            {
            } else if (parentNd != '#' && children.length > 0) //구 선택
            {
            } else {
                var intNm = data.node.data.intNm;
                var lng = data.node.data.lng;
                var lat = data.node.data.lat;

                if(parent._Level > 3) parent.map.setLevel(1);
                parent.map.panTo(new parent.kakao.maps.LatLng(lat, lng));
                setTimeout(
                    function() {
                        parent.getSignalInfo();
                        parent.customOverlayFnc(intNm,lng,lat);
                    }, 100 * 2);
            }

        });

        $('.treeLoading').hide();
    }

    //유선 센터상테 체크..
    function onlineCenterStatusCheck() {

        if (onlineCenterStatusCheckId != null) clearTimeout(onlineCenterStatusCheckId);
        onlineCenterStatusCheckId = setTimeout('onlineCenterStatusCheck()', 5 * 1000);

        var url = 'getOnlineCenterStatus.do';
        requestService(url, '', onlineCenterStatusCheckCallback);
    }

    function onlineCenterStatusCheckCallback(data) {
        onlineCenterStatusData = data;
        drawCenterStatus(0, data);
    }

    //무선 센터상테 체크..
    function offlineCenterStatusCheck() {

        if (offlineCenterStatusCheckId != null) clearTimeout(offlineCenterStatusCheckId);
        offlineCenterStatusCheckId = setTimeout('offlineCenterStatusCheck()', 5 * 1000);

        var url = 'getOfflineCenterStatus.do';
        requestService(url, '', offlineCenterStatusCheckCallback);
    }

    function offlineCenterStatusCheckCallback(data) {
        offlineCenterStatusData = data;
        drawCenterStatus(1, data);
    }

    function drawCenterStatus(network, data) {
        var regionCd;
        var totCnt;
        var errCnt;
        var commState;
        var commImg = '';

        for (var ii = 0; ii < data.length; ii++) {
            regionCd = data[ii].REGION_CD;
            totCnt = data[ii].TOT;
            errCnt = data[ii].ERR_CNT;
            commState = data[ii].COMM_STATE;

            if (commState == 1) {
                commImg = 'images/commOff.png';
                $('.intErrCnt_' + network + '_' + regionCd).text(totCnt);
            } else {
                commImg = 'images/commOn.png';
                $('.intErrCnt_' + network + '_' + regionCd).text(errCnt);
            }
            if (network == 0) $('.regionComm_' + network + '_' + regionCd).attr('src', commImg);

            $('.intTotal_' + network + '_' + regionCd).text(totCnt);
        }
    }

    //유선 제어기 상태 체크..
    function onlineIntStatusCheck() {
        if (_RegionCdArr.length > 0) {
            if (onlineIntStatusCheckId != null) clearTimeout(onlineIntStatusCheckId);
            onlineIntStatusCheckId = setTimeout('onlineIntStatusCheck()', 5 * 1000);

            var url = 'getOnlineIntStatus.do';
            var param = 'regionCd=' + _RegionCdArr;
            requestService(url, param, onlineIntStatusCheckCallback);
        }
    }

    function onlineIntStatusCheckCallback(data) {
        onlineIntStatusData = data;
        drawIntStatus(0, data);
    }

    //무선 제어기 상태 체크..
    function offlineIntStatusCheck() {
        if (_RegionCdArr.length > 0) {
            if (offlineIntStatusCheckId != null) clearTimeout(offlineIntStatusCheckId);
            offlineIntStatusCheckId = setTimeout('offlineIntStatusCheck()', 5 * 1000);

            var url = 'getOfflineIntStatus.do';
            var param = 'regionCd=' + _RegionCdArr;
            requestService(url, param, offlineIntStatusCheckCallback);
        }
    }

    function offlineIntStatusCheckCallback(data) {
        offlineIntStatusData = data;
        drawIntStatus(1, data);
    }

    function drawIntStatus(network, data) {
        var commState;
        if (network == 0) {
            for (var i = 0; i < onlineCenterStatusData.length; i++) {
                if (onlineCenterStatusData[i].REGION_CD == data[0].REGION_CD) {
                    commState = onlineCenterStatusData[i].COMM_STATE;
                    break;
                }
            }
        } else {
            commState = 0;
        }

        var regionCd;
        var siguguCd;
        var intNoArr;
        var commOnOffFlagArr;
        var commOnOffImg;

        for (var ii = 0; ii < data.length; ii++) {
            regionCd = data[ii].REGION_CD;
            sigunguCd = data[ii].SIGUNGU_CD;
            intNoArr = data[ii].INT_NO.split('|');
            commOnOffFlagArr = data[ii].COMM_ON_OFF_FLAG.split('|');

            $('.guIntTotal_' + network + '_' + sigunguCd).text(intNoArr.length);

            //sigunguCd = 41190 부천시 , 41430 의왕시, 41410 군포시

            //commState = 1;

            //시군구 코드가 없으면 상태정보이미지가 없데이트가 안된다...
            if (commState == 0) {
                var guIntErrCnt = 0;
                for (var jj = 0; jj < intNoArr.length; jj++) {
                    if (commOnOffFlagArr[jj] == 1) {
                        guIntErrCnt++;
                        commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
                    } else {
                        commOnOffImg = 'background-image:url("images/intStatusOn.png");background-position:center center';
                    }
                    $('#' + regionCd + '_' + network + '_' + intNoArr[jj] + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
                }
                $('.guIntErrCnt_' + network + '_' + sigunguCd).text(guIntErrCnt);
            } else {
                for (var j = 0; j < intNoArr.length; j++) {
                    commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
                    $('#' + regionCd + '_' + network + '_' + intNoArr[j] + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
                }
                $('.guIntErrCnt_' + network + '_' + sigunguCd).text(intNoArr.length);
            }

        }
    }


    function goIntMenu() {
        $('.tabs > li').eq(0).addClass('on');
        $('.tabs > li').eq(1).removeClass('on');
        // $('.treeLoading').hide();
        $('#historyList').hide();
        $('#intTree').show();
        $('.searchBox').css('display', 'flex');
        $('.historyBox').css('display', 'none');
        $('.leftMenu .evp-cur').hide();
        $('.evp_legend', parent.document).hide();
        unsetEvpCurr();

        const bottomFrame = $('#iframeBottomList', parent.document).contents();
        bottomFrame.find('#cvibBottomBodyTable').show();
        bottomFrame.find('#evpBottomBodyTable').hide();

        if (_historyMap && _historyMap.size) {
            if(interval) clearInterval(interval);
            _historyMap.forEach((obj)=> {
                if (obj.get('draw')) {
                    obj.get('draw').clear();
                    obj.set('draw', null);
                }
            });
            $('.history-table tr.on').removeClass('on');
            bottomFrame.find('#evpBottomInfo').empty();
            imageOnOff('play', false);
            imageOnOff('stop', false);
            imageOnOff('pause', false);
        }
        //.show();
    }

    function unsetEvpCurr() {
        if (window.parent._EmergencyMap && window.parent._EmergencyMap.size) {
            window.parent._EmergencyMap.forEach((obj)=> obj.clear());
            window.parent._EmergencyMap.clear();
            $('.evp-table tr.on').removeClass('on');
            window.parent._isClick = null;
        }
    }

    function goEvpMenu() {
        $('.tabs > li').eq(1).addClass('on');
        $('.tabs > li').eq(0).removeClass('on');
        $('.evp_legend', parent.document).show();
        // $('.treeLoading').show();
        $('#historyList').show();
        $('#intTree').hide();
        $('.searchBox').css('display', 'none');
        $('.historyBox').css('display', 'flex');
        $('.leftMenu .evp-cur').show();
        const bottomFrame = $('#iframeBottomList', parent.document).contents();
        bottomFrame.find('#cvibBottomBodyTable').hide();
        bottomFrame.find('#evpBottomBodyTable').show();
    }

    function searchHistoryData() {
        const $emptyBox = $('.empty-history');
        const $historyLoading = $('.history-loading');
        const $region       = $('#region');
        const regionVal    = $region.val();
        const startVal     = $start.val();
        const endVal       = $end.val();
        const startTimeVal = $startTime.val();
        const endTimeVal   = $endTime.val();
        if (!startVal) {
            alert('검색시작 년월일을 입력해주세요');
            return $start.focus();
        }
        if (!startTimeVal) {
            alert('검색시작 시간을 입력해주세요');
            return $startTime.focus();
        }
        if (!endVal) {
            alert('검색종료 년월일을 입력해주세요');
            return $end.focus();
        }

        if (!endTimeVal) {
            alert('검색종료 시간을 입력해주세요');
            return $endTime.focus();
        }

        const param = {
            start : startVal + ' ' + startTimeVal + ':00',
            end : endVal + ' ' + endTimeVal + ':59',
            region : regionVal
        }
        if (param.start > param.end) {
            alert('검색시작 일시가 종료 일시 보다 큽니다.');
            return $end.focus();
        }

        const $historyTable = $('.history-table');
        $historyTable.empty();
        $emptyBox.css('display', 'none');
        $historyLoading.css('display', 'flex');
        imageOnOff('play', false);
        imageOnOff('stop', false);
        imageOnOff('pause', false);

        if (_historyMap.size) {
            _historyMap.forEach((obj)=>{
                if (obj.get('draw')) obj.get('draw').clear();
            });
            _historyMap.clear();
            if (interval) {
                clearInterval(interval);
                interval = null;
                cnt = 0;
            }
            const bottomFrame = $('#iframeBottomList', parent.document).contents();
            bottomFrame.find('#evpBottomInfo').empty();
        }

        window.parent.requestService('getEvpHistory.do', param, (rec)=>{
            let str = ''
            if (rec && rec.length) {
                for (let history of rec) {
                     _historyMap.set(history.service_id, new Map());
                    const {event_list, phase_list, node_list} = history;

                    const dateMap = new Map();
                    if (event_list.length && phase_list.length) {
                        event_list.forEach((eventObj)=>{
                            dateMap.set(eventObj.clct_dt, new Map());
                            dateMap.get(eventObj.clct_dt).set('event', eventObj);
                            dateMap.get(eventObj.clct_dt).set('sig', []);
                        });

                        phase_list.forEach((obj)=>{
                            if (!dateMap.get(obj.clct_dt)) {
                                dateMap.set(obj.clct_dt, new Map());
                                dateMap.get(obj.clct_dt).set('event', null);
                                dateMap.get(obj.clct_dt).set('sig', []);

                            }
                            dateMap.get(obj.clct_dt).get('sig').push(obj);
                        });

                        if (dateMap.size) {
                            history.event_list = [];
                            history.phase_list = [];
                            const dateArr = Array.from(dateMap.keys()).sort();
                            let beforeSig;
                            let beforeEvent;

                            for (let date of dateArr) {
                                const objMap = dateMap.get(date);
                                if (objMap.get('event') === null && beforeEvent === undefined) {
                                    beforeEvent = event_list[0];
                                }
                                else if (objMap.get('event')){
                                    beforeEvent = objMap.get('event');
                                }
                                const eventData = {...beforeEvent};

                                eventData.clct_dt = date;

                                if (objMap.get('sig').length === 0 && beforeSig === undefined) {
                                    beforeSig = dateMap.get(phase_list[0].clct_dt).get('sig');
                                }
                                else if (objMap.get('sig').length) {
                                    beforeSig = objMap.get('sig');
                                }

                                if (beforeSig.length !== node_list.length) {
                                    for (let node of node_list) {
                                        let idx = objMap.get('sig').findIndex(obj => obj.seq_no === node.seq_no)
                                        if (idx === -1) {
                                            if (new Date(date).getTime() - new Date(dateArr[0]).getTime() != 0) {
                                                let startTime = new Date(dateArr[0]).getTime();
                                                let currTime = new Date(date).getTime();
                                                let beforeObj = null

                                                for (let ii = currTime; ii >= startTime; ii -= 1000) {
                                                    const key = getDateTimeToStr(new Date(ii));
                                                    if (dateMap.get(key)) {
                                                        const beforeIdx = dateMap.get(key).get('sig').findIndex(obj => obj.seq_no === node.seq_no);

                                                        if (beforeIdx > -1) {
                                                            beforeObj = dateMap.get(key).get('sig')[beforeIdx];
                                                            break;
                                                        }
                                                    }
                                                }
                                                if (beforeObj) {
                                                    beforeSig.push({
                                                        seq_no : beforeObj.seq_no,
                                                        clct_dt : date,
                                                        service_id : beforeObj.service_id,
                                                        a_end_angle : beforeObj.a_end_angle,
                                                        a_end_lat:beforeObj.a_end_lat,
                                                        a_end_lng:beforeObj.a_end_lng,
                                                        a_flow_no:beforeObj.a_flow_no,
                                                        a_head_angle:beforeObj.a_head_angle,
                                                        a_head_lat:beforeObj.a_head_lat,
                                                        a_head_lng: beforeObj.a_head_lng,
                                                        a_mid_lat:beforeObj.a_mid_lat,
                                                        a_mid_lng:beforeObj.a_mid_lng,
                                                        a_ring_phase:beforeObj.a_ring_phase,
                                                        b_end_angle:beforeObj.b_end_angle,
                                                        b_end_lat:beforeObj.b_end_lat,
                                                        b_end_lng:beforeObj.b_end_lng,
                                                        b_flow_no:beforeObj.b_flow_no,
                                                        b_head_angle:beforeObj.b_head_angle,
                                                        b_head_lat:beforeObj.b_head_lat,
                                                        b_head_lng:beforeObj.b_head_lng,
                                                        b_mid_lat:beforeObj.b_mid_lat,
                                                        b_mid_lng:beforeObj.b_mid_lng,
                                                        b_ring_phase:beforeObj.b_ring_phase,
                                                        hold_phase:beforeObj.hold_phase,
                                                        lat : beforeObj.lat,
                                                        lng : beforeObj.lng,
                                                        node_id : beforeObj.node_id,
                                                        node_nm : beforeObj.node_nm,
                                                        plan_class:beforeObj.plan_class,
                                                        rem_dist:beforeObj.rem_dist,
                                                        state : beforeObj.state,
                                                    })
                                                }

                                            }

                                        }
                                    }
                                }
                                const sigData = beforeSig;
                                history.event_list.push(eventData);
                                history.phase_list.push(sigData);
                            }
                        }
                    }

                     _historyMap.get(history.service_id).set('obj', history);
                     _historyMap.get(history.service_id).set('draw', null);
                    str += `<tr class="hs_\${history.service_id}" onclick="drawHistory('\${history.service_id}')"><td>\${history.clct_dt}</td><td>\${history.service_id}</td><td>\${history.service_nm}</td></tr>`;
                }
            }

            $historyLoading.css('display', 'none');

            if (str === '') {
                $emptyBox.css('display', 'flex');
            }

            $historyTable.html(str);
        }, true, ()=>{
            $emptyBox.css('display', 'flex');
            $historyLoading.css('display', 'none');
        });
    }

    function drawHistory(serviceId) {
        unsetEvpCurr();
        if (_historyMap.size) {
            _historyMap.forEach((obj, key)=>{
                const beforeDraw = obj.get('draw');
                if (beforeDraw && serviceId !== key) {
                    beforeDraw.clear();
                    obj.set('draw', null);
                }
            });

            if (_historyMap.get(serviceId).get('draw')) {
                return;
            }
            else {
                if (interval) {
                    clearInterval(interval);
                    interval = null;
                    cnt = 0;
                }
            }
        }

        const obj = _historyMap.get(serviceId).get('obj');
        $('#historyList tr.on').removeClass('on');
        $('.hs_' + serviceId).addClass('on');
        const drawObj = {...obj};
        const { event_list, phase_list } = obj;

        if (event_list && event_list.length) drawObj.event_list = [drawObj.event_list[0]];
        if (phase_list && phase_list.length) drawObj.phase_list = phase_list[0];
        const bottomFrame = $('#iframeBottomList', parent.document).contents();
        const bottomInfo  = bottomFrame.find('#evpBottomInfo');

        let str = '';

        event_list.forEach((event, idx)=>{
            str += getBottomListEl(obj, event, idx);
        });

        bottomInfo.html(str);
        const draw = window.parent.drawHistory(drawObj);
        _historyMap.get(serviceId).set('draw', draw);
        bottomFrame.find('.bottomBody').scrollTop(0);
        imageOnOff('play', true);
        imageOnOff('stop', false);
        imageOnOff('pause', false);
    }

    function imageOnOff(name, isOn) {
        const el = $('#' + name);
        const eventName = isOn ? 'addClass' : 'removeClass';
        el[eventName]('on');

        if (el.attr('src') === getImageName(name, !isOn)) {
            el.attr('src', getImageName(name, isOn));
        }
    }

    /**
     * 긴급차량우선신호 bottom list 생성
     * @param obj 서비스 정보
     * @param event 발생 이벤트 정보
     * @param idx 인덱스 번호
     * @returns {string} html 리스트 목록 반환
     */
    function getBottomListEl(obj, event, idx) {
        const regionNm = $('#region option[value="'+obj.service_id.substr(0,3)+'"]').text(); //왼쪽 3글자는 센터 번호를 의미
        let className = '';

        if (idx === 0) { //처음 그릴때 첫줄을 기반으로 그리므로 선택 표시
            className = 'on';
        }
        let curSpd = '-';
        if (event.cur_spd) { // 현재 스피드가 있을경우 천단위 콤마
            curSpd = event.cur_spd.toLocaleString('ko-KR');
        }

        let remDist = '-';
        if (event.rem_dist) {// 남은 거리가 있을경우 천단위 콤마
            remDist = event.rem_dist.toLocaleString('ko-KR');
        }


        let clctDt = event.clct_dt.replace(/\:|\-| /gi, '') //시간 기호(':', '-', ' ') 제거 후 값만 추출 하여 table 로우 ID 부여
        let str = `<tr onclick="moveLocation('\${obj.service_id}', this)" class="\${className}" id="\${obj.service_id}_\${clctDt}">`
                    +'<td>'+event.clct_dt+'</td>'
                    +'<td>'+regionNm+'</td>'
                    +'<td>'+obj.service_id+'</td>'
                    +'<td>'+obj.service_nm+'</td>'
                    +'<td>'+obj.ev_no+'</td>'
                    +'<td>'+event.cur_lng+'</td>'
                    +'<td>'+event.cur_lat+'</td>'
                    +'<td>'+curSpd+'</td>'
                    +'<td>'+remDist+'</td>'
                +'</tr>';
        return str;
    }

    /**
     * 시뮬레이션 재생 / 멈춤 버튼 활성화 비활성화 이미지명 가져오기
     * @param name 요소 ID name (ID 와 이미지 이름이 동일함)
     * @param isOn 활성화/비활성화(true/false)
     * @returns {string} 이미지명 반환
     */
    function getImageName(name, isOn) {
        let imgName = '/images/' + name;
        const onName = '_on';
        const extName = '.png';
        if (isOn) {
            imgName += onName;
        }
        return imgName + extName;
    }


    /**
     * 시뭏레이션 재생
     */
    function playSimulation() {
        if (!$('#play').hasClass('on')) return; //비활성화중일 때만 실행
        if (interval) {
            clearInterval(interval);
            interval = null;
        }
        const serviceId = $('.history-table tr.on').attr('class').replace(/hs_| on/gi, '');// 선택 로우에서 service id 추출
        let evp = _historyMap.get(serviceId); //Map 에 저장된 해당 service_id 데이터 정보 가져오기
        let obj = evp.get('obj'); //object 정보
        let draw = evp.get('draw'); // marker handler 정보
        if (!draw) {// handler 가 없다면 생성
            drawHistory(serviceId);
            draw = evp.get('draw');
        }

        const { event_list, phase_list } = obj; //이벤트 리스트와 신호 리스트

        //버튼 활성화/비활성화 적용
        imageOnOff('stop', true);
        imageOnOff('pause', true);
        imageOnOff('play', false);

        interval = setInterval(()=>{
            cnt++;
            if (event_list.length === cnt) {
                return stopSimulation();
            }
            const bottomFrame = $('#iframeBottomList', parent.document).contents();
            bottomFrame.find('#evpBottomInfo tr.on').removeClass('on');
            let clctDt = event_list[cnt].clct_dt.replace(/\:|\-| /gi, '')
            const bottomInfo = bottomFrame.find('#evpBottomInfo #'+obj.service_id +'_'+clctDt);
            bottomInfo.addClass('on');
            bottomFrame.find('.bottomBody').scrollTop(32 * cnt);

            const position = window.parent.getKakaoPosition(event_list[cnt].cur_lat, event_list[cnt].cur_lng);
            draw.car.moveMarker(position);
            setSigState(phase_list[cnt], draw);

        }, 500);
    }

    function setSigState(phase, draw) {
        phase.forEach((sigObj)=>{
            if (draw.sig.get(sigObj.service_id + '_' + sigObj.seq_no) === undefined) {
                draw.sig.set(sigObj.service_id + '_' + sigObj.seq_no, window.parent.createSig(sigObj));
            }
            const evpSig = draw.sig.get(sigObj.service_id + '_' + sigObj.seq_no);
            evpSig.createRing(sigObj);
        });

        draw.sig.forEach((obj, key)=>{
            const idx = phase.findIndex((sig)=>{
                return sig.service_id + '_' + sig.seq_no === key;
            })

            if (idx === -1) {
                obj.deleteRing();
                obj.setState(1);
            }
        })
    }

    function pauseSimulation() {
        if (!$('#pause').hasClass('on')) {
            return;
        }
        clearInterval(interval);
        imageOnOff('pause', false);
        imageOnOff('play', true);
    }

    function stopSimulation() {
        if (!$('#stop').hasClass('on')) {
            return;
        }
        clearInterval(interval);
        imageOnOff('stop', false);
        imageOnOff('pause', false);
        imageOnOff('play', true);
        cnt = 0;
        const serviceId = $('.history-table tr.on').attr('class').replace(/hs_| on/gi, '');
        clearSimulator();
        drawHistory(serviceId);
    }

    function clearSimulator() {
        _historyMap.forEach((obj)=>{
            const beforeDraw = obj.get('draw');
            if (beforeDraw) {
                beforeDraw.clear();
                obj.set('draw', null);
            }
        })
    }
</script>
</body>
</html>

