<?php include '../nav/top.php';?>
<title>Highlights</title>
<meta name="description" content="Highlights of trips and travels by radlfahrer">
<?php include '../nav/headpages.php';?>
<?php include '../includes/trips_merged.php'; ?>
<?php include '../includes/trip_sort.php'; ?>

<?php
if (!function_exists('h')) {
  function h($s): string {
    return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8');
  }
}

$highlightSections = [
  '01' => [
    'title' => 'Outside Europe',
    'region_key' => 'outside-europe',
    'heading_class' => 'w3-text-red',
    'button_class' => 'w3-theme-red',
    'banner_class' => 'bgimg-6',
  ],
  '02' => [
    'title' => 'Alps',
    'region_key' => 'alps',
    'heading_class' => 'w3-text-green',
    'button_class' => 'w3-theme-green',
    'banner_class' => 'bgimg-3',
  ],
  '03' => [
    'title' => 'Northern Europe',
    'region_key' => 'northern-europe',
    'heading_class' => 'w3-text-brown',
    'button_class' => 'w3-theme-brown',
    'banner_class' => 'bgimg-2',
  ],
  '04' => [
    'title' => 'Southern Europe',
    'region_key' => 'southern-europe',
    'heading_class' => 'w3-text-blue',
    'button_class' => 'w3-theme-blue',
    'banner_class' => 'bgimg-4',
  ],
  '05' => [
    'title' => 'France',
    'region_key' => 'france',
    'heading_class' => 'w3-text-dyellow',
    'button_class' => 'w3-theme-dyellow',
    'banner_class' => 'bgimg-1',
  ],
  '06' => [
    'title' => 'Germany & Eastern Europe',
    'region_key' => 'germany-eastern-europe',
    'heading_class' => 'w3-text-dark-grey',
    'button_class' => 'w3-dark-grey',
    'banner_class' => 'bgimg-5',
  ],
];

function buildHighlightTripsBySection(array $allTrips, array $sections): array {
  $result = [];

  foreach ($sections as $anchor => $section) {
    $regionKey = $section['region_key'];
    $result[$anchor] = [];

    foreach ($allTrips as $trip) {
      if (!is_array($trip)) continue;
      if (empty($trip['highlight'])) continue;
      if (($trip['status'] ?? 'published') !== 'published') continue;
      if (empty($trip['url']) || empty($trip['title'])) continue;

      $regions = $trip['regions'] ?? [];

      if (!is_array($regions) || !in_array($regionKey, $regions, true)) {
        continue;
      }

      $result[$anchor][] = $trip;
    }

    usort($result[$anchor], 'trip_sort_cmp');
  }

  return $result;
}

function renderHighlightCard(array $trip, string $headingClass): void {
  $url   = $trip['url'] ?? '#';
  $img   = $trip['img'] ?? '';
  $title = trim((string)($trip['landing_title'] ?? $trip['title'] ?? 'Untitled'));
  $desc  = trim((string)($trip['desc'] ?? ''));
  $year  = trim((string)($trip['year'] ?? ''));

  ?>
  <a class="pic-card w3-round" href="<?= h($url) ?>">
    <?php if ($img): ?>
      <img
        alt="<?= h($title) ?>"
        class="pic-img w3-hover-grayscale"
        src="<?= h($img) ?>"
        loading="lazy"
      />
    <?php endif; ?>

    <div class="pic-card-body">
      <h4 class="<?= h($headingClass) ?>"><?= h($title) ?></h4>

      <?php if ($year): ?>
        <div class="pic-meta"><?= h($year) ?></div>
      <?php endif; ?>

      <?php if ($desc): ?>
        <p><?= h($desc) ?></p>
      <?php else: ?>
        <p>Open the travel report to read more about this route.</p>
      <?php endif; ?>

      <div class="pic-cta">
        Read travel report <i class="fas fa-external-link-alt"></i>
      </div>
    </div>
  </a>
  <?php
}

$highlightTripsBySection = buildHighlightTripsBySection($all_trips, $highlightSections);

$totalHighlights = array_sum(array_map('count', $highlightTripsBySection));

$highlightTripsForMap = array_values(array_filter($all_trips, function ($trip) {
  return is_array($trip)
    && !empty($trip['highlight'])
    && (($trip['status'] ?? 'published') === 'published')
    && !empty($trip['url']);
}));
?>

<style>

:root {
  --top-nav-height: 50px;
  --region-nav-offset: calc(var(--top-nav-height) + 8px);
}

