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

#ifndef Radio_Surface_H
#define Radio_Surface_H

#include "component/AsyncComponent.h"
#include "data/StrValue.h"
#include "io/LoadControl.h"
#include "logger/Logger.h"
#include "Radio_SurfaceIF.h"

class UniversalDataWriter;


/**
 *  Provides software interface to the Wetlabs puck.
 *
 *  \ingroup modules_science
 */

class Radio_Surface : public AsyncComponent
{
public:

    Radio_Surface( const Module* module );

    virtual ~Radio_Surface();

    virtual void run();

    virtual void uninitialize();

    /// 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 start();
    }

    /// 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();

    /// 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.
    Radio_Surface( const Radio_Surface& old ); // disallow copy constructor

    /// Async thread cycle period
    static const Timespan PERIOD;

    //*------------------- vehicle parameters --------------------------*/
    float surfaceThreshold_;
    ///////////////////////////////////

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

    // checks to see if we should be on
    bool shouldBeOn();

    // Sends data to DataWriters
    void writeData();

    // Power for the Radio
    LoadControl loadControl_;

    /// Time data request started
    Timestamp startTime_, powerTime_;

    /// Timeout for powering down/up
    Timespan timeout_, powerTimeout_, resetFailTimeout_;

    // Universal output. Used only to determine if we should power up.
//    UniversalDataWriter* communicationsWriter_;

    // Slate inputs
    UniversalDataReader* depthReader_;
    DataReader* verticalModeReader_;

    // Slate outputs
    DataWriter* radioPwrWriter_;

    /// Configuration readers
    ConfigReader* surfaceThresholdCfgReader_;

    /// Debugging outputs
    bool debug_;

    // Power is on or off
    Radio_SurfaceIF::RadioPower radioPwr_;

};
#endif /*Radio_Surface_H*/
