from Scenario2.keyframes import ValueObject, ValueGenerator,KF, Interval, \
     AutoCurrentValueObject, KFAutoCurrentValue
from Scenario2.interpolators import FloatScalarInterpolator
from Scenario2.actions import Actions
from Scenario2.actor import CustomActor


def test_001constructors():
    a = Actions()


def test_002addKeyframe1():
    """
    Test adding KFs that fall on nothing or an existing KF.
    If a new KF falls on to existing one, the value of the existing Kf is
    overwritten with the value of the new KF.
    A linked KF cannot be added on top of an existing KF
    """
    a = Actions()
    
    # add keyframe as position value pair
    # dest. : 0
    a.addKeyframe( (0, 10) )
    assert len(a.keyframes) == 1
    assert a.keyframes[0].getValue() == 10
    kf0 = a.keyframes[0]
    
    # add keyframe object
    # dest. : 0        10
    kf1 = KF( 10, 25 )
    a.addKeyframe( kf1 )
    assert len(a.keyframes) == 2
    assert a.keyframes[1].getValue() == 25

    # add keyframe between the 2 existing ones
    # dest. : 0   5   10
    kf2 = KF( 5, 28 )
    a.addKeyframe( kf2 )
    assert len(a.keyframes) == 3
    assert a.keyframes[0] == kf0
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf1
    
    # overwrite existing keyframe value
    # dest. : 0   5   10
    kf3 = KF( 5, -12 )
    a.addKeyframe( kf3 )
    # no new KF is added
    assert len(a.keyframes) == 3
    assert a.keyframes[0] == kf0
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf1
    # value of kf2 is now -12
    assert a.keyframes[1].getValue() == -12

    # try to add a linked KF (this is not allowed): 
    kf4 = kf1.linkedCopy(5)
    assert a.addKeyframe(kf4) == None

    


def test_002addKeyframe2():
    """ Tests splitting an interval with a new keyframe
    """
    a = Actions()

    # add first interval from 10-30
    kf1 = KF( 10, 25 )
    kf2 = KF( 30, 35 )
    valGen = ValueGenerator()
    i1 = Interval(kf1, kf2, valGen)
    from Scenario2.interpolators import IntScalarInterpolator
    ip = IntScalarInterpolator(None, None)
    i1.setValGenGenerator(ip)
    a.addInterval(i1)
    #add a new keyframe that will split the first interval
    kf3 = KF(15, 45)
    a.addKeyframe( kf3 )
    kfs = a.keyframes
    assert kfs[0].pos == 10
    assert kfs[1].pos == 15
    assert kfs[2].pos == 30
    assert len(a.intervals) == 2
    
    in1 = a.intervals[0]
    assert in1.kf1 == kf1
    assert in1.kf2 == kf3
    vg1 = in1.valGen.generator
    assert isinstance(vg1, IntScalarInterpolator) == True
    assert vg1.firstVal == 25
    assert vg1.lastVal == 45


    in2 = a.intervals[1]
    assert in2.kf1 == kf3
    assert in2.kf2 == kf2
    vg2 = in2.valGen.generator
    assert isinstance(vg2, IntScalarInterpolator) == True
    assert vg2.firstVal == 45
    assert vg2.lastVal == 35

    assert kfs[0].leftInterval == None
    assert kfs[0].rightInterval == in1
    assert kfs[1].leftInterval == in1
    assert kfs[1].rightInterval == in2
    assert kfs[2].leftInterval == in2
    assert kfs[2].rightInterval == None
        
    # now there are 3 keyframes and 2 intervals.
    # create a KF that is linked copy of kf1  and add it to the second interval
    kf4 = kf1.linkedCopy(20)
    a.addKeyframe( kf4 )
    kfs = a.keyframes
    #for i, kf in enumerate(kfs):
    #    print "kf(%d)" %i, kf.pos, kf.getValue()
    assert kfs[0].pos == 10
    assert kfs[1].pos == 15
    assert kfs[2].pos == 20
    assert kfs[3].pos == 30
    assert len(a.intervals) == 3

    assert kfs[0].isLinked() == True
    assert kfs[2].isLinked() == True

    in1 = a.intervals[1]
    assert in1.kf1 == kf3
    assert in1.kf2 == kf4
    vg1 = in1.valGen.generator
    assert vg1.firstVal == 45
    assert vg1.lastVal == 25

    in2 = a.intervals[2]
    assert in2.kf1 == kf4
    assert in2.kf2 == kf2
    vg2 = in2.valGen.generator
    assert vg2.firstVal == 25
    assert vg2.lastVal == 35

    

