from vectortween.Animation import Animation
from vectortween.Tween import Tween
from vectortween.Mapping import  Mapping
from copy import deepcopy
from itertools import tee
import numpy as np

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

def normalize(x):
    return x / sum(x)

class SequentialAnimation(Animation):
    def __init__(self, ListOfAnimations=[], timeweight=[], tween=['linear']):
        super().__init__(None, None)
        self.ListOfAnimations = []
        self.ListOfAnimationTimeWeight = np.array([])
        self.CumulativeNormalizedTimeWeights = np.array([])
        self.T = Tween(*tween)
        if ListOfAnimations:
            if not timeweight:
                for a in ListOfAnimations:
                    self.add(a, 1)
            else:
                for a,t in zip(ListOfAnimations,timeweight):
                    self.add(a, t)

    def add(self, Anim, timeweight=1):
        self.ListOfAnimations.append(deepcopy(Anim))
        self.ListOfAnimationTimeWeight = np.append(self.ListOfAnimationTimeWeight, [timeweight])
        self.CumulativeNormalizedTimeWeights = np.cumsum(normalize(self.ListOfAnimationTimeWeight))

    def make_frame(self, frame, birthframe, startframe, stopframe, deathframe):
        if birthframe is None:
            birthframe = startframe
        if deathframe is None:
            deathframe = stopframe
        if frame < birthframe:
            return None
        if frame > deathframe:
            return None
        if frame < startframe:
            return self.ListOfAnimations[0].make_frame(frame, birthframe, startframe, stopframe, deathframe)
        if frame > stopframe:
            return self.ListOfAnimations[-1].make_frame(frame, birthframe, startframe, stopframe, deathframe)

        t = self.T.tween2(frame, startframe, stopframe)

        for i, w in enumerate(self.CumulativeNormalizedTimeWeights):
            if t <= w:
                if i == 0: # reached the end of the cumulative weights
                    relativestartframe = 0
                else:
                    relativestartframe = self.CumulativeNormalizedTimeWeights[i-1]
                relativestopframe = self.CumulativeNormalizedTimeWeights[i]
                absstartframe = Mapping.linlin(relativestartframe, 0, 1, startframe, stopframe)
                absstopframe = Mapping.linlin(relativestopframe, 0, 1, startframe, stopframe)
                return self.ListOfAnimations[i].make_frame(frame, birthframe, absstartframe, absstopframe, deathframe)

add a way to sequence animations into a new animation