export function getRectCenter(rect) {
  return buildPoint(
    rect.left + rect.width / 2,
    rect.top + rect.height / 2,
  )
}

export function intersectRects(rect0, rect1) {
  return buildRectViaEdges(
    Math.max(rect0.left, rect1.left),
    Math.max(rect0.top, rect1.top),
    Math.min(rect0.right, rect1.right),
    Math.min(rect0.bottom, rect1.bottom),
  )
}

export function rectsIntersect(rect0, rect1) {
  return rect0.left < rect1.right && rect0.right > rect1.left && rect0.top < rect1.bottom && rect0.bottom > rect1.top
}

export function rectContainersOther(rect0, rect1) { // rect0 contains rect1?
  return rect1.left >= rect0.left && rect1.right <= rect0.right && rect1.top >= rect0.top && rect1.bottom <= rect0.bottom
}

export function joinRects(rect1, rect2) {
  return {
    left: Math.min(rect1.left, rect2.left),
    right: Math.max(rect1.right, rect2.right),
    top: Math.min(rect1.top, rect2.top),
    bottom: Math.max(rect1.bottom, rect2.bottom),
  }
}

function buildRectViaEdges(left, top, right, bottom) {
  return {
    left,
    top,
    width: right - left,
    height: bottom - top,
    right,
    bottom,
  }
}

function buildPoint(left, top) {
  return {
    left,
    top,
  }
}

export function subtractPoints(point1, point0) {
  return buildPoint(
    point1.left - point0.left,
    point1.top - point0.top,
  )
}

export function addPoints(point0, point1) {
  return buildPoint(
    point0.left + point1.left,
    point0.top + point1.top,
  )
}

// in most situations you can just use the rect directly, since the interface is a superset
export function getRectTopLeft(rect) {
  return buildPoint(rect.left, rect.top)
}

export function isRect(input) {
  return typeof input === 'object' && 'left' in input && 'right' in input && 'top' in input && 'bottom' in input
}

export function isRectMostlyAbove(subjectRect, otherRect) {
  return (subjectRect.bottom - otherRect.top) < // overlap is less than
    ((subjectRect.bottom - subjectRect.top) / 2) // half the height
}

export function isRectMostlyLeft(subjectRect, otherRect) {
  return (subjectRect.right - otherRect.left) < // overlap is less then
    ((subjectRect.right - subjectRect.left) / 2) // half the width
}

export function isRectMostlyBounded(subjectRect, boundRect) {
  return isRectMostlyHBounded(subjectRect, boundRect) &&
    isRectMostlyVBounded(subjectRect, boundRect)
}

export function isRectMostlyHBounded(subjectRect, boundRect) {
  return (Math.min(subjectRect.right, boundRect.right) -
    Math.max(subjectRect.left, boundRect.left)) > // overlap area is greater than
      ((subjectRect.right - subjectRect.left) / 2) // half the width
}

export function isRectMostlyVBounded(subjectRect, boundRect) {
  return (Math.min(subjectRect.bottom, boundRect.bottom) -
    Math.max(subjectRect.top, boundRect.top)) > // overlap area is greater than
      ((subjectRect.bottom - subjectRect.top) / 2) // half the height
}

export function isRectsSimilar(rect1, rect2) {
  return isRectsHSimilar(rect1, rect2) && isRectsVSimilar(rect1, rect2)
}

function isRectsHSimilar(rect1, rect2) {
  return (Math.abs(rect1.left - rect2.left) <= 2) && (Math.abs(rect1.right - rect2.right) <= 3) // :(
}

function isRectsVSimilar(rect1, rect2) {
  return (Math.abs(rect1.top - rect2.top) <= 2) && (Math.abs(rect1.bottom - rect2.bottom) <= 3) // :(
}