class Object:

    def __init__(self, val):
        self.value = val
        
    def get(self):
        return self.value

    def set(self, value):
        self.value = value
        

def test_002addKFAutoCurrentValue1():
    """ Test adding a special case keyframe (KFAutoCurrentValue) whose value is generated by
    AutoCurrentValueObject. 
    """
    # test creating an action with a KFAutoCurrentValue kf  and a KF
    a = Actions()
    obj = Object(0)
    from Scenario2.actor import CustomActor
    from Scenario2.interpolators import IntScalarInterpolator
    actor = CustomActor('obj', obj, setMethod='set', getFunction=(obj.get, (), {}),
                        interp = (IntScalarInterpolator, (None, None), {} ))
    autoval = AutoCurrentValueObject(actor)
    kf1 = KFAutoCurrentValue(0, autoval)
    kf2 = KF (10, 20)
    i1 = Interval(kf1, kf2, generator = actor.behaviorList)
    a.addInterval(i1)

    assert a.getValue(0) == 0
    assert a.getValue(10) == 20
    assert a.getValue(5) == 10

    # change the value of the object
    obj.set(10)

    assert a.getValue(0) == 10  # the first keyframe updated properly
    assert a.getValue(10) == 20
    assert a.getValue(5) == 15



def test_002addKFAutoCurrentValue2():
    """
    Test replacing an existing keyframe with a KFAutoCurrentValue keyframe
    """
    # create an action with 3 keyframes and 2 intervals

    from Scenario2.actor import CustomActor
    from Scenario2.interpolators import IntScalarInterpolator
    obj = Object(10)
    actor = CustomActor('obj', obj, setMethod='set', getFunction=(obj.get, (), {}),
                        interp = (IntScalarInterpolator, (None, None), {} ))
    a = Actions(actor)
    kf1 = KF(0, 0)
    kf2 = KF(10, 20)
    kf3 = KF(10, 20)
    kf4 = KF(20, 30)
    gen1 =  actor.behaviorList
    gen2 = IntScalarInterpolator(None, None)
    i1 = Interval(kf1, kf2, generator = gen1)
    i2 = Interval(kf3, kf4, generator = gen2)
    a.addInterval(i1)
    a.addInterval(i2)
    
    assert a.getValue(0) == 0
    assert a.getValue(10) == 20
    assert a.getValue(5) == 10
    assert a.getValue(20) == 30
    assert a.getValue(15) == 25

    # create and add a new KFAutoCurrentValue keyframe at the position of the action's second keyframe
    autoval = AutoCurrentValueObject(actor)
    kf5 = KFAutoCurrentValue(10, autoval)
    
    a.addKeyframe(kf5)
    kfs = a.keyframes
    intervals = a.intervals
    assert len(kfs) == 3
    assert len(intervals) == 2
    assert kfs[1] == kf5    

    assert kfs[0].leftInterval == None
    assert kfs[0].rightInterval == intervals[0]
    assert intervals[0].kf1 == kfs[0]
    assert intervals[0].kf2 == kfs[1]
    assert kfs[1].leftInterval == intervals[0]
    assert kfs[1].rightInterval == intervals[1]
    assert intervals[1].kf1 == kfs[1]
    assert intervals[1].kf2 == kfs[2]
    assert kfs[2].leftInterval == intervals[1]
    assert kfs[2].rightInterval == None
    assert intervals[0].valGen.generator == gen1
    assert intervals[1].valGen.generator == gen2
    
    assert a.getValue(0) == 0
    #print  a.getValue(5), a.getValue(10), a.getValue(15), a.getValue(20), 
    assert a.getValue(5) == 5
    assert a.getValue(10) == 10
    assert a.getValue(15) == 20
    assert a.getValue(20) == 30



    
