from typing import Optional
from pojagi_dsp.channel import Filter


class Envelope(Filter[float]):
    def __init__(
        self,
        checkpoints: list[tuple[int, float]],
        *,
        srate=None,
        reader=None,
    ):
        super().__init__(reader, srate)
        self.checkpoints = sorted(checkpoints)

    def samples(self):
        checkpoints = self.checkpoints
        idx = 0
        try:
            n = 0
            while True:
                # Find current segment
                while idx + 1 < len(checkpoints) and n >= checkpoints[idx + 1][0]:
                    idx += 1

                if idx + 1 < len(checkpoints):
                    start, dest = checkpoints[idx]
                    end, end_dest = checkpoints[idx + 1]
                    t = (n - start) / (end - start) if end > start else 0.0
                    value = dest + (end_dest - dest) * t
                else:
                    value = checkpoints[-1][1]
                yield next(self.reader.stream()) * value
                n += 1
        except StopIteration:
            ...
        