"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.StyledSubmodeSelector = void 0;

require("core-js/modules/web.dom.iterable");

var _itinerary = require("@opentripplanner/core-utils/lib/itinerary");

var _tripForm = require("@opentripplanner/trip-form");

var TripFormClasses = _interopRequireWildcard(require("@opentripplanner/trip-form/lib/styled"));

var _react = _interopRequireWildcard(require("react"));

var _reactSelect = _interopRequireDefault(require("react-select"));

var _styledComponents = _interopRequireDefault(require("styled-components"));

var _styled2 = require("../styled");

var _contexts = require("../../../util/contexts");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const StyledSubmodeSelector = (0, _styledComponents.default)(_tripForm.SubmodeSelector)`
  ${TripFormClasses.SubmodeSelector.Row} {
    > * {
      padding: 3px 5px 3px 0px;
    }
    > :last-child {
      padding-right: 0px;
    }
    ${TripFormClasses.ModeButton.Button} {
      padding: 6px 12px;
    }
    svg,
    img {
      margin-left: 0px;
    }
  }
  ${TripFormClasses.SubmodeSelector.InlineRow} {
    margin: -3px 0px;
  }

  ${TripFormClasses.SubmodeSelector} {
      ${_styled2.modeButtonButtonCss}
  }
`;
exports.StyledSubmodeSelector = StyledSubmodeSelector;

const metersToMiles = meters => Math.round(meters * 0.000621371 * 100) / 100;

const milesToMeters = miles => miles / 0.000621371;

class AdvancedOptions extends _react.Component {
  constructor(props) {
    super(props);

    _defineProperty(this, "_setBannedRoutes", options => {
      const bannedRoutes = options ? options.map(o => o.value).join(',') : '';
      this.props.setQueryParam({
        bannedRoutes
      });
    });

    _defineProperty(this, "_setPreferredRoutes", options => {
      const preferredRoutes = options ? options.map(o => o.value).join(',') : '';
      this.props.setQueryParam({
        preferredRoutes
      });
    });

    _defineProperty(this, "_isBannedRouteOptionDisabled", option => {
      // Disable routes that are preferred already.
      const preferredRoutes = this.getRouteList('preferredRoutes');
      return preferredRoutes && preferredRoutes.find(o => o.value === option.value);
    });

    _defineProperty(this, "_isPreferredRouteOptionDisabled", option => {
      // Disable routes that are banned already.
      const bannedRoutes = this.getRouteList('bannedRoutes');
      return bannedRoutes && bannedRoutes.find(o => o.value === option.value);
    });

    _defineProperty(this, "getDistanceStep", distanceInMeters => {
      // Determine step for max walk/bike based on current value. Increment by a
      // quarter mile if dealing with small values, whatever number will round off
      // the number if it is not an integer, or default to one mile.
      return metersToMiles(distanceInMeters) <= 2 ? '.25' : metersToMiles(distanceInMeters) % 1 !== 0 ? `${metersToMiles(distanceInMeters) % 1}` : '1';
    });

    _defineProperty(this, "_onSubModeChange", changedMode => {
      // Get previous transit modes from state and all modes from query.
      const transitModes = [...this.state.transitModes];
      const allModes = this.props.currentQuery.mode.split(',');
      const index = transitModes.indexOf(changedMode);

      if (index === -1) {
        // If submode was not selected, add it.
        transitModes.push(changedMode);
        allModes.push(changedMode);
      } else {
        // Otherwise, remove it.
        transitModes.splice(index, 1);
        const i = allModes.indexOf(changedMode);
        allModes.splice(i, 1);
      } // Update transit modes in state.


      this.setState({
        transitModes
      }); // Update all modes in query (set to walk if all transit modes inactive).

      this.props.setQueryParam({
        mode: allModes.join(',') || 'WALK'
      });
    });

    _defineProperty(this, "_setMaxWalkDistance", evt => {
      this.props.setQueryParam({
        maxWalkDistance: milesToMeters(evt.target.value)
      });
    });

    _defineProperty(this, "getRouteList", key => {
      const routesParam = this.props.currentQuery[key];
      const idList = routesParam ? routesParam.split(',') : [];

      if (this.state.routeOptions) {
        return this.state.routeOptions.filter(o => idList.indexOf(o.value) !== -1);
      } else {
        // If route list is not available, default labels to route IDs.
        return idList.map(id => ({
          label: id,
          value: id
        }));
      }
    });

    _defineProperty(this, "routeToOption", route => {
      if (!route) return null;
      const {
        id,
        longName,
        shortName
      } = route; // For some reason the OTP API expects route IDs in this double
      // underscore format
      // FIXME: This replace is flimsy! What if there are more colons?

      const value = id.replace(':', '__');
      const label = shortName ? `${shortName}${longName ? ` - ${longName}` : ''}` : longName;
      return {
        label,
        value
      };
    });

    this.state = {
      expandAdvanced: props.expandAdvanced,
      routeOptions: [],
      transitModes: props.modes.transitModes.map(m => m.mode)
    };
  }