def test_003addInterval1():
    """
    Test adding Intervals that fall on nothing
    """
    a = Actions()

    # add first interval from 10-20
    #           10----------20
    kf1 = KF( 10, 25 )
    kf2 = KF( 20, 35 )
    i1 = Interval(kf1, kf2)
    val = a.addInterval( i1 )
    assert val == True
    assert len(a.intervals) == 1
    assert a.intervals[0] == i1
    assert len(a.keyframes) == 2
    
    # add second interval from 50-60
    #           10----------20                               50--------60
    kf1 = KF( 50, 25 )
    kf2 = KF( 60, 35 )
    i2 = Interval(kf1, kf2)
    val = a.addInterval( i2 )
    assert val == True
    assert len(a.intervals) == 2
    a.intervals[0] = i1
    a.intervals[1] = i2
    assert len(a.keyframes) == 4

    # add third interval from 30-40
    #           10----------20        30--------40           50--------60
    kf1 = KF( 30, 25 )
    kf2 = KF( 40, 35 )
    i3 = Interval(kf1, kf2)
    val = a.addInterval( i3 )
    assert val == True
    assert len(a.intervals) == 3
    a.intervals[0] = i1
    a.intervals[1] = i3
    a.intervals[2] = i2
    assert len(a.keyframes) == 6
    kfs = a.keyframes
    assert kfs[0].pos == 10
    assert kfs[1].pos == 20
    assert kfs[2].pos == 30
    assert kfs[3].pos == 40
    assert kfs[4].pos == 50
    assert kfs[5].pos == 60


def test_004addInterval1():
    """
    Test adding Intervals that fall on existng keyframes
    """

    a = Actions()
    # dest. :  0
    kf0 = KF(0, 0.)
    a.addKeyframe( kf0 )

    # add first interval from 0-10
    # The value of kf1 overwrites the value of kf0
    # the interval gets added
    # source:  0----------10
    # dest. :  0
    kf1 = KF( 0, 25. )
    kf2 = KF( 10, 35. )
    i1 = Interval(kf1, kf2)
    val = a.addInterval( i1 )
    assert val == True
    assert len(a.intervals) == 1
    a.intervals[0] = i1
    assert len(a.keyframes) == 2
    assert a.keyframes[0]== kf0
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1]== kf2

    # add second interval from 10-20
    # The value of kf1 overwrites the value of kf0
    # the interval gets added
    # dest. :  0----------10
    # source:             10----------20
    kf3 = KF( 10, 30. )
    kf4 = KF( 20, 35. )
    i2 = Interval(kf3, kf4)
    val = a.addInterval( i2 )
    kfs = a.keyframes
    intervals = a.intervals
    assert val == True
    assert len(intervals) == 2
    a.intervals[0] = i1
    a.intervals[1] = i2
    assert len(kfs) == 3
    assert kfs[0] == kf0
    assert kfs[1] == kf2
    assert kfs[1].getValue() == kf3.getValue()
    assert kfs[2] == kf4

    assert intervals[0].kf1 == kfs[0]
    assert intervals[0].kf2 == kfs[1]
    assert intervals[1].kf1 == kfs[1]
    assert intervals[1].kf2 == kfs[2]


