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

#ifndef CANONSampler_H
#define CANONSampler_H

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

#include "CANONSamplerIF.h"

class UniversalDataWriter;

/**
 *  Provides software interface to the CANONSampler sensor.
 *
 *  \ingroup modules_science
 */

class CANONSampler : public SyncSensorComponent
{
public:

    CANONSampler( const Module* module );

    virtual ~CANONSampler();

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

    void uninitialize( void );

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

    // Logs output from sampler and returns true if sample complete
    bool sampleStatus();

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

    // Queries the LCBs for status
    bool logVoltageAndCurrent();

    // Update config parameters
    bool readConfig();

    // Get simulation data
    bool getSimulatedData();

    // Write data to the slate
    void writeData();

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

    /// Holds the communications device
    UartStream uart_;

    /// Power and comms in this case
    LoadControl loadControl_;

    /// Config readers
    ConfigReader* sampleTimeoutCfgReader_;

    DataReader *rotateOnlyReader_;

    // Outputs to slate
    DataWriter* samplingActiveWriter_;
    DataWriter* sampleNumberWriter_;

    /// Debugging outputs
    bool debug_;

    Timestamp sampleTime_;
    Timespan sampleTimeout_, poTimeout_;
    bool poRetry_;
    bool samplingActive_, rotateOnly_;
    int sampleNumber_;

    // Used to save state since there are long potential waiting periods for this device to respond
    enum SampleState
    {
        BEGIN,
        SAMPLING,
        DONE
    };
    SampleState sampleState_;

};
#endif /*CANONSampler_H*/
