/** \file
 *
 *  Contains the Units class declaration.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

/** \defgroup units Units
 *
 *  One of the error-mitigating requirements of the LRAUV is to use engineering
 *  units for values throughout the system.  This reduces chance of entering
 *  (for example) 10 meters as an argument when 10 kilometers was intended.
 */

#ifndef UNITS_H_
#define UNITS_H_

#include "units/Unit.h"
#include "utils/AuvMath.h"

#ifdef PASCAL  // A workaround for windef.h
#undef PASCAL
#endif

class DataValue;
/**
 *  Static collection of standard engineering Units
 *  Can use UnitRegistry to look these up by name
 *
 *  \ingroup units
 */
class Units
{
public:

    // SI base Units
    static const BaseUnit AMPERE;
    static const BaseUnit CANDELA;
    static const BaseUnit KELVIN;
    static const BaseUnit KILOGRAM;
    static const BaseUnit METER;
    static const BaseUnit SECOND;
    static const BaseUnit MOLE;

    // named SI derived base Units
    static const BaseUnit BECQUEREL;
    static const BaseUnit COULOMB;
    static const BaseUnit FARAD;
    static const BaseUnit GRAY;
    static const BaseUnit HENRY;
    static const BaseUnit HERTZ;
    static const BaseUnit JOULE;
    static const BaseUnit KATAL;
    static const BaseUnit LUMEN;
    static const BaseUnit LUX;
    static const BaseUnit NEWTON;
    static const BaseUnit OHM;
    static const BaseUnit PASCAL;
    static const BaseUnit RADIAN;
    static const BaseUnit SIEMENS;
    static const BaseUnit SIEVERT;
    static const BaseUnit STERADIAN;
    static const BaseUnit TESLA;
    static const BaseUnit VOLT;
    static const BaseUnit WATT;
    static const BaseUnit WEBER;

    // derived SI Units
    static const BaseUnit AMPERE_SECOND;
    static const BaseUnit AMPERE_SECOND_METER_SQUARED_PER_MOLE;
    static const BaseUnit AMPERE_PER_METER;
    static const BaseUnit AMPERE_PER_SQUARE_METER;
    static const BaseUnit CANDELA_PER_SQUARE_METER;
    static const BaseUnit CUBIC_METER;
    static const BaseUnit CUBIC_METER_PER_KILOGRAM;
    static const BaseUnit CUBIC_METER_PER_SECOND;
    static const BaseUnit CUBIC_METER_SECOND;
    static const BaseUnit KELVIN_PER_METER;
    static const BaseUnit KILOGRAM_METER;
    static const BaseUnit KILOGRAM_METER_SQUARED;
    static const BaseUnit KILOGRAM_PER_CUBIC_METER;
    static const BaseUnit KILOGRAM_PER_KILOGRAM;
    static const BaseUnit KILOGRAM_PER_METER;
    static const BaseUnit METER_PER_RADIAN;
    static const BaseUnit METER_PER_SECOND;
    static const BaseUnit METER_PER_SECOND_SQUARED;
    static const BaseUnit MOLE_PER_CUBIC_METER;
    static const BaseUnit MOLE_PER_SECOND_PER_SQUARE_METER;
    static const BaseUnit MOLE_PER_SECOND_PER_SQUARE_METER_PER_AMPERE;
    static const BaseUnit NEWTON_METER;
    static const BaseUnit PASCAL_PER_PASCAL;
    static const BaseUnit PASCAL_PER_VOLT;
    static const BaseUnit RADIAN_PER_METER;
    static const BaseUnit RADIAN_PER_SECOND;
    static const BaseUnit RADIAN_PER_SECOND_PER_METER;
    static const BaseUnit RADIAN_PER_SECOND_SQUARED;
    static const BaseUnit RADIAN_SECOND_PER_METER;
    static const BaseUnit RECIPROCAL_METER;
    static const BaseUnit RECIPROCAL_METER_PER_STERADIAN;
    static const BaseUnit RECIPROCAL_SECOND;
    static const BaseUnit SIEMENS_PER_METER;
    static const BaseUnit SQUARE_METER;
    static const BaseUnit SQUARE_METER_PER_SECOND;

