# fracbars_utils.py

"""
utility functions for use in fracbars.py
"""

import random
import wx
import fracbars_globals as G

# global vars

sounds = {
    "balloon" : wx.Sound("balloon.wav"),
    "ding"    : wx.Sound("ding.wav")
}

# thresholds for skipping the drawing of some ticks on ruler,
# to avoid overlapping annotations
ticklevels = {
    1 : (25, 55, 999),
    2 : (20, 45, 65),
    3 : (15, 30, 43),
    4 : (12, 26, 35)
}

def Gray(level):
    """
    return wx.Color object at spec'd gray level
    """
    assert(type(level) == type(1))
    assert(level >= 0)
    assert(level <= 255)

    return wx.Color(level, level, level)

def Width(obj):
    """
    return the width of an object
    """
    return obj.GetSizeTuple()[0]

def Height(obj):
    """
    return the height of an object
    """
    return obj.GetSizeTuple()[1]

def ListGCD(lst):
    """
    find the GCD of all the numbers in a list
    """
    if len(lst) == 1:
        return lst[0]
    elif len(lst) == 2:
        a,b = lst
        while b:
            a,b = b, a%b
        return a
    else:
        return ListGCD( (lst[0], ListGCD(lst[1:])) )

def ListLCM(lst):
    """
    find the LCM of all the numbers in a list
    """
    if len(lst) == 1:
        return lst[0]
    elif len(lst) == 2:
        a,b = lst
        return a * b / ListGCD(lst)
    else:
        return ListLCM( (lst[0], ListLCM(lst[1:])) )

def ReduceFraction(num, den):
    """
    reduce a fraction to lowest terms
    """
    gcd = ListGCD( (num,den) )
    return (num/gcd, den/gcd)

def Rotate(mylist, direction=1):
    """
    rotate a list (in place):
      if direction==1 (default), the first member becomes last
      if direction==0, the last member becomes first
    """
    if direction==1:
        tmp = mylist[0]
        mylist.append(tmp)
        del mylist[0]
        return
    if direction==0:
        tmp = mylist.pop()
        mylist.insert(0,tmp)
        return

def ColorIdx():
    """
    generator function:
    yield *index* into list of fraction bar colors or textures
    """
    if G.USE_BG_TEXTURES:
        bg_list = G.TEXTURES
    else:
        bg_list = G.COLORS

    # start at random location in list
    idx = random.randint(0, len(bg_list)-1)
    while True:
        idx = (idx + 1) % len(bg_list)
        yield idx

# instantiate the generator
ColorIndex = ColorIdx()

def RunningSums(lst):
    """
    return a list with the same length as argument list:
    each item is running sum of the argument list's members
    """
    # NOTE: "idx+1" avoids off-by-one problem
    return [ sum(lst[:i+1]) for i in range(len(lst)) ]    

def Skipper(n):
    """
    return True every N invocations (including first time),
    else return False
    """
    x = -1
    while True:
        x += 1
        if x % n == 0:
            yield True
        else:
            yield False