:root {
  --blue: #336699;
  --blue-light: #eaf3ff;
  --blue-lighter: #f6f9ff;
  --blue-border: #cfe0f5;
  --text-muted: #667085;
  --shadow: 0 2px 10px rgba(51, 102, 153, 0.10);
  --shadow-hover: 0 8px 24px rgba(51, 102, 153, 0.16);
}

* {
  box-sizing: border-box;
}

.highlight-page {
  max-width: 1400px;
  margin: 0 auto;
}

.highlight-intro {
  padding: 16px 0 8px;
}

.highlight-intro h1 {
  margin-bottom: 8px;
}

.highlight-intro-text {
  max-width: 920px;
  color: var(--text-muted);
  line-height: 1.55;
}

.highlight-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px 0 18px;
}

.highlight-summary span {
  background: var(--blue-lighter);
  border: 1px solid var(--blue-border);
  color: var(--blue);
  border-radius: 999px;
  padding: 7px 13px;
  font-weight: 700;
  font-size: 0.95rem;
}

.highlight-map-panel {
  border: 1px solid var(--blue-border);
  border-radius: 14px;
  background: #fff;
  box-shadow: var(--shadow);
  padding: 12px;
  margin-bottom: 18px;
}

.highlight-map-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.highlight-map-control-left,
.highlight-map-control-right {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.highlight-map-note {
  color: var(--text-muted);
  font-size: 0.9rem;
}

.highlight-map-status {
  color: var(--text-muted);
  font-size: 0.86rem;
}

#map-world {
  width: 100%;
  height: 620px;
  border-radius: 12px;
  overflow: hidden;
  background: #eef5ff;
}

