///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2005-12-24
// Updated : 2006-11-14
// Licence : This source is under MIT License
// File    : glm/gtx/integer.h
///////////////////////////////////////////////////////////////////////////////////////////////////
// Dependency:
// - GLM core
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef glm_gtx_integer
#define glm_gtx_integer

// Dependency:
#include "../../glm.h"

namespace glm
{
    int powGTX(int x, int y);
    template <typename T> T powGTX(T x, T y);
    template <typename T> detail::tvec2<T> powGTX(const detail::tvec2<T>& x, const detail::tvec2<T>& y);
    template <typename T> detail::tvec3<T> powGTX(const detail::tvec3<T>& x, const detail::tvec3<T>& y);
    template <typename T> detail::tvec4<T> powGTX(const detail::tvec4<T>& x, const detail::tvec4<T>& y);

    int sqrtGTX(int x);
    template <typename T> T sqrtGTX(T x);
    template <typename T> detail::tvec2<T> sqrtGTX(const detail::tvec2<T>& x);
    template <typename T> detail::tvec3<T> sqrtGTX(const detail::tvec3<T>& x);
    template <typename T> detail::tvec4<T> sqrtGTX(const detail::tvec4<T>& x);

	int modGTX(int x, int y);
    //template <typename T> T modGTX(T x, T y);
    template <typename T> detail::tvec2<T> modGTX(const detail::tvec2<T>& x, T y);
    template <typename T> detail::tvec3<T> modGTX(const detail::tvec3<T>& x, T y);
    template <typename T> detail::tvec4<T> modGTX(const detail::tvec4<T>& x, T y);
    template <typename T> detail::tvec2<T> modGTX(const detail::tvec2<T>& x, const detail::tvec2<T>& y);
    template <typename T> detail::tvec3<T> modGTX(const detail::tvec3<T>& x, const detail::tvec3<T>& y);
    template <typename T> detail::tvec4<T> modGTX(const detail::tvec4<T>& x, const detail::tvec4<T>& y);

    template <typename T> T factorialGTX(T x);
    template <typename T> detail::tvec2<T> factorialGTX(const detail::tvec2<T>& x);
    template <typename T> detail::tvec3<T> factorialGTX(const detail::tvec3<T>& x);
    template <typename T> detail::tvec4<T> factorialGTX(const detail::tvec4<T>& x);

	namespace gtx
	{
		//! GLM_GTX_integer extension: Add support for integer for core functions
		namespace integer
		{
			// Returns the dot product of x and y, i.e., result = x * y.
			// (From GLM_GTX_integer extension)
			//template <typename genType> 
			//typename genType::value_type dot(genType const & x, genType const & y);

			inline int pow(int x, int y){return powGTX(x, y);}																//!< \brief Returns x raised to the y power. (From GLM_GTX_integer extension)
			inline int sqrt(int x){return sqrtGTX(x);}																		//!< \brief Returns the positive square root of x. (From GLM_GTX_integer extension)
			inline int mod(int x, int y){return modGTX(x, y);}																//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. (From GLM_GTX_integer extension)
			template <typename T> inline T factorial(T x){return factorialGTX(x);}											//!< \brief Return the factorial value of a number (!12 max, integer only)
			template <typename T> inline detail::tvec2<T> factorial(const detail::tvec2<T>& x){return factorialGTX(x);}	//!< \brief Return the factorial value of a number (!12 max, integer only)
			template <typename T> inline detail::tvec3<T> factorial(const detail::tvec3<T>& x){return factorialGTX(x);}	//!< \brief Return the factorial value of a number (!12 max, integer only)
			template <typename T> inline detail::tvec4<T> factorial(const detail::tvec4<T>& x){return factorialGTX(x);}	//!< \brief Return the factorial value of a number (!12 max, integer only)
		}
	}
}

#define GLM_GTX_integer namespace gtx::integer

#include "integer.inl"

#endif//glm_gtx_integer
