import collections

from gatesym.gates import Switch


class BinaryIn(collections.Sequence):
    """ a block of switches that can be read and written as a python int """
    def __init__(self, network, size, value=0):
        self.switches = [Switch(network) for i in range(size)]
        self.write(value)

    def write(self, value):
        for switch in self.switches:
            switch.write(value % 2)
            value //= 2

    def read(self):
        res = 0
        idx = 1
        for switch in self.switches:
            if switch.read():
                res += idx
            idx *= 2
        return res

    def __iter__(self):
        return iter(self.switches)

    def __len__(self):
        return len(self.switches)

    def __getitem__(self, key):
        return self.switches.__getitem__(key)

    def watch(self, name):
        for i, line in enumerate(self.switches):
            line.watch(f'{name}_{i}')


class BinaryOut(object):
    """ read a block of gates as a python int """
    def __init__(self, gates):
        self.gates = gates

    def read(self):
        res = 0
        idx = 1
        for gate in self.gates:
            if gate.read():
                res += idx
            idx *= 2
        return res

    def watch(self, name):
        for i, line in enumerate(self.gates):
            line.watch(f'{name}_{i}')
