
#pragma once

#include "indiapi.h"
#include "indidevapi.h"
#include "indibasetypes.h"

#define MAXRBUF 2048

/** @namespace INDI
 *  @brief Namespace to encapsulate INDI client, drivers, and mediator classes.
 *
 *  Developers can subclass the base devices class to implement device specific functionality. This ensures interoperability and consistency among devices within the same family
 *  and reduces code overhead.
 *
 *  <ul>
 *    <li>BaseClient: Base class for INDI clients. By subclassing BaseClient, client can easily connect to INDI server and handle device communication, command, and notifcation.</li>
 *    <li>BaseClientQt: Qt5 based class for INDI clients. By subclassing BaseClientQt, client can easily connect to INDI server
 *    and handle device communication, command, and notifcation.</li>
 *    <li>BaseMediator: Abstract class to provide interface for event notifications in INDI::BaseClient.</li>
 *    <li>BaseDevice: Base class for all INDI virtual devices as handled and stored in INDI::BaseClient. It is also the parent for all drivers.</li>
 *    <li>DefaultDevice: INDI::BaseDevice with extended functionality such as debug, simulation, and configuration support.
 *        It is the base class for all drivers and may \e only used by drivers directly, it cannot be used by clients.</li>
 *    <li>FilterInterface: Basic interface for filter wheels functions.</li>
 *    <li>GuiderInterface: Basic interface for guider (ST4) port functions.</li>
 *    <li>RotatorInterface: Basic interface for Rotator functions.</li>
 *    <li>DustCapInterface: Basic interface remotely controlled dust covers.</li>
 *    <li>LightBoxInterface: Basic interface for remotely controlled light boxes/switches.</li>
 *    <li>CCD: Base class for CCD drivers. Provides basic support for single chip CCD and CCDs with a guide head as well.</li>
 *    <li>Telescope: Base class for telescope drivers.</li>
 *    <li>FilterWheel: Base class for Filter Wheels. It implements the FilterInterface.</li>
 *    <li>Focuser: Base class for focusers.</li>
 *    <li>Rotator: Base class for rotators.</li>
 *    <li>Dome: Base class for domes.</li>
 *    <li>GPS: Base class for GPS devices.</li>
 *    <li>Weather: Base class for Weather devices.</li>
 *    <li>USBDevice: Base class for USB devices for direct read/write/control over USB.</li>
 *    <li>Controller: Class to handle controller inputs like joysticks and gamepads.</li>
 *    <li>Logger: Class to handle debugging and logging of drivers.</li>
 *  </ul>
 *
 * @author Jasem Mutlaq
 * @author Gerry Rozema
 */
namespace INDI
{
class BaseMediator;
class BaseClient;
class BaseClientQt;
class BaseDevice;
class DefaultDevice;
class FilterInterface;
class RotatorInterface;
class GuiderInterface;
class FocuserInterface;
class WeatherInterface;
class SensorInterface;
class DomeInterface;
class DustCapInterface;
class LightBoxInterface;
class CCD;
class Spectrograph;
class Detector;
class Telescope;
class FilterWheel;
class Focuser;
class Rotator;
class Dome;
class GPS;
class Weather;
class USBDevice;
class Property;
class Controller;
class Logger;
}

/** @class INDI::BaseMediator
 *  @brief Meditates event notification as generated by driver and passed to clients.
 */
class INDI::BaseMediator
{
    public:
        virtual ~BaseMediator() = default;

        /** @brief Emmited when a new device is created from INDI server.
         *  @param dp Pointer to the base device instance
         */
        virtual void newDevice(INDI::BaseDevice *dp) = 0;

        /** @brief Emmited when a device is deleted from INDI server.
         *  @param dp Pointer to the base device instance.
         */
        virtual void removeDevice(INDI::BaseDevice *dp) = 0;

        /** @brief Emmited when a new property is created for an INDI driver.
         *  @param property Pointer to the Property Container
         */
        virtual void newProperty(INDI::Property *property) = 0;

        /** @brief Emmited when a property is deleted for an INDI driver.
         *  @param property Pointer to the Property Container to remove.
         */
        virtual void removeProperty(INDI::Property *property) = 0;

        /** @brief Emmited when a new BLOB value arrives from INDI server.
         *  @param bp Pointer to filled and process BLOB.
         */
        virtual void newBLOB(IBLOB *bp) = 0;

        /** @brief Emmited when a new switch value arrives from INDI server.
         *  @param svp Pointer to a switch vector property.
         */
        virtual void newSwitch(ISwitchVectorProperty *svp) = 0;

        /** @brief Emmited when a new number value arrives from INDI server.
         *  @param nvp Pointer to a number vector property.
         */
        virtual void newNumber(INumberVectorProperty *nvp) = 0;

        /** @brief Emmited when a new text value arrives from INDI server.
         *  @param tvp Pointer to a text vector property.
         */
        virtual void newText(ITextVectorProperty *tvp) = 0;

        /** @brief Emmited when a new light value arrives from INDI server.
         *  @param lvp Pointer to a light vector property.
         */
        virtual void newLight(ILightVectorProperty *lvp) = 0;

        /** @brief Emmited when a new message arrives from INDI server.
         *  @param dp pointer to the INDI device the message is sent to.
         *  @param messageID ID of the message that can be used to retrieve the message from the device's messageQueue() function.
         */
        virtual void newMessage(INDI::BaseDevice *dp, int messageID) = 0;

        /** @brief Emmited when the server is connected. */
        virtual void serverConnected() = 0;

        /** @brief Emmited when the server gets disconnected.
         *  @param exit_code 0 if client was requested to disconnect from server. -1 if connection to server is terminated due to remote server disconnection.
         */
        virtual void serverDisconnected(int exit_code) = 0;
};
