/*
  This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.

  Author: Uwe Schulzweida

*/

#ifndef POINTSEARCH_UTILS_H
#define POINTSEARCH_UTILS_H

#include <span>
#include <algorithm>
#include <cmath>

struct PointsearchParams
{
  size_t dims[2] = { 0 };
  double searchRadius{ 0 };
  bool extrapolation{ false };
  bool isCyclic{ false };
  bool isCurve{ false };
  bool useBoundBox{ false };
};

static inline double
arc_to_chord_length(double arcLength)
{
  return 2.0 * std::sin(arcLength / 2.0);
}

static inline double
chord_to_arc_length(double chordLength)
{
  return 2.0 * std::asin(std::clamp(chordLength / 2.0, -1.0, 1.0));
}

constexpr void
min_point(std::span<double, 3> min, std::span<const double, 3> point) noexcept
{
  for (int i = 0; i < 3; ++i) { min[i] = (point[i] < min[i]) ? point[i] : min[i]; }
}

constexpr void
max_point(std::span<double, 3> max, std::span<const double, 3> point) noexcept
{
  for (int i = 0; i < 3; ++i) { max[i] = (point[i] > max[i]) ? point[i] : max[i]; }
}

constexpr void
adjust_bbox_min(std::span<double, 3> min) noexcept
{
  for (int i = 0; i < 3; ++i) { min[i] = (min[i] < 0) ? min[i] * 1.002 : min[i] * 0.998; }
}

constexpr void
adjust_bbox_max(std::span<double, 3> max) noexcept
{
  for (int i = 0; i < 3; ++i) { max[i] = (max[i] < 0) ? max[i] * 0.998 : max[i] * 1.002; }
}

constexpr bool
point_in_bbox(std::span<const double, 3> point, std::span<const float, 3> bboxMin, std::span<const float, 3> bboxMax) noexcept
{
  for (int i = 0; i < 3; ++i)
    if (point[i] < static_cast<double>(bboxMin[i]) || point[i] > static_cast<double>(bboxMax[i])) return false;
  return true;
}

#endif
