# python -m manim fichier.py Classe
from manim import *
from math import sqrt


# ================================================================
# FORMAT VERTICAL 9:16 — TIKTOK / INSTAGRAM
# ================================================================

config.pixel_width = 1080
config.pixel_height = 1920
config.frame_rate = 30
config.background_color = WHITE


class EnsemblesNombres(Scene):

    def construct(self):

        # ============================================================
        # COULEURS
        # ============================================================

        NOIR = BLACK

        # Couleur utilisée uniquement pour les nouveaux nombres
        # qui apparaissent à chaque étape.
        COULEUR_Z = BLUE
        COULEUR_D = GREEN
        COULEUR_Q = ORANGE
        COULEUR_IRRATIONNELS = PURPLE

        # ============================================================
        # TITRE
        # ============================================================

        titre = Text(
            "Les ensembles de nombres",
            font_size=42,
            color=NOIR
        )

        titre.to_edge(UP, buff=0.45)

        self.play(
            Write(titre)
        )
        
        # ============================================================
        # SIGNATURE / SITE
        # ============================================================

        signature = Text(
            "courspasquet.fr",
            font_size=28,
            color=BLACK
        )

        signature.move_to(
            RIGHT * (config.frame_width / 2 - 2)
            + DOWN * (config.frame_height - 0)
        )

        self.add(signature)

        self.wait(1)

        # ============================================================
        # DROITE GRADUÉE
        # ============================================================

        axe = NumberLine(
            x_range=[-5, 5, 1],
            length=10,
            include_numbers=False,
            include_ticks=True,
            tick_size=0.12,
            stroke_width=3,
            color=NOIR
        )

        # La droite est légèrement au-dessus du centre
        axe.move_to(UP * 0.25)

        self.play(
            Create(axe)
        )

        self.wait(0.5)

        # ============================================================
        # 1. ENTIERS NATURELS : N
        # ============================================================

        nombres_naturels = VGroup()

        for n in range(0, 6):

            nombre = MathTex(
                str(n),
                font_size=34,
                color=NOIR
            )

            nombre.move_to(
                axe.n2p(n) + DOWN * 0.42
            )

            nombres_naturels.add(nombre)

        # Texte N
        texte_N = VGroup(

            MathTex(
                r"\mathbb{N}: \text{ ensemble des entiers naturels}",
                font_size=31,
                color=NOIR
            ),

            Text(
                "(qui servent principalement à compter)",
                font_size=25,
                color=NOIR
            )

        ).arrange(
            DOWN,
            buff=0.12
        )

        texte_N.to_edge(
            DOWN,
            buff=0.6
        )

        # Apparition des naturels
        self.play(
            LaggedStart(
                *[
                    Write(nombre)
                    for nombre in nombres_naturels
                ],
                lag_ratio=0.12
            )
        )

        self.play(
            FadeIn(
                texte_N,
                shift=UP * 0.2
            )
        )

        self.wait(2)

        # ============================================================
        # 2. ENTIERS RELATIFS : Z
        # ============================================================

        nombres_negatifs = VGroup()

        for n in range(-5, 0):

            nombre = MathTex(
                str(n),
                font_size=34,
                color=COULEUR_Z
            )

            nombre.move_to(
                axe.n2p(n) + DOWN * 0.42
            )

            nombres_negatifs.add(nombre)

        # Texte Z
        texte_Z = VGroup(

            MathTex(
                r"\mathbb{Z}: \text{ ensemble des entiers relatifs}",
                font_size=31,
                color=COULEUR_Z
            ),

            Text(
                '"Z" pour "Zahl", qui signifie "nombre" en allemand',
                font_size=24,
                color=COULEUR_Z
            )

        ).arrange(
            DOWN,
            buff=0.12
        )

        texte_Z.to_edge(
            DOWN,
            buff=0.55
        )

        # Apparition des nombres négatifs
        self.play(
            LaggedStart(
                *[
                    Write(nombre)
                    for nombre in nombres_negatifs
                ],
                lag_ratio=0.12
            )
        )

        # Remplacement du texte
        self.play(
            FadeOut(texte_N),
            FadeIn(
                texte_Z,
                shift=UP * 0.2
            )
        )

        self.wait(2)

        # ============================================================
        # 3. NOMBRES DÉCIMAUX : D
        # ============================================================

        # ------------------------------------------------------------
        # Petites graduations intermédiaires
        # ------------------------------------------------------------

        graduations_decimales = VGroup()

        for i in range(-49, 50):

            x = i / 10

            # Ne pas créer une petite graduation sur les entiers
            if abs(x - round(x)) < 0.001:
                continue

            ligne = Line(
                axe.n2p(x) + UP * 0.035,
                axe.n2p(x) + DOWN * 0.035,
                stroke_width=2,
                color=NOIR
            )

            graduations_decimales.add(ligne)

        # ------------------------------------------------------------
        # Quelques exemples de nombres décimaux
        # ------------------------------------------------------------

        exemples_D = VGroup()

        valeurs_D = [
            -4.5,
            -2.5,
            -1.5,
            0.5,
            1.5,
            2.5,
            4.5
        ]

        for x in valeurs_D:

            nombre = MathTex(
                str(x).replace(".", ","),
                font_size=28,
                color=COULEUR_D
            )

            nombre.move_to(
                axe.n2p(x) + UP * 0.42
            )

            exemples_D.add(nombre)

        # ------------------------------------------------------------
        # Texte D
        # ------------------------------------------------------------

        texte_D = VGroup(

            MathTex(
                r"\mathbb{D}: \text{ ensemble des nombres décimaux}",
                font_size=30,
                color=COULEUR_D
            ),

            MathTex(
                r"\text{qui peuvent s'écrire sous la forme }"
                r"\frac{a}{10^n}",
                font_size=25,
                color=COULEUR_D
            ),

            MathTex(
                r"\text{avec }a\in\mathbb{Z}\text{ et }n\in\mathbb{N}",
                font_size=25,
                color=COULEUR_D
            )

        ).arrange(
            DOWN,
            buff=0.09
        )

        texte_D.to_edge(
            DOWN,
            buff=0.45
        )

        # Apparition des petites graduations
        self.play(
            LaggedStart(
                *[
                    Create(g)
                    for g in graduations_decimales
                ],
                lag_ratio=0.01
            ),
            run_time=2
        )

        # Apparition des décimaux
        self.play(
            LaggedStart(
                *[
                    Write(nombre)
                    for nombre in exemples_D
                ],
                lag_ratio=0.12
            )
        )

        # Remplacement du texte
        self.play(
            FadeOut(texte_Z),
            FadeIn(
                texte_D,
                shift=UP * 0.2
            )
        )

        self.wait(2)

        # ============================================================
        # 4. NOMBRES RATIONNELS : Q
        # ============================================================

        rationnels = [
            (-4, 3),
            (-2, 3),
            (1, 3),
            (2, 3),
            (4, 3)
        ]

        nombres_Q = VGroup()

        for p, q in rationnels:

            valeur = p / q

            fraction = MathTex(
                rf"\frac{{{p}}}{{{q}}}",
                font_size=29,
                color=COULEUR_Q
            )

            # Les fractions sont AU-DESSUS de la droite
            fraction.move_to(
                axe.n2p(valeur) + UP * 0.95
            )

            nombres_Q.add(fraction)

        # ------------------------------------------------------------
        # Texte Q
        # ------------------------------------------------------------

        texte_Q = VGroup(

            MathTex(
                r"\mathbb{Q}: \text{ ensemble des nombres rationnels}",
                font_size=30,
                color=COULEUR_Q
            ),

            MathTex(
                r"\text{qui s'écrivent sous la forme }"
                r"\frac{p}{q}",
                font_size=25,
                color=COULEUR_Q
            ),

            MathTex(
                r"\text{avec }p,q\in\mathbb{Z}\text{ et }q\neq0",
                font_size=25,
                color=COULEUR_Q
            )

        ).arrange(
            DOWN,
            buff=0.09
        )

        texte_Q.to_edge(
            DOWN,
            buff=0.45
        )

        # Apparition des rationnels
        self.play(
            LaggedStart(
                *[
                    Write(nombre)
                    for nombre in nombres_Q
                ],
                lag_ratio=0.15
            )
        )

        # Remplacement du texte
        self.play(
            FadeOut(texte_D),
            FadeIn(
                texte_Q,
                shift=UP * 0.2
            )
        )

        self.wait(2)

        # ============================================================
        # 5. NOMBRES RÉELS : R
        # ============================================================

        # ------------------------------------------------------------
        # Irrationnels
        # ------------------------------------------------------------

        exemples_irrationnels = [
            (sqrt(2), r"\sqrt{2}"),
            (PI, r"\pi"),
            (-sqrt(2), r"-\sqrt{2}")
        ]

        irrationnels = VGroup()

        for valeur, texte in exemples_irrationnels:

            nombre = MathTex(
                texte,
                font_size=34,
                color=COULEUR_IRRATIONNELS
            )

            # Les irrationnels sont SOUS la droite
            nombre.move_to(
                axe.n2p(valeur) + DOWN * 0.72
            )

            irrationnels.add(nombre)

        # ------------------------------------------------------------
        # Texte R
        # ------------------------------------------------------------

        texte_R = VGroup(

            MathTex(
                r"\mathbb{R}: \text{ ensemble des nombres réels}",
                font_size=31,
                color=NOIR
            ),

            MathTex(
                r"\text{tous les nombres qui peuvent apparaître}"
                r"\text{ sur la droite graduée}",
                font_size=25,
                color=NOIR
            )

        ).arrange(
            DOWN,
            buff=0.12
        )

        texte_R.to_edge(
            DOWN,
            buff=0.55
        )

        # Apparition des irrationnels
        self.play(
            LaggedStart(
                *[
                    Write(nombre)
                    for nombre in irrationnels
                ],
                lag_ratio=0.3
            )
        )

        # Remplacement du texte
        self.play(
            FadeOut(texte_Q),
            FadeIn(
                texte_R,
                shift=UP * 0.2
            )
        )

        self.wait(3)

        # ============================================================
        # CONCLUSION
        # ============================================================

        inclusion = MathTex(
            r"\mathbb{N}\subset\mathbb{Z}\subset\mathbb{D}"
            r"\subset\mathbb{Q}\subset\mathbb{R}",
            font_size=40,
            color=NOIR
        )

        inclusion.to_edge(
            UP,
            buff=0.5
        )

        self.play(
            FadeOut(titre),
            FadeIn(inclusion)
        )

        self.wait(4)