/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmLog.h"
#include "glmStringOperators.h"
#include "glmAssert.h"

namespace glm
{
    /**
	* \brief represent the distance units available
	*
	* \ingroup conversions
	* \author Golaem <dev@golaem.com>
	*/
    struct distanceUnit
    {
    public:
        enum Value
        {
            METER = 0,
            DECIMETER,
            CENTIMETER,
            MILLIMETER,
            INCH, //http://en.wikipedia.org/wiki/Inch
            FEET, //http://en.wikipedia.org/wiki/Foot_%28length%29
            YARD, //http://en.wikipedia.org/wiki/Yard
            END
        };
    };

    /**
	* \brief get the unit as a string
	* \param unit unit
	* \return a string containing the unit name
	* \ingroup conversions
	* \author Golaem <dev@golaem.com>
	*/
    inline const char* toString(const distanceUnit::Value unit);

    /**
	* \brief get the unit from a string
	* \param unit string containing the unit
	* \return the unit enumerator value, or distanceUnit::END if the unit string is unknown
	* \ingroup conversions
	* \author Golaem <dev@golaem.com>
	*/
    inline distanceUnit::Value distanceUnitFromString(const glm::GlmString& unit);

    /**
	* \brief Get the scale factor from a given unit to the standard unit (meter)
	* \param unit unit to get the scale factor from
	* \return 
	* \ingroup conversions
	* \author Golaem <dev@golaem.com>
	*/
    float GLM_CORE_API getScaleFactor(distanceUnit::Value unit);

    /**
	* \brief Convert a distance from a unit to another
	* \param distance distance to convert
	* \param originalUnit the unit in which the distance is exprimed
	* \param finalUnit the unit to convert in
	* \return the distance converted in the finalUnit unit
	* \ingroup conversions
	* \author Golaem <dev@golaem.com>
	*/
    float GLM_CORE_API convert(const float& distance, distanceUnit::Value originalUnit, distanceUnit::Value finalUnit = distanceUnit::METER);

    //------------------------------------------------------------
    // toString
    //------------------------------------------------------------
    inline const char*
    toString(const distanceUnit::Value unit)
    {
        GLM_DEBUG_ASSERT(unit < 6);
        static const char* typeNames[] = {"meter", "centimeter", "millimeter", "inch", "feet", "yard", "unknown type"};
        return typeNames[unit];
    }

    //------------------------------------------------------------
    // toString
    //------------------------------------------------------------
    inline distanceUnit::Value
    distanceUnitFromString(const glm::GlmString& unit)
    {
        glm::GlmString unitInLowerCase(toLower(unit));
        for (distanceUnit::Value currentUnit = (distanceUnit::Value)0; currentUnit < distanceUnit::END; currentUnit = (distanceUnit::Value)(currentUnit + 1))
        {
            if (unitInLowerCase.compare(toString(currentUnit)) == 0)
                return currentUnit;
        }
        return distanceUnit::END;
    }
} // namespace glm
