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

#include "LcmSlateBridge.h"
#include <vector>


LcmSlateBridge::LcmSlateBridge( Component* owner, const Str& channel, lcm::LCM* lcm, short sourceID )
    : SlateBridge( owner ),
      LcmListener( channel, lcm, sourceID ),
      debug_( false )
{}

LcmSlateBridge::~LcmSlateBridge()
{}


void LcmSlateBridge::handleMessage( const lcm::ReceiveBuffer *rbuf,
                                    const std::string &chan,
                                    const TethysLcmTypes::LrauvLcmMessage *msg )
{
    if( debug_ ) owner_->getLogger().syslog( "Recived LCM message on channel " + Str( chan.c_str() ) + ".", Syslog::INFO );
    if( sourceID_ == ANY_SOURCE || sourceID_ == msg->source )
    {
        // Decode the message
        unpackMsg( msg );
        Timestamp timestamp( msg->epochMillisec / 1000.0 );
#ifdef __FASTSIM
        timestamp = Timestamp::Now();
#endif
        std::vector<const char*> names = msg_.listNames();

        for( size_t i = 0; i < names.size(); ++i )
        {
            Str name = names[i];

            // TODO: if name in list of approved names...

            bool ok( true );
            switch( msg_.getType( name.cStr() ) )
            {
            case lrauv_lcm_tools::Int:
                ok &= slateWrite( msg_.getIntArray( name.cStr() ), timestamp );
                break;

            case lrauv_lcm_tools::Float:
                ok &= slateWrite( msg_.getFloatArray( name.cStr() ), timestamp );
                break;

            case lrauv_lcm_tools::Double:
                ok &= slateWrite( msg_.getDoubleArray( name.cStr() ), timestamp );
                break;

            case lrauv_lcm_tools::Byte:
                ok &= slateWrite( msg_.getByteArray( name.cStr() ), timestamp );
                break;

            // TODO: add support for string/blobs
            case lrauv_lcm_tools::String:
            case lrauv_lcm_tools::Unknown:
            default:
                break;
            }

            if( !ok ) owner_->getLogger().syslog( "Failed to write " + name + ".", Syslog::ERROR );
        }
    }
    else
    {
        owner_->getLogger().syslog( "Ignoring message from unknown source " + Str( ( int )msg->source ).asHex() + ".", Syslog::ERROR );
    }
}

bool LcmSlateBridge::slateWrite( const TethysLcmTypes::IntArray *array, const Timestamp& timestamp )
{
    if( array != NULL )
    {
        return SlateBridge::slateWrite( array->name.c_str(), array->unit.c_str(), array->data[0], timestamp );
    }
    return false;
}

bool LcmSlateBridge::slateWrite( const TethysLcmTypes::FloatArray *array, const Timestamp& timestamp )
{
    if( array != NULL )
    {
        return SlateBridge::slateWrite( array->name.c_str(), array->unit.c_str(), array->data[0], timestamp );
    }
    return false;
}

bool LcmSlateBridge::slateWrite( const TethysLcmTypes::DoubleArray *array, const Timestamp& timestamp )
{
    if( array != NULL )
    {
        return SlateBridge::slateWrite( array->name.c_str(), array->unit.c_str(), array->data[0], timestamp );
    }
    return false;
}

bool LcmSlateBridge::slateWrite( const TethysLcmTypes::ByteArray *array, const Timestamp& timestamp )
{
    if( array != NULL )
    {
        return SlateBridge::slateWrite( array->name.c_str(), array->unit.c_str(), array->data[0], timestamp );
    }
    return false;
}