.highlight-region-nav {
  position: sticky;
  top: var(--region-nav-offset);
  z-index: 4;
  background: rgba(255,255,255,0.94);
  backdrop-filter: blur(6px);
  border: 1px solid var(--blue-border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 8px;
  margin: 18px 0 24px;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.highlight-region-nav a,
.highlight-region-nav button {
  text-decoration: none;
}

.highlight-region-nav button {
  border-radius: 8px;
}

.section-anchor {
  scroll-margin-top: 160px;
}

.gallery {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 18px;
  margin-bottom: 28px;
}

.pic-card {
  display: flex;
  flex-direction: column;
  width: 320px;
  min-height: 430px;
  border: 1px solid #d8e1ec;
  background: #fff;
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  box-shadow: 0 1px 5px rgba(0,0,0,0.06);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.pic-card:link,
.pic-card:visited {
  text-decoration: none;
  color: inherit;
}

.pic-card:hover {
  background: #f8fbff;
  transform: translateY(-2px);
  box-shadow: var(--shadow-hover);
  text-decoration: none;
}

.pic-card img {
  width: 100%;
  height: 210px;
  object-fit: cover;
  display: block;
}

.pic-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 12px 14px 14px;
}

.pic-card h4 {
  margin: 0 0 6px;
  line-height: 1.28;
  font-weight: 700;
}

.pic-meta {
  display: inline-block;
  align-self: flex-start;
  margin-bottom: 8px;
  font-size: 0.84rem;
  color: var(--blue);
  background: var(--blue-lighter);
  border: 1px solid var(--blue-border);
  border-radius: 999px;
  padding: 3px 9px;
  font-weight: 700;
}

.pic-card p {
  margin: 0 0 12px;
  line-height: 1.45;
  color: #243b53;
}

.pic-cta {
  margin-top: auto;
  color: var(--blue);
  font-weight: 700;
  font-size: 0.92rem;
}

/* Map popup for highlighted GPX routes */
.highlight-map-popup {
  width: 260px;
}

.highlight-map-popup img {
  width: 100%;
  display: block;
  border-radius: 8px;
  margin-bottom: 8px;
}

.highlight-map-popup-title {
  font-weight: 700;
  color: var(--blue);
  font-size: 1rem;
  line-height: 1.25;
  margin-bottom: 5px;
}

.highlight-map-popup-year {
  display: inline-block;
  background: var(--blue-light);
  color: var(--blue);
  border: 1px solid var(--blue-border);
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 0.78rem;
  margin-bottom: 7px;
  font-weight: 700;
}

.highlight-map-popup-desc {
  font-size: 0.86rem;
  color: #243b53;
  line-height: 1.35;
  margin-bottom: 8px;
}

.highlight-map-popup-link {
  font-weight: 700;
  color: var(--blue);
}

/* Country/Alps tooltips */
.alps-tooltip {
  background: rgba(51, 153, 102, 0.85);
  color: white;
  font-weight: bold;
  border: none;
  padding: 4px 8px;
  border-radius: 4px;
}

.country-tooltip {
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  font-weight: bold;
  border: none;
  padding: 4px 8px;
  border-radius: 4px;
  text-align: center;
}

.leaflet-interactive:focus {
  outline: none;
}

/* Scenic banners */
.bgimg-1,
.bgimg-2,
.bgimg-3,
.bgimg-4,
.bgimg-5,
.bgimg-6 {
  background-attachment: fixed;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-size: 100% auto;
  min-height: 760px;
  border-radius: 2px;
  margin: 28px 0 0;
}

.bgimg-1 {
  background-image: url('/images/covers/hero/20130518-073850_dxo.webp');
}

.bgimg-2 {
  background-image: url("/images/covers/hero/20130801-131441_dxo.webp");
}

.bgimg-3 {
  background-image: url("/images/covers/hero/20150711-180721_dxo.webp");
}

.bgimg-4 {
  background-image: url("/images/covers/hero/dsc03746_dxo.webp");
}

.bgimg-5 {
  background-image: url("/images/covers/hero/dsc03968_dxo.webp");
}

.bgimg-6 {
  background-image: url("/images/covers/hero/p1080698_dxo.webp");
}

.banner-title {
  background: rgba(0,0,0,0.30);
  padding: 12px 20px;
  border-radius: 8px;
  text-align: center;
}

.w3-wide {
  letter-spacing: 10px;
}

.w3-hover-opacity {
  cursor: pointer;
}

.empty-section {
  color: var(--text-muted);
  background: #f8fbff;
  border: 1px dashed var(--blue-border);
  border-radius: 10px;
  padding: 16px;
}

/* Existing site navbar helpers */
.w3-sidebar {
  z-index: 3;
  width: 300px;
  top: 50px;
  bottom: 24px;
  height: inherit;
}

.w3-bar {
  z-index: 3;
  max-width: 1400px;
}

@media (max-width: 900px) {
  .section-anchor {
    scroll-margin-top: 190px;
  }
}

@media (max-width: 900px) {
  #map-world {
    height: 430px;
  }

  .bgimg-1,
  .bgimg-2,
  .bgimg-3,
  .bgimg-4,
  .bgimg-5,
  .bgimg-6 {
    min-height: 420px;
    background-attachment: scroll;
  }

  .w3-wide {
    letter-spacing: 5px;
  }

  .pic-card {
    width: calc(50% - 10px);
  }
}

@media (max-width: 560px) {
  #map-world {
    height: 300px;
  }

  .pic-card {
    width: 100%;
  }

  .highlight-map-controls {
    align-items: stretch;
  }

  .highlight-map-control-left,
  .highlight-map-control-right {
    width: 100%;
  }

  .highlight-map-controls button {
    width: 100%;
  }

  .bgimg-1,
  .bgimg-2,
  .bgimg-3,
  .bgimg-4,
  .bgimg-5,
  .bgimg-6 {
    min-height: 300px;
  }
}
</style>

