# -*- coding: iso-8859-1 -*-
from __future__ import division # 1/2 == .5 (par defaut, 1/2 == 0)

from customtest import *
symp = sympy.sympify

class TestGeolibPoints(CustomTest):

    def test_Point(self):
        A = Point(1, 2)
        self.assert_(isinstance(A.etiquette, Label_point))
        self.assertEqual(A.x, 1)
        self.assertEqual(A.y, 2)
        self.assertEqual(type(A.coordonnees),  tuple)
        A.x = 5
        A.y = 7
        self.assertEqual(A.coordonnees, (5, 7))
        self.assert_(A.style("legende") == param.NOM)
        # Test du typage dynamique
        d = Droite(rand_pt(), rand_pt())
        B = Point(d)
        self.assert_(isinstance(B, Glisseur_droite))
        c = Cercle(A, 3)
        C = Point(c)
        self.assert_(isinstance(C, Glisseur_cercle))
        d = Demidroite(rand_pt(), rand_pt())
        B = Point(d)
        self.assert_(isinstance(B, Glisseur_demidroite))
        s = Segment(rand_pt(), rand_pt())
        B = Point(s)
        self.assert_(isinstance(B, Glisseur_segment))
        a = Arc_points(Point(), Point(1, 1),  Point(1, 2))
        B = Point(a)
        self.assert_(isinstance(B, Glisseur_arc_cercle))

    def test_Point_sympy(self):
        A = Point('1/2', '2/3')
        self.assertEqual(A.x, symp('1/2'))
        self.assertAlmostEqual(A.coordonnees, (1/2, 2/3))


    def test_Milieu(self):
        A = Point(1,2)
        B = Point(2,4)
        I = Milieu(A,B)
        self.assert_(I.x == (A.x+B.x)/2 and I.y == (A.y+B.y)/2)
        self.assertEqual(type(I.coordonnees),  tuple)
        C = Point('1/3', '1')
        D = Point('1', '1')
        J = Milieu(C, D)
        self.assert_(J.x == symp('2/3'))


    def test_Barycentre(self):
        M = Point(3, 4)
        A = Point(1,2)
        B = Point(2,4)
        I = Milieu(A,B)
        K = Barycentre(M, A, B, (I, -4))
        self.assertEqual(K.x,  0)
        self.assertEqual(K.y,  2)
        self.assert_(not Barycentre(M, A, (B, -2)).existe)
        self.assertEqual(type(K.coordonnees),  tuple)
        # Test keyword 'points_ponderes'
        G = Barycentre(points_ponderes = (M, A, B, (I, -4)))
        self.assert_(K.coordonnees == G.coordonnees)
        self.assert_("point_ponderes" not in G.style())

    def test_Point_final(self):
        A = Point(random(),random())
        B = Point(random(),random())
        C = Point(random(),random())
        u = Vecteur_libre(random(),random())
        v = Vecteur(Point(random(),  random()),  Point(random(),  random()))
        w = Representant(Vecteur(Point(random(),  random()),  Point(random(),  random())),  A)
        F = Point_final(C,  (u, v, w), (-2, 1.5, 4))
        self.assertEqual(type(F.coordonnees),  tuple)
        self.assertAlmostEqual(F.x,  C.x -2*u.x+1.5*v.x+4*w.x)
        self.assertAlmostEqual(F.y,  C.y -2*u.y+1.5*v.y+4*w.y)

    def test_Point_translation(self):
        u = Vecteur_libre(1.56, 2.78)
        v = Vecteur(Point(1.1457, 2.7895), Point(2.458, -8.25))
        A = Point(5.256, -7.231)
        tu = Translation(u)
        tv = Translation(v)
        Au = Point_translation(A, tu)
        Av = Point_translation(A, tv)
        self.assertAlmostEqual(Au.coordonnees,  (6.816, -4.451))
        self.assertAlmostEqual(Av.coordonnees, (6.5683, -18.2705))

    def test_Point_rotation(self):
        A = Point(1, -4)
        r = Rotation(Point(-2, 7.56), 4.25)
        B = Point_rotation(A, r)
        self.assertAlmostEqual(r(A).coordonnees, B.coordonnees)
        self.assertAlmostEqual(B.coordonnees,  (-13.684339450863803, 10.031803308717693))
        A = Point('1',  '0')
        r = Rotation(('0', '0'), 'pi/4')
        B = Point_rotation(A, r)
        C = Point('sqrt(2)/2', 'sqrt(2)/2')
        self.assert_(C.x == B.x and C.y == B.y)

    def test_Point_homothetie(self):
        A = Point(1, -2)
        h = Homothetie(A, -3)
        M = Point(2, 7)
        self.assertAlmostEqual(Point_homothetie(M, h).coordonnees, (-2, -29))