def test_005addInterval1():
    """
    Test adding Intervals that fall on existng keyframes
    """
    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10----------20 
    # source:             10----------20
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf4 = KF( 20, 35. )
    i1 = Interval(kf2, kf4)
    val = a.addInterval( i1 )
    assert val == True

    kf5 = KF( 10, 8. )
    kf6 = KF( 20, 28. )
    def f(v):
        return v

    i2 = Interval(kf5, kf6, generator=f)
    val = a.addInterval( i2 )
    assert val == True

    assert len(a.intervals) == 2
    assert i1.valGen.generator == i2.valGen.generator
    assert len(a.keyframes) == 3
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf4
    assert a.keyframes[1].getValue() == kf5.getValue()
    assert a.keyframes[2].getValue() == kf6.getValue()


def test_006addInterval1():
    """
    Test adding Intervals that fall on existng keyframes
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10          20-----------30 
    # source:             10----------20
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 35. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == True

    kf5 = KF( 10, 8. )
    kf6 = KF( 20, 28. )
    val = a.addInterval( Interval(kf5, kf6) )
    assert val == True
    
    assert len(a.intervals) == 3
    assert len(a.keyframes) == 4
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[1].getValue() == kf5.getValue()
    assert a.keyframes[2] == kf3
    assert a.keyframes[2].getValue() == kf6.getValue()
    assert a.keyframes[3] == kf4


def test_007addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10
    # source:  0---6
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True

    kf3 = KF( 0, 8. )
    kf4 = KF( 6, 28. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 1
    assert len(a.keyframes) == 2
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    

def test_008addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10
    # source:  0----------------16
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True

    kf3 = KF( 0, 8. )
    kf4 = KF( 16, 28. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 1
    assert len(a.keyframes) == 2
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    

def test_009addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :      10----------20
    # source:  5---------------20
    kf1 = KF( 10, 0. )
    kf2 = KF( 20, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True

    kf3 = KF( 5, 8. )
    kf4 = KF( 20, 28. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 1
    assert len(a.keyframes) == 2
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    

def test_010addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10
    # source:      5------10
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True

    kf3 = KF( 5, 8. )
    kf4 = KF( 10, 28. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 1
    assert len(a.keyframes) == 2
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    

def test_011addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10----------20
    # source:                 12---16
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    val = a.addInterval( Interval(kf2, kf3) )
    assert val == True

    kf4 = KF( 12, 8. )
    kf5 = KF( 16, 28. )
    val = a.addInterval( Interval(kf4, kf5) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 3
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf3
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf3.getValue()
    

def test_012addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10----------20
    # source:        8--------16
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    val = a.addInterval( Interval(kf2, kf3) )
    assert val == True

    kf4 = KF( 8, 8. )
    kf5 = KF( 16, 28. )
    val = a.addInterval( Interval(kf4, kf5) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 3
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf3
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf3.getValue()
    

def test_013addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10         20----------30
    # source:        8--------16
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 30. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == True

    kf5 = KF( 8, 8. )
    kf6 = KF( 16, 28. )
    val = a.addInterval( Interval(kf5, kf6) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 4
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf3
    assert a.keyframes[3] == kf4
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf3.getValue()
    assert a.keyframes[3].getValue() == kf4.getValue()
    

def test_014addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10         20----------30
    # source:                   18--------26
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 30. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == True

    kf5 = KF( 18, 8. )
    kf6 = KF( 26, 26. )
    val = a.addInterval( Interval(kf5, kf6) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 4
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf3
    assert a.keyframes[3] == kf4
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf3.getValue()
    assert a.keyframes[3].getValue() == kf4.getValue()
    

def test_015addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10         20----------30
    # source:         8------------------26
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 30. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == True

    kf5 = KF( 8, 8. )
    kf6 = KF( 26, 26. )
    val = a.addInterval( Interval(kf5, kf6) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 4
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf3
    assert a.keyframes[3] == kf4
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf3.getValue()
    assert a.keyframes[3].getValue() == kf4.getValue()
    

def test_016addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0----------10    15     20----------30
    # source:                12---18
    kf1 = KF( 0, 0. )
    kf2 = KF( 10, 5. )
    val = a.addInterval( Interval(kf1, kf2) )
    assert val == True
    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 30. )
    val = a.addInterval( Interval(kf3, kf4) )
    assert val == True

    kf5 = KF( 15, 8. )
    a.addKeyframe( kf5 )

    kf6 = KF( 8, 8. )
    kf7 = KF( 26, 26. )
    val = a.addInterval( Interval(kf6, kf7) )
    assert val == False # fails to add
    
    assert len(a.intervals) == 2
    assert len(a.keyframes) == 5
    assert a.keyframes[0] == kf1
    assert a.keyframes[1] == kf2
    assert a.keyframes[2] == kf5
    assert a.keyframes[3] == kf3
    assert a.keyframes[4] == kf4
    assert a.keyframes[0].getValue() == kf1.getValue()
    assert a.keyframes[1].getValue() == kf2.getValue()
    assert a.keyframes[2].getValue() == kf5.getValue()
    assert a.keyframes[3].getValue() == kf3.getValue()
    assert a.keyframes[4].getValue() == kf4.getValue()


def test_017intervalValGen():
    """
    test that a KF with a different ValueObject overwrites the ValueObject
    when a keyframe is added
    """
    a = Actions()

    kf1 = KF( 0, 0. )

    class Object:
        def __init__(self, value):
            self.value = value
        def get(self):
            return self.value
        def set(self, value):
            self.value = value

    obj = Object(5)


    actor = CustomActor('obj', obj, setMethod='set',
                        getFunction=(obj.get, (), {}))
    assert len(actor.actions.keyframes)==1
    kf0 = actor.actions.keyframes[0]
    assert kf0.getValue() == 5
    assert isinstance(kf0.valueObject, ValueObject)

    autoValue = AutoCurrentValueObject(actor)
    kf1 = KF(0, autoValue)
    actor.addKeyframe( kf1 )
    assert len(actor.actions.keyframes)==1
    assert kf0.getValue() == 5
    assert isinstance(kf0.valueObject, AutoCurrentValueObject)
    obj.set(22)
    assert kf0.getValue() == 22


def test_018intervalValGen():
    """
    test that a KF with a different ValueObject overwrites the ValueObject
    when an Interval is added
    """
    a = Actions()

    kf1 = KF( 0, 0. )

    class Object:
        def __init__(self, value):
            self.value = value
        def get(self):
            return self.value
        def set(self, value):
            self.value = value

    obj = Object(5)

    actor = CustomActor('obj', obj, setMethod='set',
                        getFunction=(obj.get, (), {}))
    assert len(actor.actions.keyframes)==1
    kf0 = actor.actions.keyframes[0]
    assert kf0.getValue() == 5
    assert isinstance(kf0.valueObject, ValueObject)

    kf1 = KFAutoCurrentValue(0, actor)
    kf2 = KF( 10, 20)
    actor.addIntervals( [(kf1, kf2)] )
    assert len(actor.actions.keyframes)==2
    kf = actor.actions.keyframes[0]
    assert isinstance(kf.valueObject, AutoCurrentValueObject)
    assert kf.getValue() == 5
    obj.set(22)
    assert kf.getValue() == 22


def test_020addInterval1():
    """
    Test adding Intervals that fall on existng Intervals
    """

    a = Actions()

    # add intervals from 0-10 and 20-30
    # dest. :  0
    # source:  0---6
    kf1 = KF( 0, 0. )
    val = a.addKeyframe( kf1 )
    assert val == kf1

    class Object:
        def __init__(self, value):
            self.value = value
        def get(self):
            return self.value
        def set(self, value):
            self.value = value

    obj = Object(5)

    actor = CustomActor('obj', obj, setMethod='set',
                        getFunction=(obj.get, (), {}))

    kf2 = KFAutoCurrentValue( 0, actor )
    kf3 = KF( 6, 28. )
    inter = Interval(kf2, kf3)
    val = a.addInterval( inter )
    assert val == True

    assert len(a.intervals) == 1
    assert len(a.keyframes) == 2
    assert a.keyframes[0] == kf2
    assert a.keyframes[1] == kf3
    assert kf2.rightInterval == inter
    assert kf3.leftInterval == inter


def test_021addAction1():
    """
    test adding a new action to an existing one
    """

    act1 = Actions()
    kf1 = KF(0, 10)
    act1.addKeyframe(kf1)
    
    kf2 = KF( 0, (0,0,0) )
    kf3 = KF( 20,(10, 0,0) )
    i1 = Interval(kf2, kf3 )
    act2 = Actions()
    act2.addInterval(i1)
    act1.addActionsAt(act2, 0)

    assert len(act1.keyframes) == 2
    assert act1.keyframes[0].pos == 0
    assert act1.keyframes[1].pos == 20


def checkIntervals(actions, ind1, ind2):
    # check keyframes of actions.intervals[ind1:ind2]
    intervals = actions.intervals
    kfs = actions.keyframes
    kfind = kfs.index(intervals[ind1].kf1)
    for i, inter in enumerate(actions.intervals[ind1:ind2]):
        kf1 = kfs[kfind]
        kf2 = kfs[kfind + 1]
        print "checkIntervals:", kf1.pos, kf2.pos
        assert inter.kf1 == kf1
        assert inter.kf2 == kf2
        assert kf1.rightInterval == inter
        assert kf2.leftInterval == inter
        kfind = kfind + 1
        

def test_022addAction2():
    """
    test adding an action (that will be a copy of existing keyframes and intervals) at a specified position
    """
    # construct first action
    # add intervals from 0-10 and 10-20
    # dest. :  0----------10----------20    
    a1 = Actions()
    kf1 = KF( 0, 25. )
    kf2 = KF( 10, 35. )
    i1 = Interval(kf1, kf2)
    kf3 = KF( 10, 35. )
    kf4 = KF( 20, 45. )
    i2 = Interval(kf3, kf4)
    a1.addInterval(i1)
    a1.addInterval(i2)

    # create a second actions with keyframes and intervals from the first one and add it  at position 30
    # dest :  0----------10----------20
    # source: 0----------10----------20
    # result: 0----------10----------20        30----------40----------50 
    a2 = Actions()
    a2.keyframes = a1.keyframes
    a2.intervals = a1.intervals


    assert a1.addActionsAt(a2, 30) == True
    #print a1.keyframes
    #print  map(lambda x: x.pos, a1.keyframes)
    assert len(a1.keyframes) == 6
    assert len(a1.intervals) == 4
    pos = map(lambda x: x.pos, a1.keyframes)
    assert pos == [0,10,20,30,40,50]
    vals = map(lambda x: x.getValue(), a1.keyframes)
    assert vals == [25., 35., 45., 25., 35., 45.] 
    kfs = a1.keyframes
    assert kfs[0].leftInterval == None
    assert kfs[2].rightInterval == None
    checkIntervals(a1, 0,2)
    assert kfs[3].leftInterval == None
    assert kfs[5].rightInterval == None
    checkIntervals(a1, 2,4)


def test_023addAction3():
    
    a1 = Actions()
    kf1 = KF( 0, 25. )
    kf2 = KF( 10, 35. )
    i1 = Interval(kf1, kf2)
    kf3 = KF( 10, 35. )
    kf4 = KF( 20, 45. )
    i2 = Interval(kf3, kf4)
    a1.addInterval(i1)
    a1.addInterval(i2)

    a2 = Actions()
    kf5 = KF( 0, 40. )
    kf6 = KF( 10, 50. )
    i3 = Interval(kf5, kf6)
    a2.addInterval(i3)
    #a2.keyframes = a1.keyframes[:2]
    #a2.intervals = [a1.intervals[0]]
    
    print "actions 2: ", a2.keyframes
    print "actions 2: ", a2.intervals

    print a1.keyframes
    print a1.intervals
    assert a1.addActionsAt(a2, 0)  == True

    print a1.keyframes
    print a1.intervals
    
    assert len(a1.keyframes) == 3
    assert len(a1.intervals) == 2
    assert a1.getValue(0) == 40.
    assert a1.getValue(10) == 50.
    assert a1.getValue(20) == 45.
    checkIntervals(a1, 0, 2)

    assert a1.addActionsAt(a2, 15) == False
    assert a1.addActionsAt(a2, 5) == False


    

def xtest_100getStringRepr():
    # FIXME 
    a = Actions()

    kf1 = KF( 0, 25. )
    kf2 = KF( 10, 35. )
    i1 = Interval(kf1, kf2)
    val = a.addInterval( i1 )

    kf0 = KF(15, 0.)
    a.addKeyframe( kf0 )

    kf3 = KF( 20, 30. )
    kf4 = KF( 30, 35. )
    val = a.addInterval( Interval(kf3, kf4) )

    labels, posStr, actStr, fullStr = a.getStringRepr()
    assert len(labels) == 4
    assert labels[0] == 0
    assert labels[1] == 10
    assert labels[2] == 20
    assert labels[3] == 30

    assert posStr=='                               |    :    |    :    |    :    |'
    assert actStr=='               ACTOR______NAMEx---------x    x    x---------x'

    assert fullStr=="                                         1         2         3\n                               0         0         0         0\n                               |    :    |    :    |    :    |\n               ACTOR______NAMEx---------x    x    x---------x"
    i1.active = False
    labels, posStr, actStr, fullStr = a.getStringRepr()
    assert len(labels) == 4
    assert labels[0] == 0
    assert labels[1] == 10
    assert labels[2] == 20
    assert labels[3] == 30
    print "posStr:"
    print "z%sz"%posStr
    print 'actStr:'
    print "z%sz"%actStr
    print 'fullStr:'
    print "z%sz"%fullStr
    assert posStr=='               |    :    |    :    |    :    |'
    assert actStr=='ACTOR______NAM x.........x    x    x---------x'
    assert fullStr=='                         1         2         3\n               0         0         0         0\n               |    :    |    :    |    :    |\nACTOR______NAM x.........x    x    x---------x'

    # fullStr is
    ##                          1         2         3
    ##                0         0         0         0
    ##                |    :    |    :    |    :    |
    ## ACTOR______NAM x.........x    x    x---------x


    labels, posStr, actStr, fullStr = a.getStringRepr(4, 22)
    assert len(labels) == 3
    assert labels[0] == 4
    assert labels[1] == 10
    assert labels[2] == 20

    assert posStr=='                :    |    :    |  '
    assert actStr=='ACTOR______NAM ......x    x    x--'
    assert fullStr=='                     1         2  \n               4     0         0  \n                :    |    :    |  \nACTOR______NAM ......x    x    x--'
    # fullStr is
    ##                      1         2  
    ##                4     0         0  
    ##                 :    |    :    |  
    ## ACTOR______NAM ......x    x    x--







##     """
##     Test adding an Interval in the middle of an existing one

