// 마커를 담을 배열입니다
    let markers = [];
 
    const mapContainer = document.getElementById('map'), // 지도를 표시할 div
    mapOption = {
        center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
        level: 12 // 지도의 확대 레벨
    };
 
    // 지도를 생성합니다
    const map = new kakao.maps.Map(mapContainer, mapOption);
 
    // 마커 클러스터러를 생성합니다
    const clusterer = new kakao.maps.MarkerClusterer({
        map: map, // 마커들을 클러스터로 관리하고 표시할 지도 객체
        averageCenter: true, // 클러스터에 포함된 마커들의 평균 위치를 클러스터 마커 위치로 설정
        minLevel: 6 // 클러스터 할 최소 지도 레벨
    });
 
    // 일반 지도와 스카이뷰로 지도 타입을 전환할 수 있는 지도타입 컨트롤을 생성합니다
    const mapTypeControl = new kakao.maps.MapTypeControl();
 
    // 지도에 컨트롤을 추가해야 지도위에 표시됩니다
    // kakao.maps.ControlPosition은 컨트롤이 표시될 위치를 정의하는데 TOPRIGHT는 오른쪽 위를 의미합니다
    map.addControl(mapTypeControl, kakao.maps.ControlPosition.TOPRIGHT);
 
    // 지도 확대 축소를 제어할 수 있는  줌 컨트롤을 생성합니다
    const zoomControl = new kakao.maps.ZoomControl();
    map.addControl(zoomControl, kakao.maps.ControlPosition.RIGHTBOTTOM);
 
    // 지도가 이동, 확대, 축소로 인해 중심좌표가 변경되면 마지막 파라미터로 넘어온 함수를 호출하도록 이벤트를 등록합니다
    let getLat = null;
    let getLng = null;
    kakao.maps.event.addListener(map, 'center_changed', function() {
        // 지도의  레벨을 얻어옵니다
        const level = map.getLevel();
        // 지도의 중심좌표를 얻어옵니다
        const latlng = map.getCenter();
        console.log('중심 위도: '+latlng.getLat() + ', 경도: ' + latlng.getLng());
        getLat = latlng.getLat();
        getLng = latlng.getLng();
    });
 
    // 장소 검색 객체를 생성합니다
    const ps = new kakao.maps.services.Places();
 
    // 검색 결과 목록이나 마커를 클릭했을 때 장소명을 표출할 인포윈도우를 생성합니다
    const infowindow = new kakao.maps.InfoWindow({zIndex:1});
 
    // 키워드로 장소를 검색합니다
    searchPlaces();
 
    // 키워드 검색을 요청하는 함수입니다
    function searchPlaces() {
        let keyword = document.getElementById('keyword').value;
        let radius = $("input[name='radius']:checked").val();
 
        $.ajax({
            url : 'ajaxMap.php',
            type : 'GET',
            data : { 'msg': keyword, 'radius':radius, 'lat':getLat, 'lng':getLng },
            dataType: 'json',
            success : function(json) {
                if(json.length == 0) {
                    alert('검색 데이터가 없습니다.');
                    return;
                }
 
                console.log('데이터 갯수 :: ' + json.length);
                displayPlaces(json);
 
                // 클러스터에 마커들을 추가합니다
                clusterer.addMarkers(markers);
 
                var pagination = [ '1', '2', '3' ];
                displayPagination(pagination);
            },
            error : function(xhr, status, error){
                alert("에러코드 : " + xhr.status); //요청에 실패하면 에러코드 출력
            },
            complete : function() {
                
            }
        });
    }
 
    // 장소검색이 완료됐을 때 호출되는 콜백함수 입니다
    function placesSearchCB(data, status, pagination) {
        if (status === kakao.maps.services.Status.OK) {
            // 정상적으로 검색이 완료됐으면 검색 목록과 마커를 표출합니다
            displayPlaces(data);
 
            // 페이지 번호를 표출합니다
            displayPagination(pagination);
        } else if (status === kakao.maps.services.Status.ZERO_RESULT) {
            alert('검색 결과가 존재하지 않습니다.');
            return;
        } else if (status === kakao.maps.services.Status.ERROR) {
            alert('검색 결과 중 오류가 발생했습니다.');
            return;
        }
    }
 
    // 검색 결과 목록과 마커를 표출하는 함수입니다
    function displayPlaces(places) {
        let listEl = document.getElementById('placesList'),
        menuEl = document.getElementById('menu_wrap'),
        fragment = document.createDocumentFragment(),
        bounds = new kakao.maps.LatLngBounds(),
        listStr = '';
 
        // 검색 결과 목록에 추가된 항목들을 제거합니다
        removeAllChildNods(listEl);
 
        // 지도에 표시되고 있는 마커를 제거합니다
        removeMarker();
 
        const cntEl = document.getElementById('datacount');
        cntEl.innerText = '검색 개수 : ' + places.length;
 
 
        for (let i=0; i<places.length; i++) {
 
            let color_marker = "marker-icon-blue.png";
 
            if (places[i].yn == 0)  { // 없으면 => 빨간색
                color_marker = "marker-icon-red.png";
                if(places[i].isbiz > 0) {
                    color_marker = "marker-icon-green.png";
                }
            } else {
                color_marker = "marker-icon-blue.png";
                if(places[i].isbiz > 0) {
                    color_marker = "marker-icon-orange.png";
                }
            }
 
            // 마커를 생성하고 지도에 표시합니다.
            let idx = places[i].idx; // 절대 var 변수를 선언하면 안된다. 반드시 let 변수를 선언해야 제대로 동작되더라. 개삽질을 엄청했다.
            let title = places[i].idx;
            let placePosition = new kakao.maps.LatLng(places[i].latitude, places[i].longitude);
            let marker = addMarkers(placePosition, color_marker, title);
            let itemEl = getListItem(i, places[i], color_marker); // 검색 결과 항목 Element를 생성합니다
 
            // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해 LatLngBounds 객체에 좌표를 추가합니다
            bounds.extend(placePosition);
 
            // 마커와 검색결과
            // 항목에 mouseover 했을때 해당 장소에 인포윈도우에 장소명을 표시합니다. mouseout 했을 때는 인포윈도우를 닫습니다
            (function(marker, title) {
                kakao.maps.event.addListener(marker, 'mouseover', function() {
                    displayInfowindow(marker, title);
                });
 
                kakao.maps.event.addListener(marker, 'mouseout', function() {
                    infowindow.close();
                });
 
                itemEl.onmouseover =  function () {
                    displayInfowindow(marker, title);
                };
 
                itemEl.onmouseout =  function () {
                    infowindow.close();
                };
 
                // 마커에 클릭 이벤트를 등록한다.
                kakao.maps.event.addListener(marker, 'click', function() {
                    //map.panTo(placePosition); // 지도 중심을 부드럽게 이동시킨다.
                    console.log('idx:' + idx);
                    custom_infowindow(idx);
 
                });
 
            })(marker, places[i].bldNM);
 
            fragment.appendChild(itemEl);
        }
 
        // 검색결과 항목들을 검색결과 목록 Elemnet에 추가합니다
        listEl.appendChild(fragment);
        menuEl.scrollTop = 0;
 
        // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
        map.setBounds(bounds);
    }
 
    function custom_infowindow(idx){
        $('#dialog').load('infowindow.php?do='+idx, function() {
            $(this).dialog({
                autoOpen : true,
                height : 'auto',
                width : 'auto',
                position: { my: "center", at: "center", of: window },
                title : 'XX정보',
                buttons : {
                    "닫기" : function() {
                        $(this).dialog("close");
                    }
                }
            });
        });
 
    }
 
    // 검색결과 항목을 Element로 반환하는 함수입니다. 위도, 경도, 번호, 건물명, 도로명주소, 지번주소
    function getListItem(index, places, _color) {
        let el = document.createElement('li'),
        itemStr = '<span style="float:left;position:absolute;width:33px; height:31px;margin:10px 0 0 10px;"><img width="31" height="31" src="./marker/' + _color + '"></span>' +
                  '<div class="info">' +
                  '   <h5>' + places.bldNM + '</h5>';
 
        if (places.stAddress) {
            itemStr += '   <span>' + places.stAddress + '</span>' +
                       '   <span class="jibun gray">' +  places.jiAddress  + '</span>';
        } else {
            itemStr += '   <span>' +  places.jiAddress  + '</span>';
        }
 
        itemStr     += '  <span class="tel">' + places.idx  + '</span>' +
                       '</div>';
 
        el.innerHTML = itemStr;
        el.className = 'item';
 
        return el;
    }
 
 
    function addMarkers(position, _color, title) {
        const imageSrc = './marker/' + _color;
        const imageSize = new kakao.maps.Size(33, 33);
        const imageOptions = {
            offset: new kakao.maps.Point(27, 69)
        };
 
        const markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize, imageOptions)
        // 마커를 생성합니다
        const marker = new kakao.maps.Marker({
            position: position,
            //title: title,
            image: markerImage
        });
 
 
        marker.setMap(map); // 마커가 지도 위에 표시되도록 설정합니다
        markers.push(marker); // 생성된 마커를 배열에 추가합니다
 
        return marker;
    }
 
    // 지도 위에 표시되고 있는 마커를 모두 제거합니다
    function removeMarker() {
        //clusterer.removeMarkers(markers);
        clusterer.clear(); // 추가된 모든 마커 삭제
        for ( let i = 0; i < markers.length; i++ ) {
            markers[i].setMap(null);
        }
        markers = [];
    }
 
    // 검색결과 목록 하단에 페이지번호를 표시는 함수입니다
    function displayPagination(pagination) {
        let paginationEl = document.getElementById('pagination'),
            fragment = document.createDocumentFragment(),
            i;
 
        // 기존에 추가된 페이지번호를 삭제합니다
        while (paginationEl.hasChildNodes()) {
            paginationEl.removeChild (paginationEl.lastChild);
        }
 
        for (i=1; i<=pagination.last; i++) {
            let el = document.createElement('a');
            el.href = "#";
            el.innerHTML = i;
 
            if (i===pagination.current) {
                el.className = 'on';
            } else {
                el.onclick = (function(i) {
                    return function() {
                        pagination.gotoPage(i);
                    }
                })(i);
            }
 
            fragment.appendChild(el);
        }
        paginationEl.appendChild(fragment);
    }
 
    // 검색결과 목록 또는 마커를 클릭했을 때 호출되는 함수. 인포윈도우에 장소명을 표시합니다
    function displayInfowindow(marker, title) {
        const content = '<div style="padding:5px;z-index:1;">' + title + '</div>';
 
        infowindow.setContent(content);
        infowindow.open(map, marker);
    }
 
    // 검색결과 목록의 자식 Element를 제거하는 함수입니다
    function removeAllChildNods(el) {
        while (el.hasChildNodes()) {
            el.removeChild (el.lastChild);
        }
    }