<?php

use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\View;

?>

<div class="py-4">
    <div class="row gchart osm-wrapper">
        <div id="osm-map" class="col-sm-9 wt-ajax-load osm-user-map" dir="ltr"></div>
        <ul class="col-sm-3 osm-sidebar wt-page-options-value list-unstyled px-md-1"></ul>
    </div>
</div>

<?php View::push('styles') ?>
<style>
    .osm-wrapper, .osm-user-map {
        height: 70vh
    }

    .osm-sidebar {
        height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
        font-size: small;
    }

    .flag {
        border: 1px solid grey !important;
        height: 15px;
        width: 25px;
    }
</style>
<?php View::endpush() ?>

<?php View::push('javascript') ?>
<script type="application/javascript">
    "use strict";

    window.WT_OSM = (function () {
        let baseData = {
            minZoom: 2,
            providerName: "OpenStreetMap.Mapnik",
            providerOptions: [],
        };

        let map     = null;
        let zoom    = null;
        let sidebar = $(".osm-sidebar");
        let markers = L.markerClusterGroup({
            showCoverageOnHover: false,
        });

        let resetControl = L.Control.extend({
            options: {
                position: "topleft",
            },

            onAdd: function (map) {
                let container = L.DomUtil.create("div", "leaflet-bar leaflet-control leaflet-control-custom");
                container.onclick = function () {
                    if (zoom) {
                        map.flyTo(markers.getBounds().getCenter(), zoom);
                    } else {
                        map.flyToBounds(markers.getBounds().pad(0.2));
                    }
                    sidebar.scrollTo(sidebar.children(":first"));

                    return false;
                };
                let anchor = L.DomUtil.create("a", "leaflet-control-reset", container);
                let reset = <?= json_encode(I18N::translate('Reset to initial map state')) ?>;
                anchor.href = "#";
                anchor.title = reset;
                anchor.role = "button";
                $(anchor).attr("aria-label", "reset");
                let image = L.DomUtil.create("i", "fas fa-redo", anchor);
                image.alt = reset;

                return container;
            },
        });

        let _drawMap = function () {
            map = L.map("osm-map", {
                center: [0, 0],
                minZoom: baseData.minZoom, // maxZoom set by leaflet-providers.js
                zoomControl: false, // remove default
            });
            L.tileLayer.provider(baseData.providerName, baseData.providerOptions).addTo(map);
            L.control.zoom({ // Add zoom with localised text
                zoomInTitle: <?= json_encode(I18N::translate('Zoom in')) ?>,
                zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>,
            }).addTo(map);
        };

        let _addLayer = function () {
            let geoJsonLayer;
            let data = <?= json_encode($data['markers']) ?>;

            if (data.features.length === 1) {
                zoom = data.features[0].properties.zoom;
            }
            geoJsonLayer = L.geoJson(data, {
                pointToLayer: function (feature, latlng) {
                    return new L.Marker(latlng, {
                        icon:  L.BeautifyIcon.icon({
                            icon: 'bullseye fas',
                            borderColor: "transparent",
                            backgroundColor: '#1e90ff',
                            iconShape: "marker",
                            textColor: "white",
                        }),
                        title: feature.properties.tooltip,
                        alt: feature.properties.tooltip,
                        id: feature.id,
                    })
                        .on("popupopen", function (e) {
                            let item = sidebar.children(".mapped[data-id=" + e.target.feature.id + "]");
                            item.addClass("messagebox");
                            sidebar.scrollTo(item);
                        })
                        .on("popupclose", function () {
                            sidebar.children(".mapped")
                                .removeClass("messagebox");
                        });
                },
                onEachFeature: function (feature, layer) {
                    layer.bindPopup(feature.properties.popup);
                },
            });

            if (data.features.length > 0) {
                markers.addLayer(geoJsonLayer);
                map
                    .addControl(new resetControl())
                    .addLayer(markers)
                    .fitBounds(markers.getBounds().pad(0.2));
                if (zoom) {
                    map.setView(markers.getBounds().getCenter(), zoom);
                }
            } else {
                map.fitWorld();
            }
            sidebar.append(<?= json_encode($data['sidebar']) ?>);
        };

        /**
         *
         * @param elem
         * @returns {$}
         */

        $.fn.scrollTo = function (elem) {
            let _this = $(this);
            _this.animate({
                scrollTop: elem.offset().top - _this.offset().top + _this.scrollTop(),
            });
            return this;
        };

        /**
         * @private
         */
        let _initialize = function () {
            // Activate marker popup when sidebar entry clicked
            $(function () {
               sidebar
                // open marker popup if sidebar event is clicked
                    .on("click", ".mapped", function (e) {
                        // first close any existing
                        map.closePopup();
                        let eventId = $(this).data("id");
                        //find the marker corresponding to the clicked event
                        let mkrLayer = markers.getLayers().filter(function (v) {
                            return typeof (v.feature) !== "undefined" && v.feature.id === eventId;
                        });
                        let mkr = mkrLayer.pop();
                        // Unfortunately zoomToShowLayer zooms to maxZoom
                        // when all marker in a cluster have exactly the
                        // same co-ordinates
                        markers.zoomToShowLayer(mkr, function (e) {
                            mkr.openPopup();
                        });
                        return false;
                    })
                    .on("click", "a", function (e) { // stop click on a person also opening the popup
                        e.stopPropagation();
                    });
            });

            _drawMap();
            _addLayer();
        };

        return {
            drawMap: function () {
                _initialize();
            },
        };
    })();

    WT_OSM.drawMap();
</script>
<?php View::endpush() ?>
