// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef sw_Math_hpp
#define sw_Math_hpp

#include "Types.hpp"

#include "Vulkan/VkDebug.hpp"

#include <cmath>
#if defined(_MSC_VER)
	#include <intrin.h>
#endif

namespace sw {

using std::abs;

#undef min
#undef max

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

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

template<class T>
inline constexpr T max(T a, T b, T c)
{
	return max(max(a, b), c);
}

template<class T>
inline constexpr T min(T a, T b, T c)
{
	return min(min(a, b), c);
}

template<class T>
inline constexpr T max(T a, T b, T c, T d)
{
	return max(max(a, b), max(c, d));
}

template<class T>
inline constexpr T min(T a, T b, T c, T d)
{
	return min(min(a, b), min(c, d));
}

template <typename destType, typename sourceType>
destType bit_cast(const sourceType &source)
{
	union
	{
		sourceType s;
		destType d;
	} sd;
	sd.s = source;
	return sd.d;
}

inline int iround(float x)
{
	return (int)floor(x + 0.5f);
//	return _mm_cvtss_si32(_mm_load_ss(&x));   // FIXME: Demands SSE support
}

inline int ifloor(float x)
{
	return (int)floor(x);
}

inline int ceilFix4(int x)
{
	return (x + 0xF) & 0xFFFFFFF0;
}

inline int ceilInt4(int x)
{
	return (x + 0xF) >> 4;
}

#define BITS(x)    ( \
!!((x) & 0x80000000) + \
!!((x) & 0xC0000000) + \
!!((x) & 0xE0000000) + \
!!((x) & 0xF0000000) + \
!!((x) & 0xF8000000) + \
!!((x) & 0xFC000000) + \
!!((x) & 0xFE000000) + \
!!((x) & 0xFF000000) + \
!!((x) & 0xFF800000) + \
!!((x) & 0xFFC00000) + \
!!((x) & 0xFFE00000) + \
!!((x) & 0xFFF00000) + \
!!((x) & 0xFFF80000) + \
!!((x) & 0xFFFC0000) + \
!!((x) & 0xFFFE0000) + \
!!((x) & 0xFFFF0000) + \
!!((x) & 0xFFFF8000) + \
!!((x) & 0xFFFFC000) + \
!!((x) & 0xFFFFE000) + \
!!((x) & 0xFFFFF000) + \
!!((x) & 0xFFFFF800) + \
!!((x) & 0xFFFFFC00) + \
!!((x) & 0xFFFFFE00) + \
!!((x) & 0xFFFFFF00) + \
!!((x) & 0xFFFFFF80) + \
!!((x) & 0xFFFFFFC0) + \
!!((x) & 0xFFFFFFE0) + \
!!((x) & 0xFFFFFFF0) + \
!!((x) & 0xFFFFFFF8) + \
!!((x) & 0xFFFFFFFC) + \
!!((x) & 0xFFFFFFFE) + \
!!((x) & 0xFFFFFFFF))

#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define MIN(x, y) ((x) < (y) ? (x) : (y))

inline unsigned long log2i(int x)
{
	#if defined(_MSC_VER)
		unsigned long y;
		_BitScanReverse(&y, x);
		return y;
	#else
		return 31 - __builtin_clz(x);
	#endif
}

inline bool isPow2(int x)
{
	return (x & -x) == x;
}

template<class T>
inline T clamp(T x, T a, T b)
{
	ASSERT(a <= b);
	if(x < a) x = a;
	if(x > b) x = b;

	return x;
}

inline float clamp01(float x)
{
	return clamp(x, 0.0f, 1.0f);
}

// Bit-cast of a floating-point value into a two's complement integer representation.
// This makes floating-point values comparable as integers.
inline int32_t float_as_twos_complement(float f)
{
	// IEEE-754 floating-point numbers are sorted by magnitude in the same way as integers,
	// except negative values are like one's complement integers. Convert them to two's complement.
	int32_t i = bit_cast<int32_t>(f);
	return (i < 0) ? (0x7FFFFFFFu - i) : i;
}

// 'Safe' clamping operation which always returns a value between min and max (inclusive).
inline float clamp_s(float x, float min, float max)
{
	// NaN values can't be compared directly
	if(float_as_twos_complement(x) < float_as_twos_complement(min)) x = min;
	if(float_as_twos_complement(x) > float_as_twos_complement(max)) x = max;

	return x;
}