    // Non-SI Units accepted for use with the International System of Units
    static const Unit ANGULAR_DEGREE;
    static const Unit ANGULAR_MINUTE;
    static const Unit ANGULAR_SECOND;
    static const Unit CELSIUS;
    static const Unit DAY;
    static const Unit HOUR;
    static const Unit LITER;
    static const Unit LITRE;
    static const Unit MINUTE;
    static const Unit HECTARE;
    static const Unit TONNE;

    // prefixed SI (base, derived, & accepted non-SI) Units
    static const Unit AMPERE_HOUR;
    static const Unit ANGULAR_DEGREE_PER_SECOND;
    static const Unit ANGULAR_DEGREE_PER_SECOND_SQUARED;
    static const Unit ANGULAR_MINUTE_PER_SECOND;
    static const Unit CENTIMETER;
    static const Unit CENTIMETER_PER_SECOND;
    static const Unit CUBIC_CENTIMETER;
    static const Unit CUBIC_CENTIMETER_PER_METER;
    static const Unit CUBIC_CENTIMETER_PER_METER_PER_SECOND;
    static const Unit CUBIC_CENTIMETER_PER_SECOND;
    static const Unit LITER_PER_SECOND;
    static const Unit CUBIC_CENTIMETER_SECOND;
    static const Unit CUBIC_CENTIMETER_SECOND_PER_METER;
    static const Unit DEGREE;
    static const Unit DEGREE_PER_SECOND;
    static const Unit DECIBAR;
    static const Unit GRAM;
    static const Unit GRAM_PER_CUBIC_CENTIMETER;
    static const Unit GRAM_PER_KILOGRAM;
    static const Unit KILOJOULE;
    static const Unit KILOMETER;
    static const Unit KILOPASCAL;
    static const Unit KILOWATT;
    static const Unit KILOWATT_HOUR;
    static const Unit MEGAJOULE;
    static const Unit MICROAMPERE;
    static const Unit MICROBAR;
    static const Unit MICROGRAM;
    static const Unit MICROGRAM_PER_LITER;
    static const Unit MICROJOULE;
    static const Unit MICROMOLE;
    static const Unit MICROMOLE_PER_CUBIC_METER;
    static const Unit MICROMOLE_PER_SECOND_PER_SQUARE_METER;
    static const Unit MICROMOLE_PER_SECOND_PER_SQUARE_METER_PER_MICROAMPERE;
    static const Unit MICROMOLE_PER_LITER;
    static const Unit MICROPASCAL;
    static const Unit MICROSECOND;
    static const Unit MICROTESLA;
    static const Unit MICROVOLT;
    static const Unit MICROWATT;
    static const Unit MICROWATT_HOUR;
    static const Unit MILLIAMPERE;
    static const Unit MILLIAMPERE_HOUR;
    static const Unit MILLIGRAM;
    static const Unit MILLIGRAM_PER_CUBIC_METER;
    static const Unit MILLIGRAM_PER_LITER;
    static const Unit MILLIJOULE;
    static const Unit MILLILITER;
    static const Unit MILLIMETER;
    static const Unit MILLIMETER_PER_SECOND;
    static const Unit MILLIMHO_PER_CENTIMETER;
    static const Unit MILLISECOND;
    static const Unit MILLIVOLT;
    static const Unit MILLIWATT;
    static const Unit MILLIWATT_HOUR;
    static const Unit PHOTON_PER_SECOND;
    static const Unit WATT_HOUR;

