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

#ifndef TURBULENCE_NPS_H_
#define TURBULENCE_NPS_H_

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

class UniversalDataReader;
class UniversalDataWriter;

/**
 *  Software interface to Neil Brown CTD.  Also provides interface
 *  to SimSlate for providing simulated temperature, salinity, and
 *  depth.
 *
 *  \note still needs to be coded for the actual Neil Brown CTD
 *
 *  Turbulence_NPS.h should only be included by Turbulence_NPS.cpp
 *  Other classes should include Turbulence_NPSIF.h
 *
 *  \ingroup modules_science
 */
class Turbulence_NPS: public AsyncComponent
{
public:
    Turbulence_NPS( const Module* module );
    virtual ~Turbulence_NPS();

    virtual void run();

    /// Do what needs to be done to run
    /// Similar to initialize, in old init/run/uninit sequence
    virtual RunState start();

    /// Might follow a STOP...START sequence
    virtual RunState starting();

    /// Pause for a short period (indicated by pauseTime)
    virtual RunState pause();

    /// Should eventually follow a PAUSE request: should set continueTime
    virtual RunState paused();

    /// Resume from PAUSE
    virtual RunState resume();

    /// Might follow a PAUSE...RESUME sequence
    virtual RunState resuming();

    /// Should eventually follow a START request or RESETTING
    virtual RunState runnable();

    /// Might occur in case of Error
    virtual RunState resetting()
    {
        return stop();
    }

    /// Initial state -- can be later followed by START
    virtual RunState stop();

    virtual RunState stopping();

    /// Initial state -- can be later followed by START
    virtual RunState stopped();

    void uninitialize();

    /// Should return [myNamespace]::SIMULATE_HARDWARE, or [myNamespace]::POWER, etc
    virtual ConfigURI getConfigURI( ConfigOption configOption ) const;

private:

    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    Turbulence_NPS( const Turbulence_NPS& old ); // disallow copy constructor

    DataReader* gfScanActiveReader_;
    BlobWriter* microTemp1Writer_;
    BlobWriter* microCondWriter_;
    BlobWriter* microTemp2Writer_;
    DataWriter* numTCSamplesWriter_;
    BlobWriter* acmPathWriter_;
    DataWriter* rollWriter_;
    DataWriter* pitchWriter_;
    DataWriter* yawWriter_;
    DataWriter* deltaXVelocityWriter_;
    DataWriter* deltaYVelocityWriter_;
    DataWriter* deltaZVelocityWriter_;
    BlobWriter* fwdSigStrengthWriter_;
    DataWriter* packetNumWriter_;

    short shortBuffer_[34];

    // returns true if data is requested from one of the readers
    bool isDataRequested();

    // sends data writers
    void writeData();

    // Debugging outputs
    bool debug_;

    // True if first packet after power-up
    bool firstPacket_;

    // Instance of load controller
    LoadControl loadControl_;

    Timespan sensorTimeout_;
    Timespan pausePeriod_;
    Timestamp startTime_;

    // Stores the current response from the device
    char deviceResponse_[ 512 ];

    // Holds the communications device
    UartStream uart_;

    void receive(); // What we do if we are going

};

#endif /* TURBULENCE_NPS_H_ */
