///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2005-12-24
// Updated : 2011-10-13
// Licence : This source is under MIT License
// File    : glm/gtx/integer.inl
///////////////////////////////////////////////////////////////////////////////////////////////////

namespace glm
{
	// pow
	GLM_FUNC_QUALIFIER int pow(int x, int y)
	{
		if(y == 0)
			return 1;
		int result = x;
		for(int i = 1; i < y; ++i)
			result *= x;
		return result;
	}

	// sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
	GLM_FUNC_QUALIFIER int sqrt(int x)
	{
		if(x <= 1) return x;

		int NextTrial = x >> 1;
		int CurrentAnswer;

		do
		{
			CurrentAnswer = NextTrial;
			NextTrial = (NextTrial + x / NextTrial) >> 1;
		} while(NextTrial < CurrentAnswer);

		return CurrentAnswer;
	}

// Henry Gordon Dietz: http://aggregate.org/MAGIC/
namespace detail
{
	GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
	{
		/* 32-bit recursive reduction using SWAR...
		but first step is mapping 2-bit values
		into sum of 2 1-bit values in sneaky way
		*/
		x -= ((x >> 1) & 0x55555555);
		x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
		x = (((x >> 4) + x) & 0x0f0f0f0f);
		x += (x >> 8);
		x += (x >> 16);
		return(x & 0x0000003f);
	}

	template <>
	struct compute_log2<false>
	{
		template <typename T>
		GLM_FUNC_QUALIFIER T operator() (T const & Value) const
		{
#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
			return Value <= static_cast<T>(1) ? T(0) : T(32) - nlz(Value - T(1));
#else
			return T(32) - nlz(Value - T(1));
#endif
		}
	};
}//namespace _detail

	// Henry Gordon Dietz: http://aggregate.org/MAGIC/
/*
	GLM_FUNC_QUALIFIER unsigned int floor_log2(unsigned int x)
	{
		x |= (x >> 1);
		x |= (x >> 2);
		x |= (x >> 4);
		x |= (x >> 8);
		x |= (x >> 16);

		return _detail::ones32(x) >> 1;
	}
*/
	// mod
	GLM_FUNC_QUALIFIER int mod(int x, int y)
	{
		return x - y * (x / y);
	}

	// factorial (!12 max, integer only)
	template <typename genType>
	GLM_FUNC_QUALIFIER genType factorial(genType const & x)
	{
		genType Temp = x;
		genType Result;
		for(Result = 1; Temp > 1; --Temp)
			Result *= Temp;
		return Result;
	}

	template <typename T, precision P>
	GLM_FUNC_QUALIFIER detail::tvec2<T, P> factorial(
		detail::tvec2<T, P> const & x)
	{
		return detail::tvec2<T, P>(
			factorial(x.x),
			factorial(x.y));
	}

	template <typename T, precision P>
	GLM_FUNC_QUALIFIER detail::tvec3<T, P> factorial(
		detail::tvec3<T, P> const & x)
	{
		return detail::tvec3<T, P>(
			factorial(x.x),
			factorial(x.y),
			factorial(x.z));
	}

	template <typename T, precision P>
	GLM_FUNC_QUALIFIER detail::tvec4<T, P> factorial(
		detail::tvec4<T, P> const & x)
	{
		return detail::tvec4<T, P>(
			factorial(x.x),
			factorial(x.y),
			factorial(x.z),
			factorial(x.w));
	}

	GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
	{
		uint result = x;
		for(uint i = 1; i < y; ++i)
			result *= x;
		return result;
	}

	GLM_FUNC_QUALIFIER uint sqrt(uint x)
	{
		if(x <= 1) return x;

		uint NextTrial = x >> 1;
		uint CurrentAnswer;

		do
		{
			CurrentAnswer = NextTrial;
			NextTrial = (NextTrial + x / NextTrial) >> 1;
		} while(NextTrial < CurrentAnswer);

		return CurrentAnswer;
	}

	GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
	{
		return x - y * (x / y);
	}

#if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))

	GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
	{
		return 31u - findMSB(x);
	}

#else

	// Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
	GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
	{
		int y, m, n;

		y = -int(x >> 16);      // If left half of x is 0,
		m = (y >> 16) & 16;  // set n = 16.  If left half
		n = 16 - m;          // is nonzero, set n = 0 and
		x = x >> m;          // shift x right 16.
							// Now x is of the form 0000xxxx.
		y = x - 0x100;       // If positions 8-15 are 0,
		m = (y >> 16) & 8;   // add 8 to n and shift x left 8.
		n = n + m;
		x = x << m;

		y = x - 0x1000;      // If positions 12-15 are 0,
		m = (y >> 16) & 4;   // add 4 to n and shift x left 4.
		n = n + m;
		x = x << m;

		y = x - 0x4000;      // If positions 14-15 are 0,
		m = (y >> 16) & 2;   // add 2 to n and shift x left 2.
		n = n + m;
		x = x << m;

		y = x >> 14;         // Set y = 0, 1, 2, or 3.
		m = y & ~(y >> 1);   // Set m = 0, 1, 2, or 2 resp.
		return unsigned(n + 2 - m);
	}

#endif//(GLM_COMPILER)

}//namespace glm
