// Copyright 2019 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

inline bool isempty1f(const box1f &box)
{
  return box.upper <= box.lower;
}

#ifdef ISPC
inline uniform bool isempty1f(const uniform box1f &box)
{
  return box.upper <= box.lower;
}
#endif

inline bool overlaps1f(const box1f &box1, const box1f &box2)
{
  return box1.upper >= box2.lower && box1.lower <= box2.upper;
}

#ifdef ISPC
inline bool overlaps1f(const uniform box1f &box1, const box1f &box2)
{
  return box1.upper >= box2.lower && box1.lower <= box2.upper;
}

inline uniform bool overlaps1f(const uniform box1f &box1,
                               const uniform box1f &box2)
{
  return box1.upper >= box2.lower && box1.lower <= box2.upper;
}

inline bool overlapsAny1f(const box1f &r,
                          const uniform int &numRanges,
                          const box1f *uniform ranges)
{
  for (uniform int i = 0; i < numRanges; i++) {
    if (overlaps1f(ranges[i], r)) {
      return true;
    }
  }

  return false;
}

inline uniform bool overlapsAny1f(const uniform box1f &r,
                                  const uniform int &numRanges,
                                  const box1f *uniform ranges)
{
  for (uniform int i = 0; i < numRanges; i++) {
    if (overlaps1f(ranges[i], r)) {
      return true;
    }
  }

  return false;
}
#endif

inline box1f intersectBox(const vec3f &origin,
                          const vec3f &direction,
                          const box3f &box,
                          const box1f &rangeLimit)
{
  const vec3f mins = (box.lower - origin) * divide_safe(direction);
  const vec3f maxs = (box.upper - origin) * divide_safe(direction);

  box1f result;
  result.lower = reduce_max(make_vec4f(min(mins, maxs), rangeLimit.lower));
  result.upper = reduce_min(make_vec4f(max(mins, maxs), rangeLimit.upper));

  return result;
}

#ifdef ISPC
inline box1f intersectBox(const vec3f &origin,
                          const vec3f &direction,
                          const uniform box3f &box,
                          const box1f &rangeLimit)
{
  const vec3f mins = (box.lower - origin) * divide_safe(direction);
  const vec3f maxs = (box.upper - origin) * divide_safe(direction);

  box1f result;
  result.lower = reduce_max(make_vec4f(min(mins, maxs), rangeLimit.lower));
  result.upper = reduce_min(make_vec4f(max(mins, maxs), rangeLimit.upper));

  return result;
}

inline uniform box1f intersectBox(const uniform vec3f &origin,
                                  const uniform vec3f &direction,
                                  const uniform box3f &box,
                                  const uniform box1f &rangeLimit)
{
  const uniform vec3f mins = (box.lower - origin) * divide_safe(direction);
  const uniform vec3f maxs = (box.upper - origin) * divide_safe(direction);

  uniform box1f result;
  result.lower = reduce_max(make_vec4f(min(mins, maxs), rangeLimit.lower));
  result.upper = reduce_min(make_vec4f(max(mins, maxs), rangeLimit.upper));

  return result;
}
#endif