/*------------------------------------------------------------------------------
 src/lib/dj/djMath_.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

namespace dj {

template <class T>
inline const T abs(const T & in)
{
  return in < T(0) ? -in : in;
}

template <class T>
inline const T mod(const T & in, const T & mod)
{
  T tmp = in;
  if (mod != T(0)) {
    tmp = in - (int(in / mod) * mod);
    if (tmp < T(0)) tmp += mod;
  }
  return tmp;
}

template <class T>
inline const T min(const T & a, const T & b)
{
  return a < b ? a : b;
}

template <class T>
inline const T max(const T & a, const T & b)
{
  return a > b ? a : b;
}

template <class T>
inline const T clamp(const T & in, const T & min, const T & max)
{
  return in < min ? min : (in > max ? max : in);
}

template <class T, class U>
inline const T lerp(const U & in, const T & min, const T & max)
{
  return min + T(in * (max - min));
}

template <class T>
inline bool intersect(const T & in, const T & position, const T & size)
{
  return in >= position && in <= (position + size);
}

/*inline bool intersect(const int & in, const int & position, const int & size)
{
  return in >= position && in <= (position + size - 1);
}*/

template <class T>
inline bool intersect(
  const T & positionA, const T & sizeA,
  const T & positionB, const T & sizeB,
  T * position, T * size
) {
  DJ_ASSERT(position && size);
  *position = max(positionA, positionB);
  *size = min(positionA + sizeA, positionB + sizeB) - *position;
  return *size > 0;
}

/*inline bool intersect(
  const int & positionA, const int & sizeA,
  const int & positionB, const int & sizeB,
  int * position, int * size
) {
  DJ_ASSERT(position && size);
  *position = max(positionA, positionB);
  *size = min(positionA + sizeA, positionB + sizeB) - *position;
  return *size > 0;
}*/

template <class T>
inline void bound(
  const T & positionA, const T & sizeA,
  const T & positionB, const T & sizeB,
  T * position, T * size
) {
  *position = min(positionA, positionB);
  *size = max(positionA + sizeA, positionB + sizeB) - *position;
}

/*inline void bound(
  const int & positionA, const int & sizeA,
  const int & positionB, const int & sizeB,
  int * position, int * size
) {
  *position = min(positionA, positionB);
  *size = max(positionA + sizeA, positionB + sizeB) - *position;
}*/

}
