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

#include "SettingReader.h"
#include "ValueClause.h"

#include "data/DataValue.h"
#include "utils/Timestamp.h"
#include <math.h>

SettingReader::~SettingReader()
{
    if( deleteDefaultValue_ && NULL != defaultValue_ )
    {
        delete defaultValue_;
    }
    if( NULL != valueClause_ )
    {
        delete valueClause_;
    }
}

bool SettingReader::isActive()
{
    return NULL != valueClause_ && valueClause_->getDataValue() != NULL;
}

//-------------------------------------------------------------------
/// Get functions
bool SettingReader::read( const Unit& unit, unsigned char& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( unit, readTo );
}

bool SettingReader::read( const Unit& unit, double& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( unit, readTo );
}

bool SettingReader::read( const Unit& unit, float& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( unit, readTo );
}

bool SettingReader::read( const Unit& unit, int& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( unit, readTo );
}

bool SettingReader::read( bool& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( Units::BOOL, readTo );
}

bool SettingReader::read( Timespan& readTo )
{
    double seconds = 0.0;
//    if( !evalValueClause() )
//    {
//        return false;
//    }
    if( valueClause_->getDataValue()->copyTo( Units::SECOND, seconds ) )
    {
        readTo = Timespan::Seconds( seconds );
        return true;
    }
    return false;
}

bool SettingReader::read( DataValue& readTo )
{
    if( !evalValueClause() )
    {
        return false;
    }
    return valueClause_->getDataValue()->copyTo( readTo );
}

int SettingReader::asInt( const Unit& unit )
{
    int value( 0 );
    read( unit, value );
    return value;
}

double SettingReader::asDouble( const Unit& unit )
{
    double value( nan( "" ) );
    read( unit, value );
    return value;
}

Str SettingReader::asString( const Unit& unit )
{
    if( !evalValueClause() )
    {
        return Str::EMPTY_STR;
    }
    return valueClause_->getDataValue()->toString( unit );
}

const Unit* SettingReader::getDefaultUnit()
{
    return NULL == defaultValue_ ? NULL : &defaultValue_->getUnit();
}

bool SettingReader::wasTouchedSinceLastRun( const Component* component )
{
    if( !isActive() )
    {
        return false;
    }
    return valueClause_->wasTouchedSinceLastRun( component );
}

Timestamp SettingReader::getMostRecentTimestamp( )
{
    if( !isActive() )
    {
        return Timestamp::NOT_SET_TIME;
    }
    return valueClause_->getMostRecentTimestamp( );
}
bool SettingReader::evalValueClause()
{
    if( !isActive() )
    {
        return false;
    }
    if( NULL != defaultValue_ && defaultValue_->getBinaryType() == MULTIVALUE )
    {
        return valueClause_->evalStr();
    }
    return valueClause_->eval();
}

SettingReader::SettingReader( const SettingURI& settingURI, const DataValue* defaultValue,
                              bool deleteDefaultValue )
    :     settingURI_( settingURI ),
          defaultValue_( defaultValue ),
          deleteDefaultValue_( deleteDefaultValue ),
          valueClause_( NULL )
{}

SettingReader::SettingReader( const SettingURI& settingURI, ValueClause* valueClause )
    :     settingURI_( settingURI ),
          defaultValue_( NULL ),
          deleteDefaultValue_( false ),
          valueClause_( valueClause )
{}