<div class="highlight-page w3-padding">

  <section class="highlight-intro">
    <h1 class="w3-text-blue">
      <i class="fas fa-star"></i>
      Highlights
    </h1>

    <p class="w3-large w3-text-grey">
      A personal selection of favourite cycling trips, hikes and journeys — grouped by region.
      The map shows countries I have visited. Where GPX tracks are available, selected highlight
      routes can also be displayed directly on the map.
    </p>
    <!--
    <div class="highlight-summary">
      <span><?= h($totalHighlights) ?> highlighted trips</span>
      <span><?= h(count($highlightSections)) ?> regions</span>
      <span>Visited countries map</span>
      <span>Optional GPX highlight routes</span>
    </div>
    -->
  </section>

  <section class="highlight-map-panel">
    <div class="highlight-map-controls">
      <div class="highlight-map-control-left">
        <button id="toggle-highlight-routes" type="button" class="w3-button w3-theme w3-round">
          Hide highlight routes
        </button>

        <button id="reset-world-map" type="button" class="w3-button w3-light-grey w3-round">
          Reset world map
        </button>
      </div>

      <div class="highlight-map-control-right">
        <span id="highlight-route-status" class="highlight-map-status">
          Loading highlight routes…
        </span>
      </div>
    </div>

    <div id="map-world"></div>

    <p class="highlight-map-note">
      Click countries or highlighted routes for more information. Region buttons below also filter the highlighted GPX routes.
    </p>
  </section>

  <nav class="highlight-region-nav" aria-label="Highlight regions">
    <?php foreach ($highlightSections as $anchor => $section): ?>
      <a href="#<?= h($anchor) ?>">
        <button
          type="button"
          class="w3-button <?= h($section['button_class']) ?>"
          data-region-key="<?= h($section['region_key']) ?>"
        >
          <?= h($section['title']) ?>
        </button>
      </a>
    <?php endforeach; ?>
  </nav>

  <?php foreach ($highlightSections as $anchor => $section): ?>
    <section class="highlight-section">
      <div class="<?= h($section['banner_class']) ?> w3-display-container">
        <div class="w3-display-middle banner-title">
          <span class="w3-xxlarge w3-text-white w3-wide">
            <?= h(mb_strtoupper($section['title'])) ?>
          </span>
        </div>
      </div>

      <hr id="<?= h($anchor) ?>" class="section-anchor">

      <h2 class="<?= h($section['heading_class']) ?>">
        <?= h($section['title']) ?>
      </h2>

      <div class="gallery">
        <?php if (!empty($highlightTripsBySection[$anchor])): ?>
          <?php foreach ($highlightTripsBySection[$anchor] as $trip): ?>
            <?php renderHighlightCard($trip, $section['heading_class']); ?>
          <?php endforeach; ?>
        <?php else: ?>
          <div class="empty-section">
            No highlighted trips in this section yet.
          </div>
        <?php endif; ?>
      </div>
    </section>
  <?php endforeach; ?>

</div>

<script>
const highlightTripsInfo = <?php
  echo json_encode($highlightTripsForMap, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
?>;

const highlightInfoByUrl = {};
const highlightInfoByTitle = {};

highlightTripsInfo.forEach(function (trip) {
  const urlKey = normalizeUrlPath(trip.url);

  if (urlKey) {
    highlightInfoByUrl[urlKey] = trip;
  }

  const titleKey = normalizeTitle(trip.title || trip.landing_title || '');

  if (titleKey) {
    highlightInfoByTitle[titleKey] = trip;
  }
});

const regionLabels = <?php
  $regionLabels = [];
  foreach ($highlightSections as $section) {
    $regionLabels[$section['region_key']] = $section['title'];
  }
  echo json_encode($regionLabels, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
?>;

function pickWorldZoom() {
  const w = window.innerWidth;
  const h = window.innerHeight;

  if (w < 500 || w / h < 0.7) return 1;
  if (w < 800) return 1.25;

  return 2;
}

const worldMap = L.map('map-world', {
  zoomSnap: 0.25,
  zoomDelta: 0.25,
  scrollWheelZoom: false
}).setView([20, 0], pickWorldZoom());

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  maxZoom: 19,
  attribution: '&copy; OpenStreetMap contributors'
}).addTo(worldMap);

const highlightRouteLayer = L.layerGroup().addTo(worldMap);
const highlightRouteItems = [];

let highlightRoutesVisible = true;
let activeRouteRegion = null;