#        self.assert_(Point_homothetie(A, h) is A)   -> méthode __new__ ?

    def test_Point_reflexion(self):
        d = Droite_equation(1, 6, -2)
        r = Reflexion(d)
        M = Point(random()+randint(50)-randint(50), random()+randint(50)-randint(50))
        m = Mediatrice(M,  Point_reflexion(M, r))
        self.assertAlmostEqual(d.equation_reduite,  m.equation_reduite)

    def test_Projete_droite(self):
        d = Droite_equation(1.25, -7.12, 2.15)
        A = Point(1.52, 2.14)
        M = Projete_droite(A, d)
        self.assert_(M in d)
        self.assert_(Droite(A, M)._perpendiculaire(d))

    def test_Projete_cercle(self):
        c = Cercle_equation(1, -2, -20)
        self.assert_(c.existe)
        A = Point(randint(50) - randint(50) + random(), randint(50) - randint(50) + random())
        P = Projete_cercle(A, c)
        self.assert_(P.existe)
        self.assert_(P in c)
        self.assert_(P in Demidroite(c.centre, A))
        A.coordonnees = c.centre.coordonnees
        self.assert_(not P.existe)

    def test_Projete_arc_cercle(self):
        O = Point(23.15, -12.75)
        A = Point(-12.5, 7.14)
        B = Point(7.15, 8.64)
        a = Arc_cercle(O, A, B)
        M = rand_pt()
        P = Projete_arc_cercle(M, a)
        self.assert_(P in a)
        M.coordonnees = a.centre.coordonnees
        self.assert_(not P.existe)
        M.coordonnees = -17.826266675199999, 11.760911186
        self.assert_(type(P.coordonnees) is tuple)
        self.assertAlmostEqual(A.coordonnees, P.coordonnees)
        self.assertEqual(A, P)

    def test_Projete_segment(self):
        s = Segment(rand_pt(), rand_pt())
        M = rand_pt()
        self.assert_(Projete_segment(M, s) in s)
        A = Point(0, 1)
        B = Point(2, 1)
        s = Segment(A, B)
        M = Point(1, 7.15)
        P = Projete_segment(M, s)
        self.assertAlmostEqual(Milieu(A, B).coordonnees, P.coordonnees)
        M.x = .5
        self.assertAlmostEqual(Barycentre((A, 3), (B, 1)).coordonnees, P.coordonnees)
        M.x = -1
        self.assertAlmostEqual(A.coordonnees, P.coordonnees)
        M.x = 3
        self.assertAlmostEqual(B.coordonnees, P.coordonnees)


    def test_Projete_demidroite(self):
        d = Demidroite(rand_pt(), rand_pt())
        M = rand_pt()
        self.assert_(Projete_demidroite(M, d) in d)
        A = Point(0, 1)
        B = Point(2, 1)
        s = Demidroite(A, B)
        M = Point(1, 7.15)
        P = Projete_demidroite(M, s)
        self.assertAlmostEqual(Milieu(A, B).coordonnees, P.coordonnees)
        M.x = .5
        self.assertAlmostEqual(Barycentre((A, 3), (B, 1)).coordonnees, P.coordonnees)
        M.x = -1
        self.assertAlmostEqual(A.coordonnees, P.coordonnees)
        M.x = 3
        self.assertAlmostEqual(Barycentre((A, -1), (B, 3)).coordonnees, P.coordonnees)


    def test_Centre_gravite(self):
        M = rand_pt()
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        I = Milieu(B, C)
        J = Milieu(A, C)
        K = Milieu(A, B)
        G = Centre_gravite(Triangle(A, B, C))
        self.assertAlmostEqual(Segment(A, G).longueur, 2*Segment(I, G).longueur)
        self.assertAlmostEqual(Segment(B, G).longueur, 2*Segment(J, G).longueur)
        self.assertAlmostEqual(Segment(C, G).longueur, 2*Segment(K, G).longueur)

    def test_Orthocentre(self):
        A, B, C = rand_pt(), rand_pt(), rand_pt()
        p = Polygone(A, B, C)
        H = Orthocentre(p)
        self.assert_(Droite(A, H).perpendiculaire(Droite(B, C)))
        self.assert_(Droite(B, H).perpendiculaire(Droite(A, C)))
        self.assert_(Droite(C, H).perpendiculaire(Droite(B, A)))

    def test_Centre_cercle_circonscrit(self):
        A, B, C = rand_pt(), rand_pt(), rand_pt()
        p = Polygone(A, B, C)
        O= Centre_cercle_circonscrit(p)
        self.assert_(O == Point_equidistant(A, B, C))

    def test_Centre_cercle_inscrit(self):
        A, B, C = rand_pt(), rand_pt(), rand_pt()
        p = Polygone(A, B, C)
        I = Centre_cercle_inscrit(p)
        P = Projete_segment(I, Segment(B, C))
        Q = Projete_segment(I, Segment(A, C))
        R = Projete_segment(I, Segment(A, B))
        c = Cercle(I, P)
        self.assert_(P in c and Q in c and R in c)

    def test_Centre(self):
        c = rand_cercle()
        O = Centre(c)
        M = Glisseur_cercle(c)
        self.assertAlmostEqual(Segment(O, M).longueur, c.rayon)

    def test_Point_equidistant(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        P = Point_equidistant(A, B, C)
        self.assertAlmostEqual(Segment(A, P).longueur, Segment(B, P).longueur)
        self.assertAlmostEqual(Segment(A, P).longueur, Segment(C, P).longueur)
        self.assert_(P in Mediatrice(A, B))

    def test_Glisseur_droite(self):
        A = rand_pt()
        B = rand_pt()
        d = Droite(A, B)
        M = Glisseur_droite(d)
        self.assert_(M in d)
        M.k = 0
        self.assertEqual(M.k, 0)
        self.assertAlmostEqual(M.coordonnees, A.coordonnees)
        P = Point(*M.coordonnees)
        M.k = 1
        self.assertEqual(M.k, 1)
        self.assertAlmostEqual(M.coordonnees, B.coordonnees)
        M.k = 2
        self.assertEqual(M.k, 2)
        M.k = -1
        self.assertEqual(M.k, -1)
        Q = Point(*M.coordonnees)
        self.assertAlmostEqual(Droite(P, Q).equation_reduite, d.equation_reduite)
        M.k = 1.7
        M(*M.coordonnees)
        self.assertAlmostEqual(M.k, 1.7)


    def test_Glisseur_segment(self):
        A = rand_pt()
        B = rand_pt()
        s = Segment(A, B)
        M = Glisseur_segment(s)
        self.assert_(M in s)
        M.k = 0
        self.assertEqual(M.k, 0)
        self.assertAlmostEqual(M.coordonnees, A.coordonnees)
        P = Point(*M.coordonnees)
        M.k = 1
        self.assertEqual(M.k, 1)
        self.assertAlmostEqual(M.coordonnees, B.coordonnees)
        M.k = 2
        self.assertEqual(M.k, 1) # 0<=k<=1 pour un segment
        self.assert_(M in s)
        M.k = -1
        self.assertEqual(M.k, 0) # 0<=k<=1 pour un segment
        self.assert_(M in s)
        M.k = 1
        Q = Point(*M.coordonnees)
        self.assertAlmostEqual(Droite(P, Q).equation_reduite, s.equation_reduite)
        M.k = 1.7
        M(*M.coordonnees)
        self.assertAlmostEqual(M.k, 1)

    def test_Glisseur_demidroite(self):
        A = rand_pt()
        B = rand_pt()
        d = Demidroite(A, B)
        M = Glisseur_demidroite(d)
        self.assert_(M in d)
        M.k = 0
        self.assertEqual(M.k, 0)
        self.assertAlmostEqual(M.coordonnees, A.coordonnees)
        P = Point(*M.coordonnees)
        M.k = 1
        self.assertEqual(M.k, 1)
        self.assertAlmostEqual(M.coordonnees, B.coordonnees)
        M.k = 2
        self.assertEqual(M.k, 2)
        M.k = -1
        self.assertEqual(M.k, 0) # k>=0 pour une demi-droite
        M.k = 1
        Q = Point(*M.coordonnees)
        self.assertAlmostEqual(Droite(P, Q).equation_reduite, d.equation_reduite)
        M.k = 1.7
        M(*M.coordonnees)
        self.assertAlmostEqual(M.k, 1.7)

    def test_Glisseur_cercle(self):
        c = rand_cercle()
        M = Glisseur_cercle(c)
        self.assert_(M in c)
        O = c.centre
        M.coordonnees = O.coordonnees
        # il faudrait compléter un peu

    def test_Glisseur_arc_cercle(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        a = Arc_cercle(A, B, C)
        M = Glisseur_arc_cercle(a)
        self.assert_(M in a)
        O = a.centre
        M.coordonnees = O.coordonnees
        # il faudrait compléter un peu




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