"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

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

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

var POPUP_OFFSET = 3;
var POSITION_START = 'start';
var POSITION_CENTER = 'center';
var POSITION_END = 'end';
var DIRECTION_NORTH = 'north';
var DIRECTION_EAST = 'east';
var DIRECTION_SOUTH = 'south';
var DIRECTION_WEST = 'west';

var getElementPositionValues = function getElementPositionValues(element) {
  var _element$getBoundingC = element.getBoundingClientRect(),
      top = _element$getBoundingC.top,
      left = _element$getBoundingC.left,
      right = _element$getBoundingC.right,
      bottom = _element$getBoundingC.bottom;

  return {
    top: top,
    left: left,
    right: right,
    bottom: bottom,
    centerY: top + (bottom - top) / 2,
    centerX: left + (right - left) / 2
  };
};

var getElementDimensionValues = function getElementDimensionValues(element) {
  var _element$getBoundingC2 = element.getBoundingClientRect(),
      width = _element$getBoundingC2.width,
      height = _element$getBoundingC2.height;

  return {
    width: width,
    height: height
  };
}; // HORIZONTAL


var getHorizontalDirectionPositionTopValue = function getHorizontalDirectionPositionTopValue(position, anchorPosition, popoverDimensions, inputOffsetCorrection) {
  switch (position) {
    case POSITION_CENTER:
      return anchorPosition.centerY - popoverDimensions.height / 2;

    case POSITION_START:
      return anchorPosition.top - POPUP_OFFSET * 0.75 - inputOffsetCorrection;

    case POSITION_END:
      return anchorPosition.bottom - popoverDimensions.height + POPUP_OFFSET * 0.75 + inputOffsetCorrection;
  }
};

var getHorizontalDirectionPositionLeftValue = function getHorizontalDirectionPositionLeftValue(direction, anchorPosition, popoverDimensions) {
  return direction === DIRECTION_WEST ? anchorPosition.left - popoverDimensions.width - POPUP_OFFSET : anchorPosition.right + POPUP_OFFSET;
}; // VERTICAL


var getVerticalDirectionPositionTopValue = function getVerticalDirectionPositionTopValue(direction, anchorPosition, popoverDimensions) {
  return direction === DIRECTION_NORTH ? anchorPosition.top - popoverDimensions.height - POPUP_OFFSET : anchorPosition.bottom + POPUP_OFFSET;
};

var getVerticalDirectionPositionLeftValue = function getVerticalDirectionPositionLeftValue(position, anchorPosition, popoverDimensions, inputOffsetCorrection) {
  switch (position) {
    case POSITION_CENTER:
      return anchorPosition.centerX - popoverDimensions.width / 2;

    case POSITION_START:
      return anchorPosition.left - inputOffsetCorrection;

    case POSITION_END:
      return anchorPosition.right - popoverDimensions.width + inputOffsetCorrection;
  }
};

var getVerticalDirectionPositionValues = function getVerticalDirectionPositionValues(_ref) {
  var direction = _ref.direction,
      position = _ref.position,
      anchorPosition = _ref.anchorPosition,
      popoverDimensions = _ref.popoverDimensions,
      inputOffsetCorrection = _ref.inputOffsetCorrection;
  return {
    top: getVerticalDirectionPositionTopValue(direction, anchorPosition, popoverDimensions),
    left: getVerticalDirectionPositionLeftValue(position, anchorPosition, popoverDimensions, inputOffsetCorrection)
  };
};

var getHorizontalDirectionPositionValues = function getHorizontalDirectionPositionValues(_ref2) {
  var direction = _ref2.direction,
      position = _ref2.position,
      anchorPosition = _ref2.anchorPosition,
      popoverDimensions = _ref2.popoverDimensions,
      inputOffsetCorrection = _ref2.inputOffsetCorrection;
  return {
    top: getHorizontalDirectionPositionTopValue(position, anchorPosition, popoverDimensions, inputOffsetCorrection),
    left: getHorizontalDirectionPositionLeftValue(direction, anchorPosition, popoverDimensions)
  };
};

var getPositionValues = function getPositionValues(_ref3) {
  var direction = _ref3.direction,
      position = _ref3.position,
      anchorPosition = _ref3.anchorPosition,
      popoverDimensions = _ref3.popoverDimensions,
      inputOffsetCorrection = _ref3.inputOffsetCorrection;
  return direction === DIRECTION_NORTH || direction === DIRECTION_SOUTH ? getVerticalDirectionPositionValues({
    direction: direction,
    position: position,
    anchorPosition: anchorPosition,
    popoverDimensions: popoverDimensions,
    inputOffsetCorrection: inputOffsetCorrection
  }) : getHorizontalDirectionPositionValues({
    direction: direction,
    position: position,
    anchorPosition: anchorPosition,
    popoverDimensions: popoverDimensions,
    inputOffsetCorrection: inputOffsetCorrection
  });
};

var isInViewport = function isInViewport(direction, anchorPosition, popoverDimensions) {
  switch (direction) {
    case DIRECTION_NORTH:
      return anchorPosition.top - popoverDimensions.height - POPUP_OFFSET > 0;

    case DIRECTION_SOUTH:
      return anchorPosition.bottom + popoverDimensions.height + POPUP_OFFSET < window.innerHeight;

    case DIRECTION_EAST:
      return anchorPosition.right + popoverDimensions.width + POPUP_OFFSET < window.innerWidth;

    case DIRECTION_WEST:
      return anchorPosition.left - popoverDimensions.width - POPUP_OFFSET > 0;
  }
};