const visitedCountriesData = [
  { "iso_a3": "ARG", "name": "Argentina", "link": "../2023/patagonia.php", "color": "#99334d" },
  { "iso_a3": "BEL", "name": "Belgium", "link": "#03", "color": "#995a33" },
  { "iso_a3": "CHL", "name": "Chile", "link": "../2023/patagonia.php", "color": "#99334d" },
  { "iso_a3": "DNK", "name": "Denmark", "link": "#03", "color": "#995a33" },
  { "iso_a3": "DEU", "name": "Germany", "link": "#06", "color": "#616161" },
  { "iso_a3": "EST", "name": "Estonia", "link": "#03", "color": "#995a33" },
  { "iso_a3": "FIN", "name": "Finland", "link": "#03", "color": "#995a33" },
  { "iso_a3": "FRA", "name": "France", "link": "#05", "color": "#eab308" },
  { "iso_a3": "GRC", "name": "Greece", "link": "../2004/antalyamuenchen.php", "color": "#336699" },
  { "iso_a3": "GBR", "name": "United Kingdom of Great Britain and Northern Ireland", "link": "#03", "color": "#995a33" },
  { "iso_a3": "IRN", "name": "Iran", "link": "../2017/iran.php", "color": "#99334d" },
  { "iso_a3": "IRL", "name": "Ireland", "link": "#03", "color": "#995a33" },
  { "iso_a3": "ISL", "name": "Iceland", "link": "../2013/island2013.php", "color": "#995a33" },
  { "iso_a3": "ITA", "name": "Italy", "link": "#04", "color": "#336699" },
  { "iso_a3": "CAN", "name": "Canada", "link": "../1999/von-vancouver-nach-new-york.php", "color": "#99334d" },
  { "iso_a3": "LIE", "name": "Liechtenstein", "link": "#02", "color": "#339966" },
  { "iso_a3": "LTU", "name": "Lithuania", "link": "#03", "color": "#995a33" },
  { "iso_a3": "LUX", "name": "Luxembourg", "link": "#03", "color": "#995a33" },
  { "iso_a3": "LVA", "name": "Latvia", "link": "#03", "color": "#995a33" },
  { "iso_a3": "MCO", "name": "Monaco", "link": "#05", "color": "#eab308" },
  {
    "iso_a3": "NPL",
    "name": "Nepal",
    "color": "#99334d",
    "trips": [
      { "title": "Annapurna Circuit 2019", "link": "../2019/annapurna.php" },
      { "title": "Three Passes Trek 2019", "link": "../2019/everest.php" }
    ]
  },
  {
    "iso_a3": "NZL",
    "name": "New Zealand",
    "color": "#99334d",
    "center": [-41.3, 173.0],
    "zoom": 5,
    "trips": [
      { "title": "New Zealand 2015/16", "link": "../2016/nz01_auckland.php" },
      { "title": "New Zealand 2011/12", "link": "../2011/nz.php" }
    ]
  },
  { "iso_a3": "NLD", "name": "Netherlands", "link": "#03", "color": "#995a33" },
  { "iso_a3": "NOR", "name": "Norway", "link": "#03", "color": "#995a33" },
  { "iso_a3": "AUT", "name": "Austria", "link": "#02", "color": "#339966" },
  { "iso_a3": "POL", "name": "Poland", "link": "#06", "color": "#616161" },
  { "iso_a3": "PRT", "name": "Portugal", "link": "#04", "color": "#336699" },
  { "iso_a3": "SWE", "name": "Sweden", "link": "#03", "color": "#995a33" },
  { "iso_a3": "CHE", "name": "Switzerland", "link": "#02", "color": "#339966" },
  { "iso_a3": "SVN", "name": "Slovenia", "link": "#02", "color": "#339966" },
  { "iso_a3": "ESP", "name": "Spain", "link": "#04", "color": "#336699" },
  { "iso_a3": "TJK", "name": "Tajikistan", "link": "../2018/pamir.php", "color": "#99334d" },
  { "iso_a3": "CZE", "name": "Czechia", "link": "#06", "color": "#616161" },
  { "iso_a3": "TZA", "name": "Tanzania", "link": "../2008/tansania-kilimanjaro-sansibar.php", "color": "#99334d" },
  { "iso_a3": "TUR", "name": "Türkiye", "link": "../2004/antalyamuenchen.php", "color": "#336699" },
  { "iso_a3": "VAT", "name": "Vatican", "link": "#04", "color": "#336699" },
  { "iso_a3": "USA", "name": "United States of America", "link": "../1999/von-vancouver-nach-new-york.php", "color": "#99334d" }
];

const visitedCountries = {};

visitedCountriesData.forEach(function (country) {
  visitedCountries[country.iso_a3] = country;
});

loadVisitedCountries();
loadAlpsOverlay();
loadHighlightRoutes();
bindHighlightControls();

