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

from customtest import *


class TestGeolibPolygones(CustomTest):

##    def test_Cote(self):
##        pass # À ÉCRIRE
##
##    def test_Sommet(self):
##        pass # À ÉCRIRE

    def test_Polygone(self):
        # cas général : polygone à 11 côtés :
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        E = rand_pt()
        F = rand_pt()
        G = rand_pt()
        H = rand_pt()
        I = rand_pt()
        J = rand_pt()
        K = rand_pt()
        p = p0 = Polygone(A, B, C, D, E, F, G, H, I, J, K)
        self.assert_(isinstance(p.etiquette, Label_polygone))
        self.assert_(p.sommets[0] == A and p.sommets[10] == K)
        self.assert_(Milieu(B, C) in p.cotes[1])
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D, E, F, G, H, I, J, K).coordonnees)
        # cas particuliers :
        t = Polygone(A, B, C)
        O = t.centre_cercle_circonscrit
        self.assertAlmostEqual(Segment(O, A).longueur, Segment(O, C).longueur)
        self.assert_(Droite(t.orthocentre, C).perpendiculaire(Droite(A, B)))
        self.assert_(t.__class__ is Triangle)
        p = Polygone(A, B, C,  D)
        self.assert_(p.__class__ is Quadrilatere)
        p = Polygone(A, B, C,  D, E)
        self.assert_(p.__class__ is Pentagone)
        p = Polygone(A, B, C,  D, E, F)
        self.assert_(p.__class__ is Hexagone)
        p = Polygone(A, B, C,  D, E, F, G)
        self.assert_(p.__class__ is Heptagone)
        p = Polygone(A, B, C,  D, E, F, G, H)
        self.assert_(p.__class__ is Octogone)
        self.assert_(p._hierarchie < p.sommets[0]._hierarchie < p.sommets[1]._hierarchie < p.sommets[7]._hierarchie < p._hierarchie + 1)
        # Test keyword 'points'
        p = Polygone(points = (A, B, C, D, E, F, G, H, I, J, K))
        self.assert_(p.centre.coordonnees == p0.centre.coordonnees)
        self.assert_("points" not in p.style())
        # Syntaxe spéciale : Polygone créé sans arguments, ou avec un entier comme argument.
        p = Polygone()
        p = Polygone(2)
        self.assert_(isinstance(p, Segment))
        p = Polygone(3)
        self.assert_(isinstance(p, Triangle))
        p = Polygone(n = 5)
        self.assert_(isinstance(p, Pentagone))
        p = Polygone(n = 12)
        self.assert_(len(p.points) == 12)
        p = Polygone(23)
        self.assert_(len(p.points) == 23)
        self.assert_(len(str(p.points)) < 30000)


    def test_Triangle(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        t = Triangle(A, B, C)
        O = t.centre_cercle_circonscrit
        self.assertAlmostEqual(Segment(O, A).longueur, Segment(O, C).longueur)

    def test_Quadrilatere(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        p = Quadrilatere(A, B, C, D)
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D).coordonnees)

    def test_Pentagone(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        E = rand_pt()
        p = Pentagone(A, B, C, D, E)
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D, E).coordonnees)

    def test_Hexagone(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        E = rand_pt()
        F = rand_pt()
        p = Hexagone(A, B, C, D, E, F)
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D, E, F).coordonnees)

    def test_Heptagone(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        E = rand_pt()
        F = rand_pt()
        G = rand_pt()
        p = Heptagone(A, B, C, D, E, F, G)
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D, E, F, G).coordonnees)

    def test_Octogone(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        D = rand_pt()
        E = rand_pt()
        F = rand_pt()
        G = rand_pt()
        H = rand_pt()
        p = Octogone(A, B, C, D, E, F, G, H)
        self.assertAlmostEqual(p.centre.coordonnees, Barycentre(A, B, C, D, E, F, G, H).coordonnees)

    def test_Parallelogramme(self):
        A = rand_pt()
        B = rand_pt()
        C = rand_pt()
        p = Parallelogramme(A, B, C)
        D = p.sommets[3]
        self.assertEqual(Vecteur(A, B), Vecteur(D, C))

    def test_Rectangle(self):
        A = rand_pt()
        B = rand_pt()
        r = Rectangle(A, B)
        M, N, O, P = r.sommets
        diagonale1 = Segment(M, O)
        diagonale2 = Segment(N, P)
        self.assertAlmostEqual(diagonale1.longueur, diagonale2.longueur)
        cote = Droite(M, N)
        cote_oppose = Droite(O, P)
        self.assert_(cote.parallele(cote_oppose))


    def test_Losange(self):
        A = rand_pt()
        B = rand_pt()
        l = Losange(A, B)
        M, N, O, P = l.sommets
        diagonale1 = Droite(M, O)
        diagonale2 = Droite(N, P)
        self.assert_(diagonale1.perpendiculaire(diagonale2))
        cote = Droite(M, N)
        cote_oppose = Droite(O, P)
        self.assert_(cote.parallele(cote_oppose))

    def test_Polygone_regulier_centre(self):
        O = rand_pt()
        M = rand_pt()
        p = Polygone_regulier_centre(O, M, 15)
        self.assert_(len(p.cotes) == 15)
        self.assert_(p.centre is O)
        for Mi in p.sommets:
            self.assertAlmostEqual(Segment(O, Mi).longueur, Segment(O, M).longueur)
        for i in xrange(10):
            coeffs = tuple(random() for i in xrange(15))
            G = Barycentre(*zip(p.sommets, coeffs))
            self.assert_(G in p)
            G.points_ponderes[randint(11)].coefficient = -5
            self.assert_(G not in p)
        # cas particuliers :
        p = Polygone_regulier_centre(O, M, 3)
        self.assert_(isinstance(p,  Triangle))
        p = Polygone_regulier_centre(O, M, 4)
        self.assert_(isinstance(p,  Quadrilatere))
        self.assert_(len(str(p.points)) < 30000)

    def test_Triangle_equilateral_centre(self):
        O = rand_pt()
        M = rand_pt()
        p = Triangle_equilateral_centre(O, M)
        self.assert_(p.centre.existe and p.centre is O)
        self.assert_(p.centre_cercle_circonscrit.existe)
        self.assert_(p.centre_cercle_inscrit.existe)
        self.assert_(p.orthocentre.existe)
        self.assert_(p.orthocentre == p.centre == p.centre_cercle_circonscrit == p.centre_cercle_inscrit)

    def test_Carre_centre(self):
        O = rand_pt()
        M = rand_pt()
        p = Carre_centre(O, M)
        self.assert_(p.centre.existe and p.centre is O)
        self.assert_(len(p.cotes) == 4)
        self.assertAlmostEqual(p.aire,  p.cotes[0].longueur**2)

    def test_Polygone_regulier(self):
        O = rand_pt()
        M = rand_pt()
        p = Polygone_regulier(O, M, 15)
        self.assert_(len(p.cotes) == 15)
        self.assert_(p.centre in Mediatrice(O, M))
        for i in xrange(15):
            self.assertAlmostEqual(Segment(p.sommets[i%15], p.sommets[(i+1)%15]).longueur, Segment(p.sommets[(i+2)%15], p.sommets[(i+3)%15]).longueur)
        p = Polygone_regulier(O, M, 3)
        self.assert_(isinstance(p,  Triangle))
        p = Polygone_regulier(O, M, 4)
        self.assert_(isinstance(p,  Quadrilatere))
        # Test de régression :
        # la taille de str(p.points) croissait exponentiellement.
        self.assert_(len(str(p.points)) < 30000)


    def test_Triangle_equilateral(self):
        O = rand_pt()
        M = rand_pt()
        p = Triangle_equilateral(O, M)
        self.assert_(p.centre.existe)
        self.assert_(p.centre_cercle_circonscrit.existe)
        self.assert_(p.centre_cercle_inscrit.existe)
        self.assert_(p.orthocentre.existe)
        self.assert_(p.orthocentre == p.centre == p.centre_cercle_circonscrit == p.centre_cercle_inscrit)

    def test_Carre(self):
        O = rand_pt()
        M = rand_pt()
        p = Carre(O, M)
        A, B, C, D = p.sommets
        self.assert_(p.centre == Milieu(A, C) == Milieu(B, D))
        self.assert_(A == O and B == M)
        self.assert_(len(p.cotes) == 4)
        self.assertAlmostEqual(p.aire,  p.cotes[0].longueur**2)
        # Test redéfinition d'un sommet
        c = Carre((3, 2), (7, 2))
        M = Point(0, 2)
        c.point1 = M
        self.assert_(c.point1 is M)
        self.assert_(c.regulier)
        self.assertAlmostEqual(c.aire, 49)
        self.assertAlmostEqual(c.point4.coordonnees, (0, 9))


    def test_Triangle_Isocele(self):
        A = rand_pt()
        B = rand_pt()
        tri = Triangle_isocele(A, B, 2*math.pi/13)
        C = tri.point3
        a = Angle(B, A, C)
        self.assertAlmostEqual(a.radian, 2*math.pi/13)
        self.assertAlmostEqual(Segment(A, B).longueur, Segment(A, C).longueur)

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