#include "LogicGate.h"

NInMOutLogicGate::NInMOutLogicGate(std::size_t numIn, std::size_t numOut, std::vector<Wire*> inputs, std::vector<Wire*> outputs)
    :   LogicGate(),
        mNumIn(numIn),
        mNumOut(numOut)
{
    if (inputs.size() == mNumIn)
    {
        mInputs = inputs;
    }
    else
    {
        mInputs = std::vector<Wire*>(numIn, nullptr);
    }

    if (outputs.size() == mNumOut)
    {
        mOutputs = outputs;
    }
    else
    {
        mOutputs = std::vector<Wire*>(numOut, nullptr);
    }
}

std::size_t NInMOutLogicGate::getNumInputs() const
{
    return mNumIn;
}

std::size_t NInMOutLogicGate::getNumOutputs() const
{
    return mNumOut;
}

Wire* NInMOutLogicGate::getInput(std::size_t idx) const
{
    if (idx < mNumIn)
    {
        return mInputs[idx];
    }
    else
    {
        return nullptr;
    }
}

Wire* NInMOutLogicGate::getOutput(std::size_t idx) const
{
    if (idx < mNumOut)
    {
        return mOutputs[idx];
    }
    else
    {
        return nullptr;
    }
}

void NInMOutLogicGate::setAtInput(std::size_t idx, Wire* value)
{
    if (idx < mInputs.size())
    {
        mInputs[idx] = value;
    }
}

void NInMOutLogicGate::setAtOutput(std::size_t idx, Wire* value)
{
    if (idx < mOutputs.size())
    {
        mOutputs[idx] = value;
    }
}

TwoInOneOutLogicGate::TwoInOneOutLogicGate(Wire* input0, Wire* input1, Wire* output)
    : NInMOutLogicGate(2, 1, { input0, input1 }, {output})
{

}

void TwoInOneOutLogicGate::setInput0(Wire* input)
{
    setAtInput(0, input);
}

void TwoInOneOutLogicGate::setInput1(Wire* input)
{
    setAtInput(1, input);
}

void TwoInOneOutLogicGate::setOutput(Wire* output)
{
    setAtOutput(0, output);
}