// 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 "Half.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 max(T a, T b)
	{
		return a > b ? a : b;
	}

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

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

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

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

	template<class T>
	inline 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 float exp2(float x)
	{
		return exp2f(x);
	}

	inline int exp2(int x)
	{
		return 1 << x;
	}

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

	inline int ilog2(float x)
	{
		unsigned int y = *(unsigned int*)&x;

		return ((y & 0x7F800000) >> 23) - 127;
	}

	inline float log2(float x)
	{
		return logf(x) * 1.44269504f;   // 1.0 / log[e](2)
	}

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

	template<class T>
	inline T clamp(T x, T a, T 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));
	}
}

#endif   // sw_Math_hpp
