<?php

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

/**
 * @var array<mixed> $data
 * @var array<mixed> $provider
 */

?>

<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>
    "use strict";

    window.WT_OSM = (function () {
        const minZoom = 2;

        let map      = null;
        let zoom     = null;
        let sidebar  = $('.osm-sidebar');
        let provider = <?= json_encode($provider) ?>;

        // Map components
        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('Reload map')) ?>;
                anchor.setAttribute('aria-label', reset);
                anchor.href  = "#";
                anchor.title = reset;
                anchor.role  = "button";
                let image    = L.DomUtil.create("i", "fas fa-redo", anchor);
                image.alt    = reset;

                return container;
            },
        });

        // Zoom control with localised text
        let newZoomControl = new L.control.zoom({
            zoomInTitle : <?= json_encode(I18N::translate('Zoom in')) ?>,
            zoomOutTitle: <?= json_encode(I18N::translate('Zoom out')) ?>,
        });

        /**
        *
        * @private
        */
        let _drawMap = function() {
            map = L.map('osm-map', {
                center     : [0, 0],
                minZoom    : minZoom,   // maxZoom set by leaflet-providers.js
                zoomControl: false,     // remove default
            })
            .addControl(new resetControl())
            .addControl(newZoomControl)
            .addLayer(L.tileLayer(provider.url, provider.options));
        };

        /**
        *
        * @private
        */
        let _buildMapData = function () {
            let data = <?= json_encode($data['markers']) ?>;

            let 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.addLayer(markers)
            }

            map.fitBounds(<?= json_encode($data['bounds']) ?>, {padding: [50, 30]});
            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;
        };

        // 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();
        _buildMapData();

    return "Leaflet map interface for webtrees-2";
    })();
</script>
<?php View::endpush() ?>