##                          i1
##     kf1----------------------------------------------kf2
##                          i2
##                  kf3----------------kf4

## results in:

##           i1             i2               new
##     kf1----------kf3----------------kf4--------------kf2
   
##     """
    
##     a = Actions()

##     # add first interval from 10-40
##     kf1 = KF( 10, 25 )
##     kf2 = KF( 40, 35 )
##     i1 = Interval(kf1, kf2)
##     a.addIntervals( [i1] )
##     assert len(a.intervals) == 1
##     a.intervals[0] = i1
##     assert len(a.keyframes) == 2

##     # add second interval from 20-30
##     kf3 = KF( 20, 25 )
##     kf4 = KF( 30, 35 )
##     i2 = Interval(kf3, kf4)
##     a.addIntervals( [i2] )
##     assert len(a.intervals) == 3
##     assert len(a.keyframes) == 4
##     assert a.keyframes[0] == kf1
##     assert a.keyframes[1] == kf3
##     assert a.keyframes[2] == kf4
##     assert a.keyframes[3] == kf2

##     inter = a.intervals[0]
##     assert inter.kf1 == kf1
##     assert inter.kf2 == kf3

##     inter = a.intervals[1]
##     assert inter.kf1 == kf3
##     assert inter.kf2 == kf4

##     inter = a.intervals[2]
##     assert inter.kf1 == kf4
##     assert inter.kf2 == kf2