    // non-SI physical Units
    static const Unit ATMOSPHERE;
    static const Unit FAHRENHEIT;
    static const Unit CELSIUS_PER_METER;
    static const Unit FLUID_OUNCE;
    static const Unit FOOT;
    static const Unit FOOT_PER_SECOND;
    static const Unit GALLON;
    static const Unit GAUSS;
    static const Unit INCH;
    static const Unit INCH_PER_SECOND;
    static const Unit KILOGRAM_FORCE;
    static const Unit KNOT;
    static const Unit MILE;
    static const Unit MILE_PER_HOUR;
    static const Unit MILLIGAUSS;
    static const Unit NAUTICAL_MILE;
    static const Unit OUNCE_FORCE;
    static const Unit OUNCE_MASS;
    static const Unit PARTIAL_PRESSURE_PERCENT;
    static const Unit POUND_FORCE;
    static const Unit POUND_MASS;
    static const Unit POUND_PER_SQUARE_INCH;
    static const Unit POUND_PER_SQUARE_INCH_PER_VOLT;
    static const Unit PRACTICAL_SALINITY_UNIT;
    static const Unit REVOLUTION_PER_MINUTE;
    static const Unit REVOLUTION_PER_SECOND;
    static const Unit SIGMA_T;

    // Non-physical Units
    static const BaseUnit BYTE;
    static const BaseUnit BYTE_PER_SECOND;
    static const BaseUnit DECIBEL;
    static const BaseUnit NONE_UCHAR;
    static const BaseUnit NONE_SHORT;
    static const BaseUnit NONE_USHORT;
    static const BaseUnit NONE_INT;
    static const BaseUnit NONE_FLOAT;
    static const BaseUnit NONE_DOUBLE;
    static const BaseUnit NONE; // Default overloads NONE_DOUBLE
    static const BaseUnit RATIO;

    // Derivatios of non-phisical Units
    static const Unit BIT;
    static const Unit BIT_PER_SECOND;
    static const Unit GIGABYTE;
    static const Unit KILOBIT_PER_SECOND;
    static const Unit KILOBYTE;
    static const Unit KILOBYTE_PER_SECOND;
    static const Unit MEGABIT_PER_SECOND;
    static const Unit MEGABYTE;
    static const Unit MEGABYTE_PER_SECOND;
    static const Unit PART_PER_BILLION;
    static const Unit PART_PER_MILLION;
    static const Unit PART_PER_THOUSAND;
    static const Unit PERCENT;

    // Pure counting Units
    static const BaseUnit BOOL;
    static const BaseUnit COUNT;
    static const BaseUnit ENUM;

    /// Combinations of physical and counting Units
    static const BaseUnit AMPERE_PER_COUNT;
    static const BaseUnit COUNT_PER_CUBIC_METER;
    static const BaseUnit COUNT_PER_KILOGRAM;
    static const BaseUnit COUNT_PER_METER;
    static const BaseUnit COUNT_PER_NEWTON;
    static const BaseUnit COUNT_PER_RADIAN;
    static const BaseUnit COUNT_PER_SECOND;
    static const BaseUnit PER_COUNT;
    static const BaseUnit RECIPROCAL_METER_PER_STERADIAN_PER_COUNT;

    /// Derivations involving counting Units
    static const Unit COUNT_PER_ANGULAR_DEGREE;
    static const Unit COUNT_PER_CUBIC_CENTIMETER;
    static const Unit COUNT_PER_GRAM;
    static const Unit COUNT_PER_MILLIGRAM;
    static const Unit COUNT_PER_MILLILITER;
    static const Unit COUNT_PER_MILLIMETER;
    static const Unit COUNT_PER_REVOLUTION;
    static const Unit MICROAMPERE_PER_COUNT;
    static const Unit MICROGRAM_PER_LITER_PER_COUNT;
    static const Unit PART_PER_BILLION_PER_COUNT;

    // Time mappings
    static const Unit EPOCH_SECOND;
    static const Unit MATLAB_TIME;

};

#endif /*UNITS_H_*/