function loadVisitedCountries() {
  fetch('countries.geojson')
    .then(function (res) {
      return res.json();
    })
    .then(function (geoData) {
      L.geoJSON(geoData, {
        style: function (feature) {
          const isoCode = getFeatureIso(feature);
          const countryInfo = visitedCountries[isoCode];

          if (countryInfo) {
            return {
              color: '#333',
              weight: 1,
              fillColor: countryInfo.color,
              fillOpacity: 0.70
            };
          }

          return {
            color: '#888',
            weight: 1,
            fillOpacity: 0
          };
        },

        onEachFeature: function (feature, layer) {
          const isoCode = getFeatureIso(feature);
          const countryInfo = visitedCountries[isoCode];

          const tooltipText = countryInfo
            ? countryInfo.name
            : feature.properties.name;

          if (tooltipText) {
            layer.bindTooltip(tooltipText, {
              permanent: false,
              direction: 'center',
              className: 'country-tooltip'
            });
          }

          layer.on('mouseover', function () {
            layer.setStyle({
              weight: 2,
              fillOpacity: countryInfo ? 0.85 : 0.12
            });

            if (typeof layer.bringToFront === 'function') {
              layer.bringToFront();
            }
          });

          layer.on('mouseout', function () {
            if (countryInfo) {
              layer.setStyle({
                weight: 1,
                fillOpacity: 0.70,
                fillColor: countryInfo.color,
                color: '#333'
              });
            } else {
              layer.setStyle({
                weight: 1,
                fillOpacity: 0,
                color: '#888'
              });
            }
          });

          layer.on('click', function () {
            if (!countryInfo) {
              worldMap.fitBounds(layer.getBounds(), {
                padding: [20, 20]
              });
              return;
            }

            if (countryInfo.center && countryInfo.zoom) {
              worldMap.setView(countryInfo.center, countryInfo.zoom);
            } else {
              worldMap.fitBounds(layer.getBounds(), {
                padding: [20, 20]
              });
            }

            setTimeout(function () {
              layer.bindPopup(buildCountryPopup(countryInfo)).openPopup();
            }, 350);
          });
        }
      }).addTo(worldMap);
    })
    .catch(function (err) {
      console.error('Could not load countries.geojson:', err);
    });
}

function loadAlpsOverlay() {
  fetch('alps.geojson')
    .then(function (res) {
      return res.json();
    })
    .then(function (data) {
      L.geoJSON(data, {
        style: {
          color: 'green',
          weight: 2,
          fillColor: '#339966',
          fillOpacity: 0.70
        },

        onEachFeature: function (feature, layer) {
          layer.bindTooltip('Alps', {
            permanent: false,
            direction: 'center',
            className: 'alps-tooltip'
          });

          layer.on('mouseover', function () {
            layer.setStyle({
              weight: 3,
              fillOpacity: 0.90
            });
          });

          layer.on('mouseout', function () {
            layer.setStyle({
              weight: 2,
              fillOpacity: 0.70
            });
          });

          layer.on('click', function () {
            activeRouteRegion = 'alps';
            filterHighlightRoutes();

            const section = document.getElementById('02');

            if (section) {
              section.scrollIntoView({
                behavior: 'smooth',
                block: 'start'
              });
            }
          });
        }
      }).addTo(worldMap);
    })
    .catch(function (err) {
      console.warn('Could not load alps.geojson:', err);
    });
}

function loadHighlightRoutes() {
  const statusEl = document.getElementById('highlight-route-status');

  if (typeof L.GPX === 'undefined') {
    if (statusEl) {
      statusEl.textContent = 'GPX plugin not loaded.';
    }

    console.warn('Leaflet GPX plugin is not loaded.');
    return;
  }

  const sources = [
    '/includes/trips_overview_eu.json',
    '/includes/trips_overview_local.json',
    '/includes/trips_overview_nz.json',
    '/includes/trips_overview_na.json',
    '/includes/trips_overview_sa.json',

    // Extra highlight regions not included in the overview maps
  '/includes/trips_explorer_iran.json',
  '/includes/trips_explorer_nepal.json',
  '/includes/trips_explorer_pamir.json'
  ];

  Promise.all(
    sources.map(function (path) {
      return fetch(path)
        .then(function (res) {
          if (!res.ok) {
            throw new Error('HTTP ' + res.status + ' for ' + path);
          }

          return res.json();
        })
        .catch(function (err) {
          console.warn('Could not load route source:', path, err);
          return [];
        });
    })
  )
  .then(function (lists) {
    const routes = lists.flat();
    let added = 0;

    const seenRoutes = new Set();

    routes.forEach(function (route) {
      const info = findHighlightInfoForRoute(route);

      if (!info || !route.file) return;

      const routeKey =
        normalizeUrlPath(route.link) ||
        normalizeTitle(route.name || '') ||
        route.file;

      if (seenRoutes.has(routeKey)) return;

      seenRoutes.add(routeKey);

      addHighlightGpxRoute(route, info);
      added++;
    });

    if (statusEl) {
      statusEl.textContent = added
        ? added + ' highlight routes loaded.'
        : 'No highlight routes matched GPX files.';
    }
  });
}

