import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import { util } from "@opentripplanner/base-map";
import React, { useEffect } from "react";
import { Layer, Source, useMap } from "react-map-gl/maplibre";
import polyline from "@mapbox/polyline";
import bbox from "@turf/bbox";
import { getRouteLayerLayout, patternToRouteFeature } from "./route-layers";
import { drawArc, getFromToAnchors, itineraryToTransitive } from "./util";
import routeArrow from "./images/route_arrow.png";
import capsule1 from "./images/01.png";
import capsule3 from "./images/03.png";
import capsule4 from "./images/04.png";
import capsule5 from "./images/05.png";
import capsule6 from "./images/06.png";
import capsule7 from "./images/07.png";
import capsule8 from "./images/08.png";
import capsule9 from "./images/09.png";
import capsule10 from "./images/10.png";
import capsule11 from "./images/11.png";
import capsule12 from "./images/12.png";
import capsule13 from "./images/13.png";
import capsule14 from "./images/14.png";
import capsule15 from "./images/15.png";
import capsule16 from "./images/16.png";
import capsule17 from "./images/17.png";
import rectangle from "./images/square.png";
var CAPSULES = {
  3: capsule3,
  4: capsule4,
  5: capsule5,
  6: capsule6,
  7: capsule7,
  8: capsule8,
  9: capsule9,
  10: capsule10,
  11: capsule11,
  12: capsule12,
  13: capsule13,
  14: capsule14,
  15: capsule15,
  16: capsule16,
  17: capsule17
};

// These are based on the sprites in the image folder
var WIDTH_IMAGE_SIZES = {
  6: 1283,
  7: 1450,
  8: 1617,
  9: 1783,
  10: 1950,
  11: 2117,
  12: 2283,
  13: 2450,
  14: 2617,
  15: 2783,
  16: 2950,
  17: 3117
};
var HEIGHT_IMAGE_SIZE = 533;
export { itineraryToTransitive };

// TODO: BETTER COLORS
var modeColorMap = {
  CAR: "#888",
  BICYCLE: "#f00",
  SCOOTER: "#f5a729",
  MICROMOBILITY: "#f5a729",
  MICROMOBILITY_RENT: "#f5a729",
  WALK: "#86cdf9"
};

/**
 * Apply a thin, white halo around the (black) text.
 */
var defaultTextPaintParams = {
  "text-halo-blur": 1,
  "text-halo-color": "#ffffff",
  "text-halo-width": 2
};

/**
 * Common text settings.
 */
var commonTextLayoutParams = {
  "symbol-placement": "point",
  "text-allow-overlap": false,
  "text-field": ["get", "name"],
  "text-justify": "auto",
  "text-radial-offset": 1,
  "text-size": 15
};

/**
 * Text size and layout that lets maplibre relocate text space permitting.
 */
var defaultTextLayoutParams = _objectSpread(_objectSpread({}, commonTextLayoutParams), {}, {
  "text-variable-anchor": ["left", "right", "top", "bottom", "top-left", "top-right", "bottom-left", "bottom-right"]
});

/**
 * Default text + bold default fonts
 */
