# Path: pym2149/buf.py
# class BufType:
# 
#     def __init__(self, _, dtype):
#         self.dtype = dtype
# 
#     def __call__(self):
#         return MasterBuf(self.dtype)
# 
# Path: pym2149/nod.py
# class BufNode(Node):
# 
#     def __init__(self, buftype, channels = 1):
#         super().__init__()
#         self.masterbuf = buftype()
#         self.channels = channels
#         self.realcallimpl = self.callimpl
#         self.callimpl = self.makeresult
# 
#     def makeresult(self):
#         self.blockbuf = self.masterbuf.ensureandcrop(self.block.framecount * self.channels)
#         resultornone = self.realcallimpl()
#         if resultornone is not None:
#             return resultornone
#         return self.blockbuf
# 
# Path: pym2149/shapes.py
# def level5toamp(level):
# def _amptolevel4(amp):
# def level4to5(level4):
#     def level4to5(cls, data4, introlen = defaultintrolen):
#     def __init__(self, g, introlen = defaultintrolen):
#     def wavelength(self):
# def _meansin(x1, x2):
# def _sinsliceamp(i, n, skew):
# def _sinuslevel4(steps, maxlevel4, skew):
# def makesample5shape(data, signed, is4bit):
# class Shape:


from .buf import BufType
from .nod import BufNode
from .shapes import level4to5, level5toamp, level4tosinus5shape, level4totone5shape
from diapyr.util import singleton
import numpy as np

@singleton
class NullEffect:
    'All registers are non-virtual and write directly to chip, the timer does not interfere.'

    def putlevel5(self, node):
        node.blockbuf.copybuf(node.chain(node.signal))
        if node.levelmodereg.value:
            node.blockbuf.mulbuf(node.chain(node.env))
        else:
            # According to block diagram, the level is already 5-bit when combining with binary signal:
            node.blockbuf.mul(level4to5(node.fixedreg.value))

class FixedLevelEffect:
    'Registers levelmodereg and fixedreg are virtual, of which levelmodereg is ignored.'

    def __init__(self):
        self.wavelength, = {shape.wavelength() for shape in self.level4toshape}

    def getshape(self, fixedreg):
        return self.level4toshape[fixedreg.value]

    def putlevel5(self, node):
        node.blockbuf.copybuf(node.chain(node.signal))
        node.blockbuf.mulbuf(node.chain(node.rtone))

@singleton
class PWMEffect(FixedLevelEffect):
    'Interrupt setup/routine alternates fixed level between fixedreg and zero.'


# Path: pym2149/buf.py
# class BufType:
# 
#     def __init__(self, _, dtype):
#         self.dtype = dtype
# 
#     def __call__(self):
#         return MasterBuf(self.dtype)
# 
# Path: pym2149/nod.py
# class BufNode(Node):
# 
#     def __init__(self, buftype, channels = 1):
#         super().__init__()
#         self.masterbuf = buftype()
#         self.channels = channels
#         self.realcallimpl = self.callimpl
#         self.callimpl = self.makeresult
# 
#     def makeresult(self):
#         self.blockbuf = self.masterbuf.ensureandcrop(self.block.framecount * self.channels)
#         resultornone = self.realcallimpl()
#         if resultornone is not None:
#             return resultornone
#         return self.blockbuf
# 
# Path: pym2149/shapes.py
# def level5toamp(level):
# def _amptolevel4(amp):
# def level4to5(level4):
#     def level4to5(cls, data4, introlen = defaultintrolen):
#     def __init__(self, g, introlen = defaultintrolen):
#     def wavelength(self):
# def _meansin(x1, x2):
# def _sinsliceamp(i, n, skew):
# def _sinuslevel4(steps, maxlevel4, skew):
# def makesample5shape(data, signed, is4bit):
# class Shape:


# Path: pym2149/dac.py
from .buf import BufType
from .nod import BufNode
from .shapes import level4to5, level5toamp, level4tosinus5shape, level4totone5shape
from diapyr.util import singleton
import numpy as np


@singleton
class NullEffect:
    'All registers are non-virtual and write directly to chip, the timer does not interfere.'

    def putlevel5(self, node):
        node.blockbuf.copybuf(node.chain(node.signal))
        if node.levelmodereg.value:
            node.blockbuf.mulbuf(node.chain(node.env))
        else:
            # According to block diagram, the level is already 5-bit when combining with binary signal:
            node.blockbuf.mul(level4to5(node.fixedreg.value))

class FixedLevelEffect:
    'Registers levelmodereg and fixedreg are virtual, of which levelmodereg is ignored.'

    def __init__(self):
        self.wavelength, = {shape.wavelength() for shape in self.level4toshape}

    def getshape(self, fixedreg):
        return self.level4toshape[fixedreg.value]

    def putlevel5(self, node):
        node.blockbuf.copybuf(node.chain(node.signal))
        node.blockbuf.mulbuf(node.chain(node.rtone))

@singleton
class PWMEffect(FixedLevelEffect):
    'Interrupt setup/routine alternates fixed level between fixedreg and zero.'


    level4toshape = level4totone5shape