#ifndef MDD_INPUT_H
#define MDD_INPUT_H

#include <string>
#include <functional>
#include "IInput.h"
#include "IModule.h"
#include <memory>
#include "IUnique.h"

namespace mdd {
    class Input 
        : public IInput
        , public std::enable_shared_from_this<Input>
    {
    private:
        std::string _name;
        int _appendix;
        std::weak_ptr<IModule> _parent;

        std::vector<double> _value;
        //std::function<bool(const json &)> _verification;
        std::shared_ptr<IOutput> _output;
        bool _optimizable;
        std::shared_ptr<limits> _limit;

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

    public:
        Input(const std::string& name, int appendix, const std::vector<double>& default_value = std::vector<double>({ 1 }));
        //const std::function<bool(const json &)> &verification = [](const json&) { return true; }
        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(std::shared_ptr<IModule> parent) override;
        std::vector<std::string> getParentID() override;

        state getState() override;
        void resetState() override;

        const std::vector<double>& getValue() override;
        std::vector<double>& setValue() override;
        state setValue(const std::vector<double>& val) override;
        bool isOptimizable() override;
        void setOptimizability(bool state) override;

        const std::shared_ptr<limits> getLimits() override;
        std::shared_ptr<limits>& setLimits() override;

        std::shared_ptr<IOutput> getConnection() override;
        
        //bool verify(const json & data) override;
        int addConnection(std::shared_ptr<IOutput> output) override;
        int removeConnection(std::shared_ptr<IOutput> output = nullptr) override;
        bool connect(std::shared_ptr<IOutput> output) 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 //MDD_INPUT_H