var defaultBoldTextLayoutParams = _objectSpread(_objectSpread({}, commonTextLayoutParams), {}, {
  // FIXME: find a better way to set a bold font
  "text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
  "text-overlap": "never"
});
var routeFilter = ["==", "type", "route"];
var stopFilter = ["==", "type", "stop"];
var accessLegFilter = ["match", ["get", "type"], ["BICYCLE", "SCOOTER", "MICROMOBILITY", "MICROMOBILITY_RENT", "CAR"], true, false];
var loadImages = function loadImages(map, images) {
  images.forEach(function (img) {
    if (!map.hasImage(img.id)) {
      // Only load if the image hasn't already been added
      map.loadImage(img.url).then(function (response) {
        map.addImage(img.id, response.data, img.options);
      })["catch"](function (error) {
        // eslint-disable-next-line no-console
        console.error("Error loading image ".concat(img.id, ":"), error);
      });
    }
  });
};
var TransitiveCanvasOverlay = function TransitiveCanvasOverlay(_ref) {
  var activeLeg = _ref.activeLeg,
    accessLegColorOverride = _ref.accessLegColorOverride,
    _ref$boundsFitting = _ref.boundsFitting,
    boundsFitting = _ref$boundsFitting === void 0 ? true : _ref$boundsFitting,
    showRouteArrows = _ref.showRouteArrows,
    transitiveData = _ref.transitiveData;
  var _useMap = useMap(),
    map = _useMap.current;
  var mapImages = [];
  // This is used to render arrows along the route
  // Only load if that option is enabled to save the bandwidth
  if (showRouteArrows) {
    mapImages.push({
      id: "arrow-icon",
      url: routeArrow,
      options: {
        sdf: true
      }
    });
  }
  function generateCapsulePadding(width) {
    // Low widths have no padding
    if (!WIDTH_IMAGE_SIZES[width]) {
      return undefined;
    }

    // This could be more efficient, but this makes it very clear what is happening.
    // Higher widths require more padding
    var topPad = 0;
    if (width === 6) {
      topPad = 100;
    }
    if (width > 6) {
      topPad = 150;
    }
    if (width > 12) {
      topPad = 175;
    }

    // Each image has same height
    return [topPad, 0, WIDTH_IMAGE_SIZES[width] - topPad, HEIGHT_IMAGE_SIZE];
  }
  mapImages.push({
    id: "1",
    url: capsule1,
    options: {
      // These paddings are specifically set so that the circle appears circular
      // despite non-circular padding
      content: [0, 15, 500, 485],
      sdf: true
    }
  });
  mapImages.push({
    id: "2",
    url: capsule1,
    options: {
      // These paddings are specifically set so that the circle appears circular
      // despite non-circular padding
      content: [0, 40, 500, 460],
      sdf: true
    }
  });

  // Generate each capsule image from 3 - 17
  for (var i = 3; i < 18; i++) {
    mapImages.push({
      id: "".concat(i),
      url: CAPSULES[i],
      options: {
        content: generateCapsulePadding(i),
        sdf: true
      }
    });
  }
  mapImages.push({
    id: "rect",
    url: rectangle,
    options: {
      sdf: true
    }
  });
  useEffect(function () {
    loadImages(map, mapImages);
  }, []);
  var geojson = {
    type: "FeatureCollection",
    features: transitiveData ? [].concat(_toConsumableArray((transitiveData.places || []).flatMap(function (place) {
      return {
        type: "Feature",
        properties: {
          color: modeColorMap[place.type] || "#008",
          name: place.place_name,
          type: place.type || "place"
        },
        geometry: {
          type: "Point",
          coordinates: [place.place_lon, place.place_lat]
        }
      };
    })), _toConsumableArray((transitiveData.journeys || []).flatMap(function (journey) {
      return journey.segments.filter(function (segment) {
        var _segment$streetEdges;
        return ((_segment$streetEdges = segment.streetEdges) === null || _segment$streetEdges === void 0 ? void 0 : _segment$streetEdges.length) > 0;
      }).map(function (segment) {
        return _objectSpread(_objectSpread({}, segment), {}, {
          geometries: segment.streetEdges.map(function (edge) {
            return transitiveData.streetEdges.find(function (entry) {
              return entry.edge_id === edge;
            });
          })
        });
      }).flatMap(function (segment) {
        return segment.geometries.map(function (geometry) {
          var straight = polyline.toGeoJSON(geometry.geometry.points);
          return {
            type: "Feature",
            properties: {
              type: "street-edge",
              color: accessLegColorOverride || modeColorMap[segment.type] || "#008",
              mode: segment.type
            },
            geometry: segment.arc ? drawArc(straight) : straight
          };
        });
      });
    })), _toConsumableArray((transitiveData.journeys || []).flatMap(function (journey) {
      return journey.segments;
    }).filter(function (segment) {
      return segment.type === "TRANSIT";
    }).map(function (segment) {
      return transitiveData.patterns.find(function (p) {
        var _segment$patterns$;
        return p.pattern_id === ((_segment$patterns$ = segment.patterns[0]) === null || _segment$patterns$ === void 0 ? void 0 : _segment$patterns$.pattern_id);
      });
    }).filter(function (pattern) {
      return !!pattern;
    }).flatMap(function (pattern) {
      return pattern.stops.filter(function (_, index, stopsArr) {
        return index === 0 || index === stopsArr.length - 1;
      });
    }).map(function (pStop) {
      return (
        // pStop (from pattern.stops) only has an id (and sometimes line geometry)
        transitiveData.stops.find(function (stop) {
          return stop.stop_id === pStop.stop_id;
        })
      );
    }).map(function (stop) {
      return {
        type: "Feature",
        properties: {
          name: stop.stop_name,
          type: "stop"
        },
        geometry: {
          type: "Point",
          coordinates: [stop.stop_lon, stop.stop_lat]
        }
      };
    })), _toConsumableArray((transitiveData.patterns || []).flatMap(function (pattern) {
      return patternToRouteFeature(pattern, transitiveData.routes);
    }))) : []
  };
  var zoomToGeoJSON = function zoomToGeoJSON(geoJson) {
    if (!boundsFitting) return;
    var b = bbox(geoJson);
    var bounds = [b[0], b[1], b[2], b[3]];
    if (map && bounds.length === 4 && bounds.every(Number.isFinite)) {
      map.fitBounds(bounds, {
        duration: 500,
        padding: util.getFitBoundsPadding(map, 0.2)
      });
    }
  };
  useEffect(function () {
    zoomToGeoJSON(geojson);
  }, [transitiveData]);
  useEffect(function () {
    if (!(activeLeg !== null && activeLeg !== void 0 && activeLeg.legGeometry)) return;
    zoomToGeoJSON(polyline.toGeoJSON(activeLeg.legGeometry.points));
  }, [activeLeg]);
  if (!transitiveData) return /*#__PURE__*/React.createElement(React.Fragment, null);
  var _getFromToAnchors = getFromToAnchors(transitiveData),
    fromAnchor = _getFromToAnchors.fromAnchor,
    toAnchor = _getFromToAnchors.toAnchor;

  // Generally speaking, text/symbol layers placed first will be rendered in a lower layer
  // (or, if it is text, rendered with a lower priority or not at all if higher-priority text overlaps).
  return /*#__PURE__*/React.createElement(Source, {
    data: geojson,
    id: "itinerary",
    type: "geojson"
  }, /*#__PURE__*/React.createElement(Layer
  // This layer is for WALK modes - dotted path
  , {
    filter: ["all", ["==", "type", "street-edge"], ["==", "mode", "WALK"]],
    id: "street-edges-walk",
    layout: {
      "line-cap": "round",
      "line-join": "round"
    },
    paint: {
      // TODO: get from transitive properties
      "line-color": ["get", "color"],
      // First parameter of array is the length of the dash which is set to zero,
      // so that maplibre simply adds the rounded ends to make things look like dots.
      // Even so, note that maplibre still renders beans instead of dots
      // (as if maplibre fuses dots together).
      "line-dasharray": [0, 1.3],
      "line-opacity": 0.9,
      "line-width": 6
    },
    type: "line"
  }), /*#__PURE__*/React.createElement(Layer
  // This layer is for other modes - dashed path
  , {
    filter: ["all", ["==", "type", "street-edge"], ["!=", "mode", "WALK"]],
    id: "street-edges",
    layout: {
      "line-cap": "butt"
    },
    paint: {
      // TODO: get from transitive properties
      "line-color": ["get", "color"],
      "line-dasharray": [2, 1],
      // TODO: get from transitive properties
      "line-width": 4,
      "line-opacity": 0.9
    },
    type: "line"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: routeFilter,
    id: "routes",
    layout: {
      "line-join": "round",
      "line-cap": "round"
    },
    paint: {
      "line-color": ["get", "color"],
      // Apply a thinner line (width = 6) for bus routes (route_type = 3), set width to 10 otherwise.
      "line-width": ["match", ["get", "routeType"], 3, 6, 10],
      "line-opacity": 1
    },
    type: "line"
  }), showRouteArrows && /*#__PURE__*/React.createElement(Layer, {
    id: "route-arrows",
    layout: {
      "symbol-placement": "line",
      "icon-image": "arrow-icon",
      "icon-size": 0.1,
      "symbol-spacing": 10,
      "icon-allow-overlap": true,
      "icon-ignore-placement": true,
      "icon-offset": [0, 8000]
    },
    paint: {
      "icon-color": ["get", "color"],
      "icon-opacity": 0.8
    },
    type: "symbol"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: accessLegFilter,
    id: "access-leg-circles",
    paint: {
      "circle-color": ["get", "color"],
      "circle-radius": 8,
      "circle-stroke-color": "#fff",
      "circle-stroke-width": 3
    },
    type: "circle"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: stopFilter,
    id: "stops-circles",
    paint: {
      "circle-color": "#fff",
      "circle-radius": 7,
      "circle-stroke-width": 3
    },
    type: "circle"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: accessLegFilter,
    id: "access-leg-labels",
    layout: defaultTextLayoutParams,
    paint: defaultTextPaintParams,
    type: "symbol"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: stopFilter,
    id: "stops-labels",
    layout: defaultTextLayoutParams,
    paint: defaultTextPaintParams,
    type: "symbol"
  }), /*#__PURE__*/React.createElement(Layer
  // This layer renders transit route names (foreground).
  , {
    filter: routeFilter,
    id: "routes-labels",
    layout: getRouteLayerLayout("name"),
    paint: {
      "icon-color": ["get", "color"],
      "text-color": ["get", "textColor"]
    },
    type: "symbol"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: ["==", "type", "from"],
    id: "from-label",
    layout: _objectSpread(_objectSpread({}, defaultBoldTextLayoutParams), {}, {
      "text-anchor": fromAnchor
    }),
    paint: defaultTextPaintParams,
    type: "symbol"
  }), /*#__PURE__*/React.createElement(Layer, {
    filter: ["==", "type", "to"],
    id: "to-label",
    layout: _objectSpread(_objectSpread({}, defaultBoldTextLayoutParams), {}, {
      "text-anchor": toAnchor
    }),
    paint: _objectSpread(_objectSpread({}, defaultTextPaintParams), {}, {
      "text-color": "#910818"
    }),
    type: "symbol"
  }));
};
export default TransitiveCanvasOverlay;
//# sourceMappingURL=index.js.map