"""the versatile ticker animates based on time"""

from math import sin, cos, pi, sqrt
halfpi = pi / 2.0


#interpolation functions
def linear(val):
    return min(val, 1.0)
def smooth(val):
    return (1 - cos(min(val, 1.0) * pi)) * .5
def hop(val): #opposite of smooth
    return (sin(min(val, 1.0) * pi)) * .5
def zigzag(val):
    return 1.0 - abs((val % 2.0) - 1.0)
def smoothzag(val):
    return (1 - cos(val * pi)) * .5
def looping(val):
    return val % 1.0


class Ticker:
    """can be used by a state (or anything really), it counts down
    an amount of time, tracking the percentage to completion. great
    for things in a game that need to wait for awhile, time is really
    whatever unit you want to pass in. by passing a different
    "minval" and "maxval" to the constructor, it will return a
    different range than percentage. minval and maxval can be
    tuples, in which case the returned value will be interped
    across each index."""
    def __init__(self, time, startval=0.0, endval=1.0, interp=linear):
    	if not time: time = .001
        self.endtime = time
        self.curtime = 0.0
        self.startval = startval
        self.endval = endval
        self.interp = interp
        self.gotlastval = 0
	self.percent = 0.0
        try:
            self.multi = len(startval)
            self.diff = [y-x for x,y in zip(startval, endval)]
        except TypeError:
            self.multi = 0
            self.diff = endval - startval

    def tick(self, timeinc):
        self.curtime += timeinc
        self.percent = self.curtime / self.endtime
        percent = self.interp(self.percent)
        if not self.multi:
            val = percent * self.diff + self.startval
        else:
            val = [percent*d+s for d, s in zip(self.diff, self.startval)]
        if self.curtime >= self.endtime: self.gotlastval = .5
        return val

    def __nonzero__(self):
        return not self.gotlastval and self.curtime < self.endtime


class TickerSpeed(Ticker):
    """same as Ticker class, but you pass it a "speed" instead of
    a total movement time."""
    def __init__(self, speed, startval=0.0, endval=1.0, interp=linear):
        try:
            count = len(startval)
            dist = 0.0
            for x,y in zip(startval, endval):
                dist += (x-y)**2
            dist = sqrt(dist)
        except TypeError:
            dist = abs(endval - startval)
        endtime = dist / speed
        Ticker.__init__(self, endtime, startval, endval, interp)
