/** \file
 *
 *  Contains the MultiRay class declaration.
 *
 *  MultiRay.h should only be included by MultiRay.cpp
 *  Other classes should include MultiRay.h
 *
 *  Copyright (c) 2022 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef MULTIRAY_H
#define MULTIRAY_H

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

#include "MultiRayIF.h"

class UniversalDataReader;
class UniversalDataWriter;

class MultiRay: public SyncSensorComponent
#define MULTIRAY_UART_BUFFSIZE 32L

{
public:
    MultiRay( const Module* module );

    virtual ~MultiRay();

    virtual void run();
    virtual RunState start();
    virtual RunState starting();
    virtual RunState pause();
    //virtual RunState pausing();
    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();
    virtual void uninitialize();

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

    enum LightMode
    {
        LIGHT_OFF = 0,
        LIGHT_ON_RED,
        LIGHT_ON_WHITE
    };

    enum ChangeModeState
    {
        CHANGE_LED_ARRAY = 0,
        CHANGE_LED_BRIGHTNESS
    };

// protected:



private:


    bool debug_;
    bool changeRequested_;      // Used to enforce returning to changeLightMode() until the requested change is finished
    bool readNewLightMode_;     // Used to set up state for cycling through commands (for turning red and white lights on)
    bool waitBeforeAck_;        // Used to enforce delay between sending command and looking for acknowledge
    int changeModeState_;       // State enum for turning on red / white lights
    int defaultBrightness_;
    int brightnessWhite_;
    int brightnessRed_;

    Timestamp startTime_;
    Timespan powerOnTimeout_;
    Timespan timeout_;
    LoadControl loadControl_, loadControl2_; // load control board needed for each light
    UartStream uart_, uart2_; // uart needed for each light

    ConfigReader* brightnessWhiteCfgReader_;
    ConfigReader* brightnessRedCfgReader_;
    DataReader* lightModeReader_;

    DataWriter* lightModeWriter_;

    bool readConfig();
    Component::RunState changeLightMode();
    void sendChangeLightsRed( UartStream &uart );
    void sendChangeLightsWhite( UartStream &uart );
    void sendRedLightOn( UartStream &uart );
    void sendWhiteLightOn( UartStream &uart );
    void sendLightOff( UartStream &uart );
    int getAcknowledge( UartStream &uart );
    bool isDataRequested();
    LightMode lightMode_;

};

#endif