## def test_006deleteKF():
##     """
##     test deleteing keyframes
##     """
##     a = Actions()
##     kf1 = KF(0, 10)
##     kf2 = KF(10, 0)
##     i1 = Interval(kf1, kf2)
##     a.addIntervals( [i1] )

##     kf3 = KF(15, 0)
##     a.addKeyframe( kf3 )

##     assert len(a.keyframes) == 3

##     # test that we can delete kf3 because it is isolated
##     a.deleteKeyframe(kf3)
##     assert len(a.keyframes) == 2

##     # test that we can NOT delete kf2 because it belong to an interval
##     a.deleteKeyframe(kf2)
##     assert len(a.keyframes) == 2
    
 
## def test_007addInterval():
##     """
##     Test adding an Interval at the beginning of an existing one

##                          i1
##     kf1----------------------------------------------kf2
##               i2
##     kf3----------------kf4

## results in:

##           new                   i1
##     kf3----------------kf4--------------kf2
   
##     """
    
##     a = Actions()

##     # add first interval from 10-40
##     kf1 = KF( 10, 25 )
##     kf2 = KF( 40, 35 )
##     i1 = Interval(kf1, kf2)
##     a.addIntervals( [i1] )
##     assert len(a.intervals) == 1
##     a.intervals[0] = i1
##     assert len(a.keyframes) == 2