function addHighlightGpxRoute(route, info) {
  const color = route.color || '#336699';

  const item = {
    route,
    info,
    color,
    regions: Array.isArray(info.regions) ? info.regions : [],
    lines: [],
    layer: null
  };

  const gpxLayer = new L.GPX(route.file, {
    async: true,

    markers: {
      startIcon: false,
      endIcon: false,
      wptIcons: {}
    },

    marker_options: {
      startIconUrl: '',
      endIconUrl: '',
      shadowUrl: '',
      wptIconUrls: {}
    },

    gpx_options: {
      parseElements: ['track']
    },

    polyline_options: {
      color: color,
      opacity: 0.82,
      weight: 3
    }
  });

  item.layer = gpxLayer;

  gpxLayer.on('loaded', function (e) {
    removeGpxMarkers(e.target);
  });

  gpxLayer.on('addline', function (e) {
    const line = e.line;

    item.lines.push(line);

    line.setStyle({
      color: color,
      opacity: 0.82,
      weight: 3
    });

    line.bindPopup(buildHighlightRoutePopup(route, info), {
      maxWidth: 300
    });

    line.on('mouseover', function () {
      line.setStyle({
        weight: 6,
        opacity: 1
      });

      if (typeof line.bringToFront === 'function') {
        line.bringToFront();
      }
    });

    line.on('mouseout', function () {
      applyRouteLineStyle(item);
    });
  });

  gpxLayer.on('error', function () {
    console.warn('Could not load GPX:', route.file);
  });

  highlightRouteItems.push(item);
  gpxLayer.addTo(highlightRouteLayer);
}

function bindHighlightControls() {
  const toggleBtn = document.getElementById('toggle-highlight-routes');
  const resetMapBtn = document.getElementById('reset-world-map');

  if (toggleBtn) {
    toggleBtn.addEventListener('click', function () {
      highlightRoutesVisible = !highlightRoutesVisible;

      if (highlightRoutesVisible) {
        highlightRouteLayer.addTo(worldMap);
        toggleBtn.textContent = 'Hide highlight routes';
      } else {
        worldMap.removeLayer(highlightRouteLayer);
        toggleBtn.textContent = 'Show highlight routes';
      }
    });
  }

if (resetMapBtn) {
  resetMapBtn.addEventListener('click', function () {
    resetWorldMap();
  });
}

  document.querySelectorAll('.highlight-region-nav button[data-region-key]').forEach(function (btn) {
    btn.addEventListener('click', function () {
      activeRouteRegion = btn.dataset.regionKey || null;
      filterHighlightRoutes();

      document.querySelectorAll('.highlight-region-nav button').forEach(function (other) {
        other.classList.remove('w3-border', 'w3-border-blue');
      });

      btn.classList.add('w3-border', 'w3-border-blue');
    });
  });

  window.addEventListener('resize', function () {
    worldMap.invalidateSize();
  });
}

function resetWorldMap() {
  activeRouteRegion = null;
  filterHighlightRoutes();

  document.querySelectorAll('.highlight-region-nav button').forEach(function (btn) {
    btn.classList.remove('w3-border', 'w3-border-blue');
  });

  worldMap.closePopup();

  worldMap.setView([20, 0], pickWorldZoom(), {
    animate: true
  });

  setTimeout(function () {
    worldMap.invalidateSize();
  }, 250);
}

function filterHighlightRoutes() {
  highlightRouteItems.forEach(function (item) {
    applyRouteLineStyle(item);
  });

  const statusEl = document.getElementById('highlight-route-status');

  if (statusEl && activeRouteRegion) {
    statusEl.textContent = 'Filtered routes: ' + (regionLabels[activeRouteRegion] || activeRouteRegion);
  } else if (statusEl) {
    statusEl.textContent = highlightRouteItems.length + ' highlight routes loaded.';
  }
}

function applyRouteLineStyle(item) {
  const matches = !activeRouteRegion || item.regions.includes(activeRouteRegion);

  item.lines.forEach(function (line) {
    line.setStyle({
      color: item.color,
      opacity: matches ? 0.86 : 0.18,
      weight: matches ? 3 : 2
    });

    if (matches && typeof line.bringToFront === 'function') {
      line.bringToFront();
    }
  });
}

function findHighlightInfoForRoute(route) {
  const urlKey = normalizeUrlPath(route.link);

  if (urlKey && highlightInfoByUrl[urlKey]) {
    return highlightInfoByUrl[urlKey];
  }

  const titleKey = normalizeTitle(route.name || '');

  if (titleKey && highlightInfoByTitle[titleKey]) {
    return highlightInfoByTitle[titleKey];
  }

  return null;
}