inline int ceilPow2(int x)
{
	int i = 1;

	while(i < x)
	{
		i <<= 1;
	}

	return i;
}

inline int floorDiv(int a, int b)
{
	return a / b + ((a % b) >> 31);
}

inline int floorMod(int a, int b)
{
	int r = a % b;
	return r + ((r >> 31) & b);
}

inline int ceilDiv(int a, int b)
{
	return a / b - (-(a % b) >> 31);
}

inline int ceilMod(int a, int b)
{
	int r = a % b;
	return r - ((-r >> 31) & b);
}

template<const int n>
inline unsigned int unorm(float x)
{
	static const unsigned int max = 0xFFFFFFFF >> (32 - n);
	static const float maxf = static_cast<float>(max);

	if(x >= 1.0f)
	{
		return max;
	}
	else if(x <= 0.0f)
	{
		return 0;
	}
	else
	{
		return static_cast<unsigned int>(maxf * x + 0.5f);
	}
}

template<const int n>
inline int snorm(float x)
{
	static const unsigned int min = 0x80000000 >> (32 - n);
	static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
	static const float maxf = static_cast<float>(max);
	static const unsigned int range = 0xFFFFFFFF >> (32 - n);

	if(x >= 0.0f)
	{
		if(x >= 1.0f)
		{
			return max;
		}
		else
		{
			return static_cast<int>(maxf * x + 0.5f);
		}
	}
	else
	{
		if(x <= -1.0f)
		{
			return min;
		}
		else
		{
			return static_cast<int>(maxf * x - 0.5f) & range;
		}
	}
}

template<const int n>
inline unsigned int ucast(float x)
{
	static const unsigned int max = 0xFFFFFFFF >> (32 - n);
	static const float maxf = static_cast<float>(max);

	if(x >= maxf)
	{
		return max;
	}
	else if(x <= 0.0f)
	{
		return 0;
	}
	else
	{
		return static_cast<unsigned int>(x + 0.5f);
	}
}

template<const int n>
inline int scast(float x)
{
	static const unsigned int min = 0x80000000 >> (32 - n);
	static const unsigned int max = 0xFFFFFFFF >> (32 - n + 1);
	static const float maxf = static_cast<float>(max);
	static const float minf = static_cast<float>(min);
	static const unsigned int range = 0xFFFFFFFF >> (32 - n);

	if(x > 0.0f)
	{
		if(x >= maxf)
		{
			return max;
		}
		else
		{
			return static_cast<int>(x + 0.5f);
		}
	}
	else
	{
		if(x <= -minf)
		{
			return min;
		}
		else
		{
			return static_cast<int>(x - 0.5f) & range;
		}
	}
}

inline float sRGBtoLinear(float c)
{
	if(c <= 0.04045f)
	{
		return c * 0.07739938f;   // 1.0f / 12.92f;
	}
	else
	{
		return powf((c + 0.055f) * 0.9478673f, 2.4f);   // 1.0f / 1.055f
	}
}

inline float linearToSRGB(float c)
{
	if(c <= 0.0031308f)
	{
		return c * 12.92f;
	}
	else
	{
		return 1.055f * powf(c, 0.4166667f) - 0.055f;   // 1.0f / 2.4f
	}
}

unsigned char sRGB8toLinear8(unsigned char value);

uint64_t FNV_1a(const unsigned char *data, int size);   // Fowler-Noll-Vo hash function

// Round up to the next multiple of alignment
template<typename T>
inline T align(T value, unsigned int alignment)
{
	return ((value + alignment - 1) / alignment) * alignment;
}

template<unsigned int alignment, typename T>
inline T align(T value)
{
	return ((value + alignment - 1) / alignment) * alignment;
}

inline int clampToSignedInt(unsigned int x)
{
	return static_cast<int>(min(x, 0x7FFFFFFFu));
}

// Convert floating value v to fixed point with p digits after the decimal point
constexpr int toFixedPoint(float v, int p) {
	return static_cast<int>(v * (1 << p));
}

}  // namespace sw

#endif   // sw_Math_hpp
