/** \file
 *
 *  Contains the PowerOnly class declaration.
 *
 *  PowerOnly.h should only be included by PowerOnly.cpp
 *  Other classes should include PowerOnlyIF.h
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 *  This class simply provides power and a data writer to
 *  allowing a mission to request it
 */

#ifndef POWERONLY_H
#define POWERONLY_H

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

class UniversalDataWriter;


/**
 *  PowerOnly load control board interface definition.
 *
 */
typedef struct LCB
{
    /// Constructor
    LCB( const ConfigURI& loadControlCfg, bool useHardware, Logger& logger, Component* component, const Str& name );

    /// Returns true if sample is requested from the LCB
    bool isRequested( bool request = false );

    /// Slate interface
    DataWriter* samplingLoadWriter_;

    /// Config reader for sampleTime
    ConfigReader* sampleTimeCfgReader_;

    /// Power interface
    LoadControl loadControl_;

    /// Marks the beginning of the sample
    Timestamp startTime_;

    /// Holds the LCB sampling duration
    Timespan sampleTime_;

    /// True when a sample is requsted
    bool sampleRequest_;

    /// True when a sample is in process
    bool samplingLoad_;

    /// Holds the LCB name
    Str name_;

} LCB;

/**
 *  Provides software interface to a simple component that just turns power on/off
 *  to load control ports.
 *
 */
class PowerOnly : public SyncSensorComponent
{
public:

    PowerOnly( const Module* module );

    virtual ~PowerOnly();

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

    //*------------------- vehicle parameters --------------------------*/

    /// Initialize vehicle config variables
    bool readConfig( void );

    /// Returns true if data is requested from at least one of the LCBs
    bool isDataRequested( void );

    /// Creates an LCB instance and adds it to the ongoing list of LCBs
    void addLoadControl( const ConfigURI& loadControlCfg, const ConfigURI& sampleTimeCfg, const DataURI& sampleLoadControl );

    /// Logs the voltage/current of a given LCB
    bool logVoltageAndCurrent( LCB& lcb );

    /// Powers up a given LCB
    bool powerUpLoadControl( LCB& lcb );

    /// Powers down a given LCB
    bool powerDownLoadControl( LCB& lcb );

    /// Holds the component's power interfaces
    FlexArray<LCB*> loadControls_;

    /// Interface to 24v power converter
    DataReader* power24vConverterDataReader_;

    /// Holds the component-wide power request writer
    DataWriter* samplingPowerOnlyDataWriter_;

    /// Specifies the sampling duration for running LCBs
    ConfigReader* sampleTimeCfgReader_;

    /// Indicates a sample is in process
    bool sampling_;

    /// Debugging outputs
    bool debug_;

};
#endif /*PowerOnly_H*/