function buildCountryPopup(countryInfo) {
  let html = '<strong>' + escapeHtml(countryInfo.name) + '</strong>';

  if (Array.isArray(countryInfo.trips) && countryInfo.trips.length) {
    html += '<br>';

    countryInfo.trips.forEach(function (trip) {
      html += '<a href="' + escapeHtml(trip.link) + '">' +
        escapeHtml(trip.title) +
        '</a><br>';
    });

    return html;
  }

  if (countryInfo.link) {
    const label = countryInfo.link.startsWith('#')
      ? 'Go to section'
      : 'Open travel report';

    html += '<br><a href="' + escapeHtml(countryInfo.link) + '">' +
      escapeHtml(label) +
      '</a>';
  }

  return html;
}

function buildHighlightRoutePopup(route, info) {
  const title = info.landing_title || info.title || route.name || 'Untitled trip';
  const desc = shortText(
    info.desc || 'Open the travel report to read more about this route.',
    190
  );

  const url = info.url || route.link || '#';

  return `
    <div class="highlight-map-popup">
      ${
        info.img
          ? `<a href="${escapeHtml(url)}">
               <img src="${escapeHtml(info.img)}" alt="${escapeHtml(title)}">
             </a>`
          : ''
      }

      <div class="highlight-map-popup-title">
        ${escapeHtml(title)}
      </div>

      ${
        info.year
          ? `<div class="highlight-map-popup-year">${escapeHtml(info.year)}</div>`
          : ''
      }

      <div class="highlight-map-popup-desc">
        ${escapeHtml(desc)}
      </div>

      <a class="highlight-map-popup-link" href="${escapeHtml(url)}">
        Travel Report <i class="fas fa-external-link-alt"></i>
      </a>
    </div>
  `;
}

function getFeatureIso(feature) {
  const props = feature && feature.properties ? feature.properties : {};

  return props.gu_a3 ||
    props.iso_a3 ||
    props.ISO_A3 ||
    props.ADM0_A3 ||
    props.adm0_a3 ||
    '';
}

function normalizeUrlPath(url) {
  if (!url) return '';

  let s = String(url).replace(/\\/g, '/').trim();

  s = s.split('#')[0].split('?')[0];

  if (/^https?:\/\//i.test(s)) {
    try {
      s = new URL(s).pathname;
    } catch (e) {}
  }

  if (s.startsWith('../')) {
    s = '/' + s.substring(3).replace(/^\/+/, '');
  } else if (!s.startsWith('/')) {
    s = '/' + s.replace(/^\/+/, '');
  }

  s = s.replace(/\/index\.(php|html?)$/i, '');
  s = s.replace(/\/+$/, '');

  return s;
}

function normalizeTitle(title) {
  return String(title || '')
    .toLowerCase()
    .replace(/&amp;/g, '&')
    .replace(/[^a-z0-9äöüß]+/gi, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

function shortText(str, maxLength) {
  const text = String(str || '').replace(/\s+/g, ' ').trim();

  if (!text || text.length <= maxLength) {
    return text;
  }

  return text.substring(0, maxLength - 1).trim() + '…';
}

function escapeHtml(str) {
  return String(str || '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

function removeGpxMarkers(gpxLayer) {
  if (!gpxLayer || typeof gpxLayer.eachLayer !== 'function') return;

  const markersToRemove = [];

  gpxLayer.eachLayer(function (subLayer) {
    if (subLayer instanceof L.Marker) {
      markersToRemove.push(subLayer);
    }
  });

  markersToRemove.forEach(function (marker) {
    gpxLayer.removeLayer(marker);
  });
}
</script>

<div class="w3-row w3-padding-16 w3-large">
  <footer class="w3-center w3-padding-16 w3-opacity w3-hover-opacity-off">
    <p class="w3-text-blue">
      <b><a href="https://www.radlfahrer.de">radlfahrer.de</a></b>
      &nbsp;&nbsp;
      <i class="far fa-copyright"></i>
      &nbsp;1991-<?php echo date("Y"); ?>
    </p>

    <p class="w3-text-blue">
      a blog about bicycle touring<br>
      <a href="impressum.php">Impressum/Imprint</a><br>
      <a href="datenschutz.php">Datenschutz/privacy policy</a>
    </p>
  </footer>
</div>

<?php include '../nav/tail.php';?>