var getOppositeDirection = function getOppositeDirection(direction) {
  switch (direction) {
    case DIRECTION_NORTH:
      return DIRECTION_SOUTH;

    case DIRECTION_SOUTH:
      return DIRECTION_NORTH;

    case DIRECTION_EAST:
      return DIRECTION_WEST;

    case DIRECTION_WEST:
      return DIRECTION_EAST;
  }
};

var getClockwise90DegreeDirection = function getClockwise90DegreeDirection(direction) {
  switch (direction) {
    case DIRECTION_NORTH:
      return DIRECTION_EAST;

    case DIRECTION_EAST:
      return DIRECTION_SOUTH;

    case DIRECTION_SOUTH:
      return DIRECTION_WEST;

    case DIRECTION_WEST:
      return DIRECTION_NORTH;
  }
};

var getClockwise270DegreeDirection = function getClockwise270DegreeDirection(direction) {
  switch (direction) {
    case DIRECTION_NORTH:
      return DIRECTION_WEST;

    case DIRECTION_EAST:
      return DIRECTION_NORTH;

    case DIRECTION_SOUTH:
      return DIRECTION_EAST;

    case DIRECTION_WEST:
      return DIRECTION_SOUTH;
  }
};

var getDirection = function getDirection(direction, anchorPosition, popoverDimensions) {
  var inputDirectionRendersOnScreen = isInViewport(direction, anchorPosition, popoverDimensions);
  var oppositeDirectionRendersOnScreen = isInViewport(getOppositeDirection(direction), anchorPosition, popoverDimensions);
  var clockwise90DegreeDirectionRendersOnScreen = isInViewport(getClockwise90DegreeDirection(direction), anchorPosition, popoverDimensions);
  var clockwise270DegreeDirectionRendersOnScreen = isInViewport(getClockwise270DegreeDirection(direction), anchorPosition, popoverDimensions);

  if (!inputDirectionRendersOnScreen) {
    if (oppositeDirectionRendersOnScreen) {
      return getOppositeDirection(direction);
    }

    if (clockwise90DegreeDirectionRendersOnScreen) {
      return getClockwise90DegreeDirection(direction);
    }

    if (clockwise270DegreeDirectionRendersOnScreen) {
      return getClockwise270DegreeDirection(direction);
    }
  }

  return direction;
};

var isHorizontalDirectionPositionPossible = function isHorizontalDirectionPositionPossible(position, anchorPosition, popoverDimensions) {
  switch (position) {
    case POSITION_CENTER:
      return anchorPosition.centerX + popoverDimensions.width / 2 < window.innerWidth && anchorPosition.centerX - popoverDimensions.width / 2 > 0;

    case POSITION_END:
      return anchorPosition.left + popoverDimensions.width < window.innerWidth;

    case POSITION_START:
      return anchorPosition.right - popoverDimensions.width > 0;
  }
};

var isPositionPossible = function isPositionPossible(position, anchorPosition, popoverDimensions) {
  return isHorizontalDirectionPositionPossible(position, anchorPosition, popoverDimensions);
};

var getOppositePosition = function getOppositePosition(position) {
  switch (position) {
    case POSITION_START:
      return POSITION_END;

    case POSITION_END:
      return POSITION_START;
  }
};

var getPosition = function getPosition(position, anchorPosition, popoverDimensions) {
  if (isPositionPossible(position, anchorPosition, popoverDimensions)) {
    if (position === POSITION_CENTER) {
      return position;
    }

    return getOppositePosition(position);
  }

  switch (position) {
    case POSITION_CENTER:
      return isPositionPossible(POSITION_START, anchorPosition, popoverDimensions) ? POSITION_END : isPositionPossible(POSITION_END, anchorPosition, popoverDimensions) ? POSITION_START : position;

    default:
      return isPositionPossible(POSITION_CENTER, anchorPosition, popoverDimensions) ? POSITION_CENTER : getOppositePosition(position);
  }
};

var getMaxHeightValue = function getMaxHeightValue(direction, anchorPosition) {
  switch (direction) {
    case DIRECTION_NORTH:
      return anchorPosition.top - POPUP_OFFSET * 2;

    case DIRECTION_SOUTH:
      return window.innerHeight - anchorPosition.bottom - POPUP_OFFSET * 2;
  }
};

var calculatePositions = function calculatePositions(anchorEl, popoverEl, inputDirection, inputPosition, inputOffsetCorrection) {
  var anchorPosition = getElementPositionValues(anchorEl);
  var popoverDimensions = getElementDimensionValues(popoverEl);
  var direction = getDirection(inputDirection, anchorPosition, popoverDimensions);
  var position = getPosition(inputPosition, anchorPosition, popoverDimensions);
  return _objectSpread({
    maxHeight: getMaxHeightValue(direction, anchorPosition)
  }, position && getPositionValues({
    direction: direction,
    position: position,
    anchorPosition: anchorPosition,
    popoverDimensions: popoverDimensions,
    inputOffsetCorrection: inputOffsetCorrection
  }));
};

exports.calculatePositions = calculatePositions;