  componentDidMount() {
    // Fetch routes for banned/preferred routes selectors.
    this.props.findRoutes();
  }

  componentDidUpdate(prevProps) {
    const {
      routes
    } = this.props; // Once routes are available, map them to the route options format.

    if (routes && !prevProps.routes) {
      const routeOptions = Object.values(routes).map(this.routeToOption);
      this.setState({
        routeOptions
      });
    }
  }

  render() {
    const {
      currentQuery,
      modes,
      onKeyDown
    } = this.props;
    const {
      ModeIcon
    } = this.context;
    const {
      maxBikeDistance,
      maxWalkDistance,
      mode
    } = currentQuery;
    const bannedRoutes = this.getRouteList('bannedRoutes');
    const preferredRoutes = this.getRouteList('preferredRoutes');
    const transitModes = modes.transitModes.map(modeObj => {
      const modeStr = modeObj.mode || modeObj;
      return {
        id: modeStr,
        selected: this.state.transitModes.indexOf(modeStr) !== -1,
        text: /*#__PURE__*/_react.default.createElement(ModeIcon, {
          mode: modeStr
        }),
        title: modeObj.label
      };
    }); // FIXME: Set units via config.

    const unitsString = '(mi.)';
    return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
      style: {
        alignItems: 'center',
        display: 'flex',
        justifyContent: 'space-between'
      }
    }, /*#__PURE__*/_react.default.createElement("label", {
      style: {
        fontWeight: '400'
      }
    }, "Max walk ", unitsString, /*#__PURE__*/_react.default.createElement("input", {
      min: "0",
      onChange: this._setMaxWalkDistance,
      onKeyDown: onKeyDown,
      step: this.getDistanceStep(maxWalkDistance),
      style: {
        display: 'block',
        marginRight: '10px',
        width: '60px'
      },
      type: "number",
      value: metersToMiles(maxWalkDistance)
    })), (0, _itinerary.hasBike)(mode) ? /*#__PURE__*/_react.default.createElement("label", {
      style: {
        fontWeight: '400'
      }
    }, "Max bike ", unitsString, /*#__PURE__*/_react.default.createElement("input", {
      min: "0",
      onChange: this._setMaxBikeDistance,
      onKeyDown: onKeyDown,
      step: this.getDistanceStep(maxBikeDistance),
      style: {
        display: 'block',
        marginRight: '10px',
        width: '60px'
      },
      type: "number",
      value: metersToMiles(maxBikeDistance)
    })) : null, /*#__PURE__*/_react.default.createElement(StyledSubmodeSelector, {
      modes: transitModes,
      onChange: this._onSubModeChange // FIXME: Need to pass onKeyDown to children buttons in
      // otp-ui.
      ,
      onKeyDown: onKeyDown
    })), /*#__PURE__*/_react.default.createElement(_reactSelect.default, {
      id: "preferredRoutes",
      isMulti: true,
      isOptionDisabled: this._isPreferredRouteOptionDisabled,
      onChange: this._setPreferredRoutes,
      options: this.state.routeOptions,
      placeholder: "Select preferred routes...",
      value: preferredRoutes
    }), /*#__PURE__*/_react.default.createElement(_reactSelect.default, {
      id: "bannedRoutes",
      isMulti: true,
      isOptionDisabled: this._isBannedRouteOptionDisabled,
      onChange: this._setBannedRoutes,
      options: this.state.routeOptions,
      placeholder: "Select banned routes...",
      value: bannedRoutes
    }));
  }

}

exports.default = AdvancedOptions;

_defineProperty(AdvancedOptions, "contextType", _contexts.ComponentContext);

//# sourceMappingURL=advanced-options.js