// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/DeviceImpl.h 1160 2019-01-24 16:30:31Z depa $
#pragma once
// #include "basda/service/bcu/worker/Device.h"
#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/Device.h"

#include <Basda/Microgate/Bcu/BcuDevice.h>
#include <Basda/Microgate/Mgp/MgpHeader.h>
#include <Basda/Microgate/Mgp/OpCode.h>

#include <Nice/Util/Sync.h>


namespace Sharknir { namespace Bcu {

class DeviceImpl : public ::Sharknir::Bcu::Device
{
public:
    typedef Basda::Microgate::DWord DWord;

    DeviceImpl(const Nice::JointPtr & config);

    void initialize();

    /** @note overridden */
    virtual double readBcuFpgaTemperatureInC();

    DWord readBcuTemperatureDword();

    /** @note overridden */
    virtual double readBcuPcbTemperatureInC();

    // /** @note overridden */
    // virtual double readDsp16do0FpgaTemperatureInC();

    // double readDsp16doFpgaTemperatureInC(uint8_t dsp);

    // DWord readDsp16doTemperatureWord(uint8_t dsp);

    // /** @note overridden */
    // virtual double readDsp16do0PcbTemperatureInC();

    // double readDsp16DoPcbTemperatureInC(uint8_t dsp);

    // /** @note overridden */
    // virtual double readDsp16do1FpgaTemperatureInC();

    // /** @note overridden */
    // virtual double readDsp16do1PcbTemperatureInC();

    /** @note overridden */
    // virtual double readHvc0FpgaTemperatureInC();

    // double readHvcFpgaTemperatureInC(uint8_t dsp);

    // DWord readHvcTemperatureDword(uint8_t dsp);

    /** @note overridden */
    // virtual double readHvc0PcbTemperatureInC();

    // double readHvcPcbTemperatureInC(uint8_t dsp);

    // /** @note overridden */
    // virtual double readHvc1FpgaTemperatureInC();

    // /** @note overridden */
    // virtual double readHvc1PcbTemperatureInC();

    /** @note overridden */
    virtual Basda::Microgate::MemoryBufferPtr read(
            Basda::Microgate::OpCode opcode,
            uint8_t firstDspIndex, uint8_t lastDspIndex,
            int32_t address, unsigned lengthInDword);

    /** @note overridden */
    virtual void write(Basda::Microgate::OpCode opcode,
                       uint8_t firstDsp,
                       uint8_t lastDsp,
                       int32_t address,
                       const Basda::Microgate::MemoryBufferPtr& buffer );

    /** @note overridden */
    virtual void uploadDspCode(Nice::U8 firstDsp, Nice::U8 lastDsp,
                           const Nice::File& dspProgram);

    /** @note overridden */
    virtual void enableMasterDiagnostics( Nice::U16 decimationFactor,
            const std::string& remoteIpv4Address,
            const std::string& remoteMacAddress, Nice::U16 remoteUdpPortNr);

    /** @note overridden */
    virtual ~DeviceImpl();

private:
    struct PropertyName
    {
        static std::string name()
        {
            return "NAME";
        }
    };

    void checkInvariant();

    const Nice::JointPtr config_;
    Basda::BcuDevicePtr wrappedDevice_;
    std::string name_;
    static const double TEMPERATURE_CONVERSION_FACTOR;

};

typedef IceUtil::Handle<DeviceImpl> DeviceImplPtr;
}
}
