#include "Input.h"

namespace mdd{
    int Input::addConnection(std::shared_ptr<IOutput> output)
    {
        _output = output;
        return 1;
    }
    int Input::removeConnection(std::shared_ptr<IOutput> output)
    {
        _output = nullptr;
        return 0;
    }
    Input::Input(const std::string& type, int appendix, const std::vector<double>& default_value) {
        _type = type;
        _value = default_value;
        _prefix = "";
        _appendix = appendix;
        _optimizable = false;

    }

    std::string Input::setType(const std::string& type){
        _type = type;
        return getID();
    }
    std::string Input::getType(){
        return  _type;
    }
    std::string Input::getID(){
        return _prefix + "/" + _type + std::to_string(_appendix);
    }

    std::string Input::setPrefix(const std::string& prefix){
        _prefix = prefix;
        return getID();
    }

    std::string Input::setAppendix(int appendix){
        _appendix = appendix;
        return  getID();
    }

    state Input::getState() {
        if (_output == nullptr) {
            return state::UNCHANGED;
        }
        else {
            return _output->getState();
        }
    }

    void Input::resetState() {

    }

    const std::vector<double>& Input::getValue() {
        if(_output == nullptr){
            return _value;
        } else{
            return _output->getValue();
        }
    }

    std::shared_ptr<IOutput> Input::getConnection() { return _output; }

    std::vector<double>& Input::setValue(){
        return _value;
    }

    state Input::setValue(const std::vector<double>& val) {
        if (val != _value)
        {
            _value = val;
            return state::CHANGED;
        }
        else {
            return state::UNCHANGED;
        }
    }

    bool Input::connect(std::shared_ptr<IOutput> output){
        _output = output;
        _output->addConnection(std::make_shared<Input>((*this)));
        return true;
    }

    bool Input::isOptimizable() {
        return _optimizable;
    }

    void Input::setOptimizability(bool state) {
        _optimizable = state;
    }
    const limits& Input::getLimits()
    {
        return _limit;
    }
    limits& Input::setLimits()
    {
        return _limit;
    }
}