#ifndef _quantity_h__
#define _quantity_h__

/** Quantity **
 * 
 * Measured quantity consisting of a numerical value and a measurement unit.
 * 
 */

#include <stdint.h>

#include "unit.h"

#ifdef __cplusplus
extern "C" {
#endif


/*
 * Type constants
 */
#define QUANTITY_TYPE_FLOAT  0
#define QUANTITY_TYPE_UINT32 1
#define QUANTITY_TYPE_INT32  2
#define QUANTITY_TYPE_ERROR  3


/**
 * Measured quantity consisting of a numerical value and a measurement unit.
 * 
 * The 32-bit value can be interpreted as a float or as an integer (signed or unsigned)
 * for maximum flexibility.
 */
typedef struct Quantity {

    unit_t unit;
    uint8_t type;

    union {
        float value_float;
        uint32_t value_uint32;
        int32_t value_int32;
        int32_t value_error;
    };

} Quantity;

/**
 * Default quantity with no data.
 */
extern const Quantity QUANTITY_NO_DATA;

/**
 * Return a Quantity's value as a double. The Quantity struct itself is not modified.
 */
double quantity_value_as_double(const Quantity *quantity);

/**
 * Convert a Quantity to a given unit and return 0 to indicate success.
 * If the conversion isn't possible (e.g. from mass to length), the quantity is left unmodified,
 * and a non-zero value is returned to indicate that an error occurred.
 */ 
int quantity_convert_to_unit(Quantity *quantity, unit_t dst_unit);

/**
 * Convert a Quantity to type float. Nothing is done if the quantity is already a float, or an error.
 */
void quantity_convert_to_float(Quantity *quantity);


#ifdef __cplusplus
}
#endif

#endif
