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

#include "UniversalURI.h"

#include "data/Slate.h"
#include "logger/Logger.h"

/// Protected Constructor
UniversalURI::UniversalURI( unsigned short code, const char* fullURI,
                            const Unit& unit, BinaryDataType binaryType,
                            BlobType blobType, unsigned short dimension1,
                            unsigned short dimension2, unsigned short dimension3 )
    : ElementURI( code, "", fullURI, UNIVERSAL_ELEMENT, unit, binaryType,
                  blobType, dimension1, dimension2, dimension3 )
{
    //Slate::CodifyElementURI( *this );
}

/// Protected Constructor
UniversalURI::UniversalURI( const char* fullURI,
                            const Unit& unit, BinaryDataType binaryType,
                            BlobType blobType, unsigned short dimension1,
                            unsigned short dimension2, unsigned short dimension3 )
    : ElementURI( "", fullURI, UNIVERSAL_ELEMENT, unit, binaryType,
                  blobType, dimension1, dimension2, dimension3 )
{
    Slate::CodifyElementURI( *this );
}

/// Destructor
UniversalURI::~UniversalURI()
{}

UniversalURI* UniversalURI::FindURI( const Str& name )
{
    ElementURI* uri = ElementURI::FindURI( name );
    if( NULL != uri && uri->isUniversal() )
    {
        return ( UniversalURI* )uri;
    }
    return NULL;
}

UniversalURI* UniversalURI::FindURI( const char* name )
{
    return FindURI( Str( name ) );
}

const Str UniversalURI::NAME( "Universal" );

