#include "ModuleBase.h"
#include <iostream>

namespace mdd{
    class ModuleSwitch : public ModuleBase {
    protected:
        bool configureChild(const json& config) override;
    public:
        ModuleSwitch();
        state update() override;
    };
    ModuleSwitch::ModuleSwitch()
        :ModuleBase(R"JSON(
        {
        "configure":{
            "size":{
                "value": 1
            }
        },
        "GUI":{
            "name":{"value":"Switch"},
            "color":{"value":"#fd8d18"}
        }
        })JSON")
    {    
        inputs.push_back(std::make_shared<Input>( "Switch", 0));
        inputs.push_back(std::make_shared<Input>( "Default", 0));
        outputs.push_back(std::make_shared<Output>("Value", 0));
        key = "ModuleSwitch";
    }
    bool ModuleSwitch::configureChild(const json& config) {
        auto jit = config.find("size");
        if (jit != config.end())
        {
            json jval = jit.value()["value"];
            if (jval.is_string())
            {
                jval = json::parse(jval.get<std::string>());
            }
            size_t length = jval.get<size_t>();
            if (length != inputs.size() - 1)
            {
                size_t length_before = inputs.size();
                if (length_before != 1)
                {
                    inputs.back()->setName("Value");
                }

                for (size_t j = length_before - 1; j < length; j++)
                {
                    inputs.push_back(std::make_shared<Input>("Value", inputs.size() - 1));
                    inputs.back()->setParent(shared_from_this());
                }
                for (size_t j = length; j < length_before - 1; j++)
                {
                    inputs.pop_back();
                }
                if (length != 0)
                {
                    inputs.back()->setName("Default");
                }
            }
            _base_config["configure"]["size"]["value"] = jval;
            return true;
        }
        return false;
    }

    state ModuleSwitch::update(){
        std::vector<double> ret;
        size_t length = getInput(0)->getValue().size();
        for (size_t i = 0; i < length; i++)
        {
            int index = (int)getInput(0)->getValue()[i];
           
            if (index == 0) {
                index = 1;
            }

            if (index > inputs.size() - 1) {
                index = inputs.size() - 1;
            }
            for (size_t j = 0; j < getInput(index)->getValue().size(); j++)
            {
                ret.push_back(getInput(index)->getValue()[j]);
            }
            
        }
        return getOutput(0)->setValue(ret);

    }
}