// 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<class T>
	inline void swap(T &a, T &b)
	{
		T t = a;
		a = b;
		b = t;
	}

	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