##     # add second interval from 20-30
##     kf3 = KF( 20, 25 )
##     kf4 = KF( 30, 35 )
##     i2 = Interval(kf3, kf4)
##     a.addIntervals( [i2] )
##     assert len(a.intervals) == 3
##     assert len(a.keyframes) == 4
##     assert a.keyframes[0] == kf1
##     assert a.keyframes[1] == kf3
##     assert a.keyframes[2] == kf4
##     assert a.keyframes[3] == kf2

##     inter = a.intervals[0]
##     assert inter.kf1 == kf1
##     assert inter.kf2 == kf3

##     inter = a.intervals[1]
##     assert inter.kf1 == kf3
##     assert inter.kf2 == kf4

##     inter = a.intervals[2]
##     assert inter.kf1 == kf4
##     assert inter.kf2 == kf2

## ## def test_004ActionsAddkeyframe2()
## ##     """
## ##     Test adding a KF that fall on nothing or an existing Interval
## ##     """
## ##      kf1 = KF( 10, 25 )
## ##      kf2 = KF( 20, 35 )

## ##      i1 = Interval(kf1, kf2)

## ##      a = Actions()
## ##      A

## def test_008AddAction():
##     kf0 = KF(0, (1,1,1))
##     act1 = Actions()
##     act1.addKeyframe(kf0)
##     kf1 = KF( 0, (0,0,0) )
##     kf2 = KF( 20,(10, 0,0) )
##     i1 = Interval(kf1, kf2 )
##     act2 = Actions()
##     act2.addIntervals([i1])
##     act1.addActionsAt(act2, 0)

##     assert len(act1.keyframes) == 2
##     assert act1.keyframes[0].pos == 0
##     assert act1.keyframes[1].pos == 20
