import isWithin from "../is-within";

const isPartiallyVisibleThroughFrame = (frame) => {
  const isWithinVertical = isWithin(frame.top, frame.bottom);
  const isWithinHorizontal = isWithin(frame.left, frame.right);
  return (subject) => {
    // situations where target is visible:
    // 1. is completely contained within frame
    // 2. is partially visible on both axis within frame
    // 3. is bigger than frame on both axis
    // 4. is bigger than frame on one axis and is partially visible on the other

    // completely contained
    const isContained =
      isWithinVertical(subject.top) &&
      isWithinVertical(subject.bottom) &&
      isWithinHorizontal(subject.left) &&
      isWithinHorizontal(subject.right);
    if (isContained) {
      return true;
    }
    const isPartiallyVisibleVertically = isWithinVertical(subject.top) || isWithinVertical(subject.bottom);
    const isPartiallyVisibleHorizontally = isWithinHorizontal(subject.left) || isWithinHorizontal(subject.right);

    // partially visible on both axis
    const isPartiallyContained = isPartiallyVisibleVertically && isPartiallyVisibleHorizontally;
    if (isPartiallyContained) {
      return true;
    }
    const isBiggerVertically = subject.top < frame.top && subject.bottom > frame.bottom;
    const isBiggerHorizontally = subject.left < frame.left && subject.right > frame.right;

    // is bigger than frame on both axis
    const isTargetBiggerThanFrame = isBiggerVertically && isBiggerHorizontally;
    if (isTargetBiggerThanFrame) {
      return true;
    }

    // is bigger on one axis, and partially visible on another
    const isTargetBiggerOnOneAxis =
      (isBiggerVertically && isPartiallyVisibleHorizontally) || (isBiggerHorizontally && isPartiallyVisibleVertically);
    return isTargetBiggerOnOneAxis;
  };
};

export default isPartiallyVisibleThroughFrame;
