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

#ifndef glm_gtx_transform
#define glm_gtx_transform

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

namespace glm
{
	namespace test{
		void main_ext_gtx_transform();
	}//namespace test

    template <typename T> detail::tmat4x4<T> translateGTX(T x, T y, T z);
    template <typename T> detail::tmat4x4<T> translateGTX(const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> translateGTX(const detail::tmat4x4<T> & m, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> translateGTX(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> rotateGTX(T angle, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> rotateGTX(T angle, const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> rotateGTX(const detail::tmat4x4<T> & m, T angle, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> rotateGTX(const detail::tmat4x4<T> & m, T angle, const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> scaleGTX(T x, T y, T z);
    template <typename T> detail::tmat4x4<T> scaleGTX(const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> scaleGTX(const detail::tmat4x4<T> & m, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> scaleGTX(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v);

    // 3D
    template <typename T> detail::tmat4x4<T> translate3DGTX(const detail::tmat4x4<T> & m, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> translate3DGTX(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> rotate3DGTX(const detail::tmat4x4<T> & m, T angle, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> rotate3DGTX(const detail::tmat4x4<T> & m, T angle, const detail::tvec3<T> & v);
    template <typename T> detail::tmat3x3<T> rotate3DGTX(const detail::tmat3x3<T> & m, T angle, T x, T y, T z);
    template <typename T> detail::tmat3x3<T> rotate3DGTX(const detail::tmat3x3<T> & m, T angle, const detail::tvec3<T> & v);
    template <typename T> detail::tmat4x4<T> scale3DGTX(const detail::tmat4x4<T> & m, T x, T y, T z);
    template <typename T> detail::tmat4x4<T> scale3DGTX(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v);
    template <typename T> detail::tmat3x3<T> scale3DGTX(const detail::tmat3x3<T> & m, T x, T y, T z);
    template <typename T> detail::tmat3x3<T> scale3DGTX(const detail::tmat3x3<T> & m, const detail::tvec3<T> & v);

    // 2D
    template <typename T> detail::tmat3x3<T> translate2DGTX(const detail::tmat3x3<T> & m, T x, T y);
    template <typename T> detail::tmat3x3<T> translate2DGTX(const detail::tmat3x3<T> & m, const detail::tvec2<T> & v);
    template <typename T> detail::tmat3x3<T> rotate2DGTX(const detail::tmat3x3<T> & m, T angle);
    template <typename T> detail::tmat2x2<T> rotate2DGTX(const detail::tmat2x2<T> & m, T angle);
    template <typename T> detail::tmat3x3<T> scale2DGTX(const detail::tmat3x3<T> & m, T x, T y);
    template <typename T> detail::tmat3x3<T> scale2DGTX(const detail::tmat3x3<T> & m, const detail::tvec2<T> & v);
    template <typename T> detail::tmat2x2<T> scale2DGTX(const detail::tmat2x2<T> & m, T x, T y);
    template <typename T> detail::tmat2x2<T> scale2DGTX(const detail::tmat2x2<T> & m, const detail::tvec2<T> & v);

    namespace gtx
    {
		//! GLM_GTX_transform extension: Add transformation matrices
        namespace transform
        {
            template <typename T> inline detail::tmat4x4<T> translate(T x, T y, T z){return translateGTX(x, y, z);}                                          //!< /brief Builds a translation 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> translate(const detail::tvec3<T> & v){return translateGTX(v);}                                          //!< /brief Builds a translation 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> translate(const detail::tmat4x4<T> & m, T x, T y, T z){return translateGTX(m, x, y, z);}                  //!< /brief Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> translate(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v){return translateGTX(m, v);}                  //!< /brief Transforms a matrix with a translation 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate(T angle, T x, T y, T z){return rotateGTX(angle, x, y, z);}                                //!< /brief Builds a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate(T angle, const detail::tvec3<T> & v){return rotateGTX(angle, v);}                                //!< /brief Builds a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate(const detail::tmat4x4<T> & m, T angle, T x, T y, T z){return rotateGTX(m, angle, x, y, z);}        //!< /brief Transforms a matrix with a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate(const detail::tmat4x4<T> & m, T angle, const detail::tvec3<T> & v){return rotateGTX(m, angle, v);}        //!< /brief Transforms a matrix with a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale(T x, T y, T z){return scaleGTX(x, y, z);}                                                  //!< /brief Builds a scale 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale(const detail::tvec3<T> & v){return scaleGTX(v);}                                                  //!< /brief Builds a scale 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale(const detail::tmat4x4<T> & m, T x, T y, T z){return scaleGTX(m, x, y, z);}                          //!< /brief Transforms a matrix with a scale 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v){return scaleGTX(m, v);}                          //!< /brief Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)

            // 3D
            template <typename T> inline detail::tmat4x4<T> translate3D(const detail::tmat4x4<T> & m, T x, T y, T z){return translate3DGTX(m, x, y, z);}              //!< /brief Transforms a matrix with a translation 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> translate3D(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v){return translate3DGTX(m, v);}              //!< /brief Transforms a matrix with a translation 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate3D(const detail::tmat4x4<T> & m, T angle, T x, T y, T z){return rotate3DGTX(m, angle, x, y, z);}    //!< /brief Transforms a matrix with a rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> rotate3D(const detail::tmat4x4<T> & m, T angle, const detail::tvec3<T> & v){return rotate3DGTX(m, angle, v);}    //!< /brief Transforms a matrix with a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> rotate3D(const detail::tmat3x3<T> & m, T angle, T x, T y, T z){return rotate3DGTX(m, angle, x, y, z);}    //!< /brief Transforms a matrix with a rotation 3 * 3 matrix created from an axis of 3 scalars and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> rotate3D(const detail::tmat3x3<T> & m, T angle, const detail::tvec3<T> & v){return rotate3DGTX(m, angle, v);}    //!< /brief Transforms a matrix with a rotation 3 * 3 matrix created from an axis vector and an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale3D(const detail::tmat4x4<T> & m, T x, T y, T z){return scale3DGTX(m, x, y, z);}                      //!< /brief Transforms a matrix with a scale 4 * 4 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat4x4<T> scale3D(const detail::tmat4x4<T> & m, const detail::tvec3<T> & v){return scale3DGTX(m, v);}                      //!< /brief Transforms a matrix with a scale 4 * 4 matrix created from a vector of 3 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> scale3D(const detail::tmat3x3<T> & m, T x, T y, T z){return scale3DGTX(m, x, y, z);}                      //!< /brief Transforms a matrix with a scale 3 * 3 matrix created from 3 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> scale3D(const detail::tmat3x3<T> & m, const detail::tvec3<T> & v){return scale3DGTX(m, v);}                      //!< /brief Transforms a matrix with a scale 3 * 3 matrix created from a vector of 3 components (from GLM_GTX_transform extension)

            // 2D
            template <typename T> inline detail::tmat3x3<T> translate2D(const detail::tmat3x3<T> & m, T x, T y){return translate2DGTX(m, x, y);}                      //!< /brief Translates a 3 * 3 matrix from 2 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> translate2D(const detail::tmat3x3<T> & m, const detail::tvec2<T> & v){return translate2DGTX(m, v);}              //!< /brief Translates a 3 * 3 matrix from a vector of 2 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> rotate2D(const detail::tmat3x3<T> & m, T angle){return rotate2DGTX(m, angle);}                            //!< /brief Rotates a 3 * 3 matrix from an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat2x2<T> rotate2D(const detail::tmat2x2<T> & m, T angle){return rotate2DGTX(m, angle);}                            //!< /brief Rotates a 2 * 2 matrix from an angle expressed in degrees (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> scale2D(const detail::tmat3x3<T> & m, T x, T y){return scale2DGTX(m, x, y);}                              //!< /brief Scales a 3 * 3 matrix using 2 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat3x3<T> scale2D(const detail::tmat3x3<T> & m, const detail::tvec2<T> & v){return scale2DGTX(m, v);}                      //!< /brief Scales a 3 * 3 matrix using a vector of 2 components (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat2x2<T> scale2D(const detail::tmat2x2<T> & m, T x, T y){return scale2DGTX(m, x, y);}                              //!< /brief Scales a 2 * 2 matrix using 2 scalars (from GLM_GTX_transform extension)
            template <typename T> inline detail::tmat2x2<T> scale2D(const detail::tmat2x2<T> & m, const detail::tvec2<T> & v){return scale2DGTX(m, v);}                      //!< /brief Scales a 2 * 2 matrix using a vector of 2 components (from GLM_GTX_transform extension)
        }
    }
}

#define GLM_GTX_transform namespace gtx::transform

#include "transform.inl"

#endif//glm_gtx_transform
