import isPartiallyVisibleThroughFrame from "./is-partially-visible-through-frame";
import isTotallyVisibleThroughFrame from "./is-totally-visible-through-frame";
import isTotallyVisibleThroughFrameOnAxis from "./is-totally-visible-through-frame-on-axis";
import { offsetByPosition } from "../spacing";
import { origin } from "../position";

const getDroppableDisplaced = (target, destination) => {
  const displacement = destination.frame ? destination.frame.scroll.diff.displacement : origin;
  return offsetByPosition(target, displacement);
};
const isVisibleInDroppable = (target, destination, isVisibleThroughFrameFn) => {
  // destination subject is totally hidden by frame
  // this should never happen - but just guarding against it
  if (!destination.subject.active) {
    return false;
  }

  // When considering if the target is visible in the droppable we need
  // to consider the change in scroll of the droppable. We need to
  // adjust for the scroll as the clipped viewport takes into account
  // the scroll of the droppable.

  return isVisibleThroughFrameFn(destination.subject.active)(target);
};
const isVisibleInViewport = (target, viewport, isVisibleThroughFrameFn) => isVisibleThroughFrameFn(viewport)(target);
const isVisible = ({
  target: toBeDisplaced,
  destination,
  viewport,
  withDroppableDisplacement,
  isVisibleThroughFrameFn
}) => {
  const displacedTarget = withDroppableDisplacement ? getDroppableDisplaced(toBeDisplaced, destination) : toBeDisplaced;
  return (
    isVisibleInDroppable(displacedTarget, destination, isVisibleThroughFrameFn) &&
    isVisibleInViewport(displacedTarget, viewport, isVisibleThroughFrameFn)
  );
};
export const isPartiallyVisible = (args) =>
  isVisible({
    ...args,
    isVisibleThroughFrameFn: isPartiallyVisibleThroughFrame
  });
export const isTotallyVisible = (args) =>
  isVisible({
    ...args,
    isVisibleThroughFrameFn: isTotallyVisibleThroughFrame
  });
export const isTotallyVisibleOnAxis = (args) =>
  isVisible({
    ...args,
    isVisibleThroughFrameFn: isTotallyVisibleThroughFrameOnAxis(args.destination.axis)
  });
