#!/cygdrive/c/Python26/python.exe
# Based on TestPendulum.cpp SimTK example program

import sys
import simtk.molmodel as ss
from simtk.molmodel import Vec3
import unittest

class TestVec3(unittest.TestCase):
    def assertSimilarVectors(self, v1, v2):
        diff = v2 - v1
        diff = abs(diff)
        self.assertAlmostEqual(0, diff)

    def assertNotSimilarVectors(self, v1, v2):
        diff = v2 - v1
        diff = abs(diff)
        self.assertNotAlmostEqual(0, diff)
        
    def test_negate(self):
        v = ss.Vec3(1,-2,3)
        print v
        print -v
        
    def test_getitem(self):
        v = ss.Vec3(1,2,3)
        self.assertEqual(1.0, v[0])
        self.assertEqual(2.0, v[1])
        self.assertEqual(3.0, v[2])
        self.assertNotEqual(7.0, v[1])
        
    def test_str(self):
        v = ss.Vec3(1,2,3)
        self.assertEqual("Vec3(1.000000, 2.000000, 3.000000)", str(v))
        
    def test_len(self):
        self.assertEqual( 3, len(ss.Vec3()) )
        self.assertEqual( 3, len(ss.Vec3(1,2,3)) )
        
    def test_iter(self):
        v = ss.Vec3(1,2,3)
        count = 0
        for e in v:
            count += 1
        self.assertEqual(3, count)
        
    def test_setitem(self):
        v = ss.Vec3(1,2,3)
        self.assertNotEqual(7, v[1])
        v[1] = 7
        self.assertEqual(7, v[1])

    def test_to_tuple(self):
        v = ss.Vec3(1,2,3)
        self.assertEqual( (1,2,3), tuple(v) )
        
    def test_from_tuple(self):
        v = ss.Vec3(tuple([2,1,2]))
        self.assertSimilarVectors(v, ss.Vec3(2,1,2))
        
    def test_simtk_methods(self):
        v = ss.Vec3(2,1,-2)
        self.assertEqual(3, v.size())
        self.assertEqual(3, v.nrow())
        self.assertEqual(1, v.ncol())
        self.assertEqual(9, v.scalarNormSqr())
        self.assertNotSimilarVectors(ss.Vec3(2,1,2), v)
        self.assertSimilarVectors(ss.Vec3(2,1,2), v.abs())
        self.assertEqual(1, v.sum())
        
    def test_copy(self):
        # assignment by reference, like python, not by value, like C++
        v1 = ss.Vec3(1,2,3)
        v2 = v1
        v2[1] = 7
        self.assertEqual(7, v1[1])
        # copy constructor copy by value
        v3 = ss.Vec3(v1)
        v3[1] = 5
        self.assertEqual(5, v3[1])
        self.assertEqual(7, v1[1])
        
    def test_py_abs(self):
        v = ss.Vec3(2,1,-2)
        self.assertEqual(3, abs(v))


if __name__ == '__main__':
    unittest.main()
