//! \~\file piunits_prefix.h
//! \~\ingroup Units
//! \~\brief
//! \~english Unit prefixes
//! \~russian Префиксы единиц измерения
/*
    PIP - Platform Independent Primitives
    Unit prefix
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PIUNITS_PREFIX_H
#define PIUNITS_PREFIX_H

#include "pistring.h"

//! \~\ingroup Units
//! \~\brief
//! \~english Namespace containing unit prefix helpers.
//! \~russian Пространство имен со вспомогательными средствами префиксов единиц.
namespace PIUnits {

//! \~\ingroup Units
//! \~\brief
//! \~english Helpers for localized prefix names, symbols, and multipliers.
//! \~russian Вспомогательные методы для локализованных имен, обозначений и множителей префиксов.
class PIP_EXPORT Prefix {
	friend class Value;

public:
	//! \~english Supported SI prefixes.
	//! \~russian Поддерживаемые префиксы СИ.
	enum {
		None /** \~english No prefix \~russian Без префикса */,

		Deca = 0x100 /** \~english Deca prefix, 10^1 \~russian Префикс дека, 10^1 */,
		Hecto /** \~english Hecto prefix, 10^2 \~russian Префикс гекто, 10^2 */,
		Kilo /** \~english Kilo prefix, 10^3 \~russian Префикс кило, 10^3 */,
		Mega /** \~english Mega prefix, 10^6 \~russian Префикс мега, 10^6 */,
		Giga /** \~english Giga prefix, 10^9 \~russian Префикс гига, 10^9 */,
		Tera /** \~english Tera prefix, 10^12 \~russian Префикс тера, 10^12 */,
		Peta /** \~english Peta prefix, 10^15 \~russian Префикс пета, 10^15 */,
		Exa /** \~english Exa prefix, 10^18 \~russian Префикс экса, 10^18 */,
		Zetta /** \~english Zetta prefix, 10^21 \~russian Префикс зетта, 10^21 */,
		Yotta /** \~english Yotta prefix, 10^24 \~russian Префикс йотта, 10^24 */,
		Ronna /** \~english Ronna prefix, 10^27 \~russian Префикс ронна, 10^27 */,
		Quetta /** \~english Quetta prefix, 10^30 \~russian Префикс кветта, 10^30 */,

		Deci = 0x200 /** \~english Deci prefix, 10^-1 \~russian Префикс деци, 10^-1 */,
		Centi /** \~english Centi prefix, 10^-2 \~russian Префикс санти, 10^-2 */,
		Milli /** \~english Milli prefix, 10^-3 \~russian Префикс милли, 10^-3 */,
		Micro /** \~english Micro prefix, 10^-6 \~russian Префикс микро, 10^-6 */,
		Nano /** \~english Nano prefix, 10^-9 \~russian Префикс нано, 10^-9 */,
		Pico /** \~english Pico prefix, 10^-12 \~russian Префикс пико, 10^-12 */,
		Femto /** \~english Femto prefix, 10^-15 \~russian Префикс фемто, 10^-15 */,
		Atto /** \~english Atto prefix, 10^-18 \~russian Префикс атто, 10^-18 */,
		Zepto /** \~english Zepto prefix, 10^-21 \~russian Префикс зепто, 10^-21 */,
		Yocto /** \~english Yocto prefix, 10^-24 \~russian Префикс йокто, 10^-24 */,
		Ronto /** \~english Ronto prefix, 10^-27 \~russian Префикс ронто, 10^-27 */,
	};

	//! \~english Returns localized full name of prefix "prefix".
	//! \~russian Возвращает локализованное полное имя префикса "prefix".
	static PIString name(int prefix);

	//! \~english Returns localized short symbol of prefix "prefix".
	//! \~russian Возвращает локализованное короткое обозначение префикса "prefix".
	static PIString prefix(int prefix);

	//! \~english Returns numeric multiplier for prefix "prefix".
	//! \~russian Возвращает числовой множитель префикса "prefix".
	static double multiplier(int prefix);

private:
	Prefix();
	NO_COPY_CLASS(Prefix);
	static Prefix & instance();
	static PIString valueToString(double v, void * type_class, int type, char format = 'g', int prec = 5);

	struct P {
		PIString name;
		PIString prefix;
		int pow;
		double divider;
		bool non3;
	};

	const P getPrefix(int p) const;
	const P getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const;

	PIMap<int, P> prefixes;
	PIMap<int, P *> prefixes_by_pow;
	P def_prefix;
};

} // namespace PIUnits


#endif
