/** \file
 *
 *  Contains the RDI_Pathfinder class declaration.
 *
 *  RDI_Pathfinder.h should only be included by RDI_Pathfinder.cpp
 *  Other classes should include RDI_PathfinderIF.h
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef RDI_PATHFINDER_H
#define RDI_PATHFINDER_H

#include "RDI_PathfinderIF.h"

#include "component/SyncComponent.h"
#include "io/LoadControl.h"
#include "io/UartStream.h"
#include "logger/Logger.h"

#include "data/Point3D.h"
#include "data/Point6D.h"
#include "data/Matrix3x3.h"

class UniversalDataReader;
class UniversalDataWriter;


#define UART_BUFSIZE 10240L

class RDI_Pathfinder : public SyncSensorComponent
{
public:

    RDI_Pathfinder( const Module* module );

    virtual ~RDI_Pathfinder();

    virtual void run();
    virtual RunState start();
    virtual RunState starting();
    virtual RunState pause();
    virtual RunState paused();
    virtual RunState resume();
    virtual RunState resuming();
    virtual RunState runnable();

    virtual RunState resetting()
    {
        return stop();
    }

    virtual RunState stop();
    virtual RunState stopping();
    virtual RunState stopped();
    void uninitialize();
    void logVoltageAndCurrent();
    /// Should return [myNamespace]::SIMULATE_HARDWARE, or [myNamespace]::POWER, etc
    virtual ConfigURI getConfigURI( ConfigOption configOption ) const;

private:
    RDI_Pathfinder( const RDI_Pathfinder& old );

    // Component interfaces
    LoadControl loadControl_;
    UartStream uart_;

    // scan configuraiton settings
    bool readConfig( void );

    bool checkTimeouts( void );
    bool simPD6( void );
    bool simPD13( void );
    bool readPD6( void );
    bool readPD13( void );
    bool parsePD6( void );
    bool parsePD13( void );
    void processPD6( void );
    void processPD13( void );
    void writeData( void );
    void setGroundVelWritersInvalid( bool invalid );
    void setWaterVelWritersInvalid( bool invalid );

    bool hasPD13_;
    bool hasPD6_;

    Timespan dvlTimeout_;
    Timespan dvlFailTimeout_; // How long we can go without valid data
    Timespan powerOnTimeout_; // How long it takes for the DVL to begin sending data
    Timestamp startTime_, dvlFailTime_;

    DataReader* power24vConverterDataReader_;

    UniversalDataWriter* altitudeWriter_;

    // Vehicle referenced water-mass velocity data
    UniversalBlobWriter* velocityWrtWaterWriter_;
    UniversalDataWriter* xVelWrtWaterWriter_;
    UniversalDataWriter* yVelWrtWaterWriter_;
    UniversalDataWriter* zVelWrtWaterWriter_;

    DataWriter* waterMassRangeWriter_;
    DataWriter* waterVeloInstFlagWriter_;

    // Vehicle referenced bottom-track velocity data
    UniversalBlobWriter* velocityWrtGroundWriter_;
    UniversalDataWriter* xVelWrtGroundWriter_;
    UniversalDataWriter* yVelWrtGroundWriter_;
    UniversalDataWriter* zVelWrtGroundWriter_;

    DataWriter* veloInstFlagWriter_;
    DataWriter* beam1RangeWriter_;
    DataWriter* beam2RangeWriter_;
    DataWriter* beam3RangeWriter_;
    DataWriter* beam4RangeWriter_;

    // Configuration inputs
    ConfigReader* readPD6CfgReader_;

    bool isDataRequested();

    bool dvlTimeoutArmed_;
    int usePD6_; // If set to true, expect PD6 messages from the instrument. Otherwise, expect PD13.
    char deviceResponse_[UART_BUFSIZE];

    int status_;

    // Water mass variables
    Point3D waterVeloInst_;
    double waterVeloInstX_;
    double waterVeloInstY_;
    double waterVeloInstZ_;
    double waterVeloError_;
    int waterVeloInstFlag_;

    double waterMassRange_;

    // Bottom track variables
    Point3D veloInst_;
    double veloInstX_;
    double veloInstY_;
    double veloInstZ_;
    double veloError_;
    int veloInstFlag_;

    double altEstimate_;
    double beam1Range_, beam2Range_, beam3Range_, beam4Range_;

    int bitError_;

    bool debug_;
};
#endif /*RDI_PATHFINDER_H*/
