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

#include "UnitRegistry.h"

#include "Unit.h"
#include "Units.h"
#include "utils/Str.h"

UnitRegistry* UnitRegistry::Instance_( NULL );

UnitRegistry::StaticDestructor UnitRegistry::StaticDestructor_;

UnitRegistry::StaticDestructor::~StaticDestructor()
{
    if( NULL != Instance_ )
    {
        delete Instance_;
    }
    Instance_ = NULL;
}

void UnitRegistry::AddUnit( const Unit* unit )
{
    if( dynamic_cast<UnitRegistry*>( Instance_ ) == NULL )
    {
        Instance_ = new UnitRegistry();
    }
    if( !Instance_->unitMap_.put( unit->getName(), unit ) )
    {
        fprintf( stderr, "Duplicate unit name: %s\n", unit->getName() );
    }
    if( !Instance_->unitMap_.put( unit->getAbbreviation(), unit ) )
    {
        // Maybe name and abbreviation match
        if( strcmp( unit->getName(), unit->getAbbreviation() ) != 0 )
        {
            // Maybe it's an alternate spelling for a unit
            const Unit* oldUnit = FindUnit( unit->getAbbreviation() );
            if( *oldUnit != *unit )
            {
                fprintf( stderr, "Duplicate unit abbreviation: %s\n", unit->getAbbreviation() );
            }
        }
    }
}

const Unit* UnitRegistry::FindUnit( const Str& name )
{
    if( dynamic_cast<UnitRegistry*>( Instance_ ) == NULL )
    {
        return NULL;
    }
    return Instance_->unitMap_.get( name );
}

unsigned int UnitRegistry::Size()
{
    if( dynamic_cast<UnitRegistry*>( Instance_ ) == NULL )
    {
        return 0;
    }
    return Instance_->unitMap_.size();
}

const Str& UnitRegistry::GetIndexedKey( unsigned int index )
{
    if( dynamic_cast<UnitRegistry*>( Instance_ ) == NULL )
    {
        return Str::EMPTY_STR;
    }
    MapEntry<const Str, const Unit*>* entry( Instance_->unitMap_.getIndexedEntry( index, false ) );
    return NULL == entry ? Str::EMPTY_STR : entry->getKey();
}

const Unit* UnitRegistry::GetIndexedUnit( unsigned int index )
{
    if( dynamic_cast<UnitRegistry*>( Instance_ ) == NULL )
    {
        return NULL;
    }
    return Instance_->unitMap_.getIndexed( index, false );
}
