"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getOppositePosition = getOppositePosition;
exports.isVerticalPosition = isVerticalPosition;
exports.capitalize = capitalize;
exports.toPopperPlacement = toPopperPlacement;
exports.fromPopperPlacement = fromPopperPlacement;
exports.splitPlacement = splitPlacement;
exports.parsePopperOffset = parsePopperOffset;
exports.getPopoverMarginStyles = getPopoverMarginStyles;
exports.getStartPosition = getStartPosition;
exports.getEndPosition = getEndPosition;
exports.getArrowPositionStyles = getArrowPositionStyles;

var _constants = require("./constants.js");

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

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; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

var OPPOSITE_POSITIONS = {
  top: 'bottom',
  bottom: 'top',
  right: 'left',
  left: 'right'
};
/**
 * Returns the opposite of the specified position. Useful for tooltip
 * positioning logic.
 * Examples:
 * top -> bottom
 * left -> right
 */

function getOppositePosition(position) {
  return OPPOSITE_POSITIONS[position];
}
/**
 * Determines whether or not the specified position is a vertical one (top or bottom)
 */


function isVerticalPosition(position) {
  return position === 'top' || position === 'bottom';
}
/**
 * Simple utility function for capitalizing the first letter of a string
 */


function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
 * Converts our placement prop to a Popper.js placement
 * See docs: https://popper.js.org/popper-documentation.html
 * auto, top, right, bottom, left are the same but things
 * like 'rightTop' must be converted to 'right-start'
 */


function toPopperPlacement(placement) {
  return placement.replace(/(Top|Left)$/, '-start').replace(/(Right|Bottom)$/, '-end');
}
/**
 * Opposite of function above, converts from Popper.js placement
 * to our placement prop
 */


function fromPopperPlacement(placement) {
  var popoverPlacement = placement.replace(/(top|bottom)-start$/, '$1Left').replace(/(top|bottom)-end$/, '$1Right').replace(/(left|right)-start$/, '$1Top').replace(/(left|right)-end$/, '$1Bottom');
  return _constants.PLACEMENT[popoverPlacement] || null;
}
/**
 * Splits something like 'topLeft' to ['top', 'left'] for easier usage
 */


function splitPlacement(placement) {
  var matches = placement.match(/^([a-z]+)([A-Z][a-z]+)?/) || [];
  return matches.slice(1, 3).filter(Boolean).map(function (s) {
    return s.toLowerCase();
  });
}
/**
 * Takes the offset passed from popper.js and normalizes it
 */


function parsePopperOffset(offset) {
  return {
    top: Math.floor(offset.top || 0),
    left: Math.floor(offset.left || 0)
  };
}
/**
 * Returns margin styles to add spacing between the popover
 * and its anchor.
 *
 * We may eventually want to make margin a prop that can be overridden.
 */


function getPopoverMarginStyles(showArrow, placement) {
  var _splitPlacement = splitPlacement(placement),
      _splitPlacement2 = _slicedToArray(_splitPlacement, 1),
      position = _splitPlacement2[0];

  var opposite = getOppositePosition(position);

  if (!opposite) {
    return null;
  }

  var property = "margin".concat(capitalize(opposite));
  return _defineProperty({}, property, "".concat(showArrow ? _constants.ARROW_SIZE : _constants.POPOVER_MARGIN, "px"));
}
/**
 * Returns CSS rules for the popover animation start keyframe
 */


function getStartPosition(offset, placement, showArrow) {
  offset = _objectSpread({}, offset);

  var _splitPlacement3 = splitPlacement(placement),
      _splitPlacement4 = _slicedToArray(_splitPlacement3, 1),
      position = _splitPlacement4[0];

  var margin = (showArrow ? _constants.ARROW_SIZE : _constants.POPOVER_MARGIN) * 2;

  if (isVerticalPosition(position)) {
    offset.top += position === 'top' ? margin : -margin;
  } else {
    offset.left += position === 'left' ? margin : -margin;
  }

  return "translate3d(".concat(offset.left, "px, ").concat(offset.top, "px, 0)");
}
/**
 * Returns CSS rules for the popover animation end keyframe
 */


function getEndPosition(offset) {
  return "translate3d(".concat(offset.left, "px, ").concat(offset.top, "px, 0)");
}
/**
 * Returns top/left styles to position the popover arrow
 */


function getArrowPositionStyles(offsets, placement) {
  var _ref2;

  var _splitPlacement5 = splitPlacement(placement),
      _splitPlacement6 = _slicedToArray(_splitPlacement5, 1),
      position = _splitPlacement6[0];

  var oppositePosition = getOppositePosition(position);

  if (!oppositePosition) {
    return null;
  }

  var alignmentProperty = isVerticalPosition(position) ? 'left' : 'top';
  return _ref2 = {}, _defineProperty(_ref2, alignmentProperty, "".concat(offsets[alignmentProperty], "px")), _defineProperty(_ref2, oppositePosition, "-".concat(_constants.ARROW_SIZE - 2, "px")), _ref2;
}