#pragma once

#include "QuantumCircuitElement.h"

class AbstractQuantumWire : public QuantumCircuitElement
{
public:
    enum class WireType
    {
        QUANTUM,
        CLASSICAL
    };

    AbstractQuantumWire(QuantumCircuitElement* input, QuantumCircuitElement* output);

    virtual ~AbstractQuantumWire() = default;

    virtual WireType getWireType() const = 0;

    bool isFullyConnected() const override
    {
        return mInput && mOutput;
    }

protected:
    QuantumCircuitElement* mInput{ nullptr };
    QuantumCircuitElement* mOutput{ nullptr };
};

class QuantumWire : public AbstractQuantumWire
{
public:
    QuantumWire(QuantumCircuitElement* input, QuantumCircuitElement* output);

    QuantumCircuitElement* getInput() const;
    QuantumCircuitElement* getOutput() const;

    Type getType() const override;
    WireType getWireType() const override;
};
using QuantumWirePtr = std::unique_ptr<QuantumWire>;

class ClassicalWire : public AbstractQuantumWire
{
public:
    WireType getWireType() const override
    {
        return WireType::CLASSICAL;
    }
};