/*const UniversalURI UniversalURI::NONE( "" );*/
// TODO: make sure each of these definitions has units (and possibly a description field)
// TODO: should these be separated out into UniversalURIIF.h like has been done for other components?
const UniversalURI UniversalURI::ACOUSTIC_RECEIVE_TIME( "acoustic_receive_time", Units::EPOCH_SECOND );
const UniversalURI UniversalURI::ACOUSTIC_TRANSMIT_TIME( "acoustic_transmit_time", Units::EPOCH_SECOND );
const UniversalBlobURI UniversalURI::ACOUSTIC_CONTACT_DIRECTION_VF( "acoustic_contact_direction_vehicle_frame", Units::NONE, BLOB_FLOAT64LE, 3 );
const UniversalURI UniversalURI::ACOUSTIC_CONTACT_ADDRESS_READING( "acoustic_contact_address", Units::ENUM );
const UniversalURI UniversalURI::ACOUSTIC_CONTACT_RANGE_READING( "acoustic_contact_range", Units::METER );
const UniversalURI UniversalURI::CONCENTRATION_OF_COLORED_DISSOLVED_ORGANIC_MATTER_IN_SEA_WATER( "concentration_of_colored_dissolved_organic_matter_in_sea_water", Units::PART_PER_BILLION );
const UniversalURI UniversalURI::DEPTH( "depth", Units::METER );
const UniversalURI UniversalURI::DEPTH_RATE( "depth_rate", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::DIRECTION_OF_SEA_WATER_VELOCITY( "direction_of_sea_water_velocity", Units::RADIAN );
const UniversalURI UniversalURI::DISTANCE_FROM_SHORE( "distance_from_shore", Units::METER );
const UniversalURI UniversalURI::DOWNWELLING_PHOTOSYNTHETIC_PHOTON_FLUX_IN_SEA_WATER( "downwelling_photosynthetic_photon_flux_in_sea_water", Units::MICROMOLE_PER_SECOND_PER_SQUARE_METER );
const UniversalURI UniversalURI::DOWNWARD_SEA_WATER_VELOCITY( "downward_sea_water_velocity", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::EASTWARD_SEA_WATER_VELOCITY( "eastward_sea_water_velocity", Units::METER_PER_SECOND );
//const UniversalURI UniversalURI::ELAPSED_TIME_SINCE_ORIENTATION_READ( "elapsed_time_since_orientation_read", Units::SECOND );
//const UniversalURI UniversalURI::ELAPSED_TIME_SINCE_VELOCITY_READ( "elapsed_time_since_velocity_read", Units::SECOND );
const UniversalURI UniversalURI::FIX_DISTANCE_MADE_GOOD( "fix_distance_made_good", Units::METER );
const UniversalURI UniversalURI::FIX_HORIZONTAL_PATH_LENGTH_SINCE_LAST_FIX( "fix_horizontal_path_length_since_last_fix", Units::METER );
const UniversalURI UniversalURI::FIX_RESIDUAL_DISTANCE( "fix_residual_distance", Units::METER );
const UniversalURI UniversalURI::FIX_RESIDUAL_BEARING( "fix_residual_bearing", Units::RADIAN );
const UniversalURI UniversalURI::FIX_RESIDUAL_PERCENT_DISTANCE_TRAVELED( "fix_residual_percent_distance_traveled", Units::PERCENT );
const UniversalURI UniversalURI::GRID_LATITUDE( "grid_latitude", Units::METER, DOUBLE6 );
const UniversalURI UniversalURI::GRID_LONGITUDE( "grid_longitude", Units::METER, DOUBLE6 );
const UniversalURI UniversalURI::HEIGHT_ABOVE_SEA_FLOOR( "height_above_sea_floor", Units::METER );
const UniversalURI UniversalURI::HORIZONTAL_PATH_LENGTH_SINCE_LAST_FIX( "horizontal_path_length_since_last_fix", Units::METER );
const UniversalURI UniversalURI::NORTHWARD_SEA_WATER_VELOCITY( "northward_sea_water_velocity", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::LATITUDE( "latitude", Units::DEGREE, DOUBLE6 );
const UniversalURI UniversalURI::LATITUDE_FIX( "latitude_fix", Units::DEGREE, DOUBLE6 );
const UniversalBlobURI UniversalURI::LOCATION_FIX( "location_fix", Units::DEGREE, BLOB_FLOAT64LE, 2 );
const UniversalURI UniversalURI::LONGITUDE( "longitude", Units::DEGREE, DOUBLE6 );
const UniversalURI UniversalURI::LONGITUDE_FIX( "longitude_fix", Units::DEGREE, DOUBLE6 );
const UniversalURI UniversalURI::MISSION_STARTED( "mission_started", Units::COUNT );
const UniversalURI UniversalURI::MASS_CONCENTRATION_OF_CHLOROPHYLL_IN_SEA_WATER( "mass_concentration_of_chlorophyll_in_sea_water", Units::MICROGRAM_PER_LITER );
const UniversalURI UniversalURI::MASS_CONCENTRATION_OF_OXYGEN_IN_SEA_WATER( "mass_concentration_of_oxygen_in_sea_water", Units::MICROGRAM_PER_LITER );
const UniversalURI UniversalURI::MASS_CONCENTRATION_OF_PETROLEUM_HYDROCARBONS_IN_SEA_WATER( "mass_concentration_of_petroleum_hydrocarbons_in_sea_water", Units::KILOGRAM_PER_CUBIC_METER );
const UniversalURI UniversalURI::MOLE_CONCENTRATION_OF_NITRATE_IN_SEA_WATER( "mole_concentration_of_nitrate_in_sea_water", Units::MICROMOLE_PER_LITER );
const UniversalURI UniversalURI::PLATFORM_AVERAGE_CURRENT( "platform_average_current", Units::MILLIAMPERE );
const UniversalURI UniversalURI::PLATFORM_AVERAGE_POWER( "platform_average_power", Units::WATT );
const UniversalURI UniversalURI::PLATFORM_BATTERY_CHARGE( "platform_battery_charge", Units::AMPERE_HOUR );
const UniversalURI UniversalURI::PLATFORM_BATTERY_CHARGE_USAGE( "platform_battery_charge_usage" );
const UniversalURI UniversalURI::PLATFORM_BATTERY_ENERGY_USAGE( "platform_battery_energy_usage" );
const UniversalURI UniversalURI::PLATFORM_BATTERY_VOLTAGE( "platform_battery_voltage", Units::VOLT );
const UniversalURI UniversalURI::PLATFORM_BATTERY_FULLY_CHARGED( "platform_battery_fully_charged", Units::BOOL );
const UniversalURI UniversalURI::PLATFORM_BATTERY_DISCHARGING( "platform_battery_discharging", Units::BOOL );
const UniversalURI UniversalURI::PLATFORM_BUOYANCY_POSITION( "platform_buoyancy_position", Units::CUBIC_CENTIMETER );
const UniversalURI UniversalURI::PLATFORM_COMMUNICATIONS( "platform_communications", Units::BOOL );
const UniversalURI UniversalURI::PLATFORM_CONVERSATION( "platform_conversation", Units::BOOL );
const UniversalURI UniversalURI::PLATFORM_COURSE( "platform_course" );
const UniversalURI UniversalURI::PLATFORM_DISTANCE_WRT_GROUND( "platform_distance_wrt_ground", Units::METER );
const UniversalURI UniversalURI::PLATFORM_DISTANCE_WRT_SEA_WATER( "platform_distance_wrt_sea_water", Units::METER );
const UniversalURI UniversalURI::PLATFORM_ELEVATOR_ANGLE( "platform_elevator_angle", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_FAULT( "platform_fault", Units::ENUM );
const UniversalURI UniversalURI::PLATFORM_FAULT_LEAK( "platform_fault_leak", Units::ENUM );
const UniversalURI UniversalURI::PLATFORM_MAGNETIC_ORIENTATION( "platform_magnetic_orientation", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_MASS_POSITION( "platform_mass_position", Units::METER );
const UniversalURI UniversalURI::PLATFORM_ORIENTATION( "platform_orientation", Units::RADIAN );
const UniversalBlobURI UniversalURI::PLATFORM_ORIENTATION_MATRIX( "platform_orientation_matrix", Units::NONE, BLOB_FLOAT64LE, 3, 3 );
const UniversalURI UniversalURI::PLATFORM_PITCH_ANGLE( "platform_pitch_angle", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_PITCH_RATE( "platform_pitch_rate", Units::RADIAN_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_PRESSURE( "platform_pressure" );
const UniversalURI UniversalURI::PLATFORM_PROPELLER_ROTATION_RATE( "platform_propeller_rotation_rate", Units::RADIAN_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_RELATIVE_HUMIDITY( "platform_relative_humidity" );
const UniversalURI UniversalURI::PLATFORM_ROLL_ANGLE( "platform_roll_angle", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_ROLL_RATE( "platform_roll_rate", Units::RADIAN_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_RUDDER_ANGLE( "platform_rudder_angle", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_SPEED_WRT_GROUND( "platform_speed_wrt_ground", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_SPEED_WRT_SEA_WATER( "platform_speed_wrt_sea_water", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_TEMPERATURE( "platform_temperature" );
const UniversalURI UniversalURI::PLATFORM_VEHICLE_POWER( "platform_vehicle_power", Units::WATT );
const UniversalBlobURI UniversalURI::PLATFORM_VELOCITY_WRT_GROUND( "platform_velocity_wrt_ground", Units::METER_PER_SECOND, BLOB_FLOAT64LE, 3 );
const UniversalBlobURI UniversalURI::PLATFORM_VELOCITY_WRT_SEA_WATER( "platform_velocity_wrt_sea_water", Units::METER_PER_SECOND, BLOB_FLOAT64LE, 3 );
const UniversalURI UniversalURI::PLATFORM_X_SEA_WATER_VELOCITY( "platform_x_sea_water_velocity", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_X_VELOCITY_WRT_GROUND( "platform_x_velocity_wrt_ground", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_X_VELOCITY_WRT_SEA_WATER( "platform_x_velocity_wrt_sea_water", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_X_VELOCITY_CURRENT( "platform_x_velocity_current", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Y_SEA_WATER_VELOCITY( "platform_y_sea_water_velocity", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Y_VELOCITY_WRT_GROUND( "platform_y_velocity_wrt_ground", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Y_VELOCITY_WRT_SEA_WATER( "platform_y_velocity_wrt_sea_water", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Y_VELOCITY_CURRENT( "platform_y_velocity_current", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_YAW_ANGLE( "platform_yaw_angle", Units::RADIAN );
const UniversalURI UniversalURI::PLATFORM_YAW_RATE( "platform_yaw_rate", Units::RADIAN_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Z_SEA_WATER_VELOCITY( "platform_z_sea_water_velocity", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Z_VELOCITY_WRT_GROUND( "platform_z_velocity_wrt_ground", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Z_VELOCITY_WRT_SEA_WATER( "platform_z_velocity_wrt_sea_water", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PLATFORM_Z_VELOCITY_CURRENT( "platform_z_velocity_current", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::PROJECTION_X_COORDINATE( "projection_x_coordinate" );
const UniversalURI UniversalURI::PROJECTION_Y_COORDINATE( "projection_y_coordinate" );
const UniversalURI UniversalURI::PROJECTION_ZONE( "projection_zone" );
const UniversalURI UniversalURI::SEA_FLOOR_DEPTH_BELOW_GEOID( "sea_floor_depth_below_geoid", Units::METER );
const UniversalURI UniversalURI::SEA_WATER_DENSITY( "sea_water_density", Units::KILOGRAM_PER_CUBIC_METER );
const UniversalURI UniversalURI::SEA_WATER_ELECTRICAL_CONDUCTIVITY( "sea_water_electrical_conductivity", Units::SIEMENS_PER_METER );
const UniversalURI UniversalURI::SEA_WATER_POTENTIAL_DENSITY( "sea_water_potential_density" );
const UniversalURI UniversalURI::SEA_WATER_POTENTIAL_TEMPERATURE( "sea_water_potential_temperature" );
const UniversalURI UniversalURI::SEA_WATER_PRESSURE( "sea_water_pressure", Units::DECIBAR ); // decibar units consistent with old writer definition in driver for Depth_Keller.cpp
const UniversalURI UniversalURI::SEA_WATER_RHODAMINE( "sea_water_rhodamine", Units::PART_PER_BILLION );
const UniversalURI UniversalURI::SEA_WATER_SALINITY( "sea_water_salinity", Units::PRACTICAL_SALINITY_UNIT );
const UniversalURI UniversalURI::SEA_WATER_SIGMA_T( "sea_water_sigma_t" );
const UniversalURI UniversalURI::SEA_WATER_SIGMA_THETA( "sea_water_sigma_theta" );
const UniversalURI UniversalURI::SEA_WATER_SPEED( "sea_water_speed" );
const UniversalURI UniversalURI::SEA_WATER_TEMPERATURE( "sea_water_temperature", Units::CELSIUS );
const UniversalURI UniversalURI::SPEED_OF_SOUND_IN_SEA_WATER( "speed_of_sound_in_sea_water", Units::METER_PER_SECOND );
const UniversalURI UniversalURI::SURFACE_EASTWARD_SEA_WATER_VELOCITY( "surface_eastward_sea_water_velocity", Units::METER_PER_SECOND ); // TODO: should this really be a universal?
const UniversalURI UniversalURI::SURFACE_NORTHWARD_SEA_WATER_VELOCITY( "surface_northward_sea_water_velocity", Units::METER_PER_SECOND ); // TODO: should this really be a universal?
const UniversalURI UniversalURI::TIME( "time", Units::SECOND, DOUBLE8 );
const UniversalURI UniversalURI::TIME_FIX( "time_fix", Units::SECOND, DOUBLE8 );
const UniversalURI UniversalURI::UPWARD_DERIVATIVE_OF_SEA_WATER_TEMPERATURE( "upward_derivative_of_sea_water_temperature", Units::CELSIUS_PER_METER );
const UniversalURI UniversalURI::VOLUME_BACKWARDS_SCATTERING_COEFFICIENT_OF_RADIATIVE_FLUX_IN_SEA_WATER( "volume_backwards_scattering_coefficient_of_radiative_flux_in_sea_water", Units::RECIPROCAL_METER );

//-----------------------------------------------------------------------------
// UniversalBlobURI's
//-----------------------------------------------------------------------------

/// Protected Constructor for use by ElementURI::Read
UniversalBlobURI::UniversalBlobURI( unsigned short code, const char* fullURI, const Unit& unit,
                                    BlobType blobType, unsigned short dimension1,
                                    unsigned short dimension2, unsigned short dimension3 )
    : UniversalURI( code, fullURI, unit, MULTIVALUE, blobType, dimension1, dimension2, dimension3 )
{}

/// Protected Constructor for use by static initializers
UniversalBlobURI::UniversalBlobURI( const char* fullURI, const Unit& unit = UNSPECIFIED_UNIT,
                                    BlobType blobType = NOT_BLOB, unsigned short dimension1,
                                    unsigned short dimension2, unsigned short dimension3 )
    : UniversalURI( fullURI, unit, MULTIVALUE, blobType, dimension1, dimension2, dimension3 )
{}
