#ifndef MDD_OUTPUT_H
#define MDD_OUTPUT_H
#include "IOutput.h"
#include "IModule.h"

namespace mdd {
    class Output 
        : public IOutput
        , public std::enable_shared_from_this<Output>
    {
    private:
        state _state;
        std::vector<double> _value;
        std::string _name;
        int _appendix;
        std::vector<std::weak_ptr<IInput>> _connections;
        bool _optimizable;
        std::weak_ptr<IModule> _parent;

    protected:
        json _base_config;
        std::string type;
        std::string key;
        bool configureChild(const json& config) override { return true; };

    public:
        Output(const std::string& name, int appendix, const std::vector<double>& initial = std::vector<double>({ 1 }));
        const std::vector<double>& getValue() override;
        std::vector<double>& setValue() override;
        state setValue(const std::vector<double>& val) override;
        bool isOptimizable();
        void setOptimizability(bool state);
        state getState() override;
        void resetState() override;
        std::string getType() override;
        std::string getGeneratorKey() override;
        std::string setName(const std::string& name) override;
        std::string getName() override;
        std::string setAppendix(int appendix) override;
        int getAppendix() override;
        std::string getID() override;
        void setParent(IModule::Ptr parent) override;
        std::vector<std::string> getParentID() override;
        int addConnection(std::shared_ptr<IInput> input) override;
        int removeConnection(std::shared_ptr<IInput> input) override;
        bool connect(std::shared_ptr<IInput> input) override;
        std::vector<std::shared_ptr<IInput>> getConnections() override;
        void disconnect() override;

        bool configure(const json& config) override;
        const json& getConfiguration() override;
        void load(const json& j) override;
        json dump() override;
        json getIdentifier() override;
    };
}
#endif
