from big_ol_pile_of_manim_imports import *
from old_projects.lost_lecture import ShowWord
from old_projects.clacks.solution2.mirror_scenes import ReflectWorldThroughMirrorNew
from old_projects.clacks.question import Thumbnail


class WrapperScene(Scene):
    CONFIG = {
        "title": "Title",
        "shade_of_grey": "#333333"
    }

    def construct(self):
        title = TextMobject(self.title)
        title.scale(1.5)
        title.to_edge(UP)
        big_rect = self.get_big_rect()
        screen_rect = self.get_screen_rect()
        screen_rect.next_to(title, DOWN)

        self.add(big_rect, screen_rect)
        self.play(
            FadeIn(big_rect),
            FadeInFrom(title, DOWN),
            FadeInFrom(screen_rect, UP),
        )
        self.wait()

    def get_big_rect(self):
        big_rect = FullScreenFadeRectangle()
        big_rect.set_fill(self.shade_of_grey, 1)
        return big_rect

    def get_screen_rect(self, height=6):
        screen_rect = ScreenRectangle(height=height)
        screen_rect.set_fill(BLACK, 1)
        return screen_rect


class ComingUpWrapper(WrapperScene):
    CONFIG = {"title": "Coming up..."}


class LastVideoWrapper(WrapperScene):
    CONFIG = {"title": "Last time..."}


class LeftEdge(Scene):
    CONFIG = {
        "text": "Left edge",
        "vect": LEFT,
    }

    def construct(self):
        words = TextMobject(self.text)
        arrow = Vector(self.vect)
        arrow.match_width(words)
        arrow.next_to(words, DOWN)

        self.play(
            FadeInFromDown(words),
            GrowArrow(arrow)
        )
        self.wait()


class RightEdge(LeftEdge):
    CONFIG = {
        "text": "Right edge",
        "vect": RIGHT,
    }


class NoteOnEnergyLostToSound(Scene):
    def construct(self):
        self.add(TextMobject(
            "Yeah yeah, the clack sound\\\\"
            "would require energy, but\\\\"
            "don't let accuracy get in the\\\\"
            "way of delight!",
            alignment="",
        ))


class DotProductVideoWrapper(WrapperScene):
    CONFIG = {"title": "Dot product"}


class Rectangle(Scene):
    def construct(self):
        rect = ScreenRectangle(height=FRAME_HEIGHT - 0.25)
        rect.set_stroke(WHITE, 6)
        self.add(rect)


class ShowRectangleCreation(Scene):
    def construct(self):
        rect = ScreenRectangle(height=2)
        rect.set_stroke(YELLOW, 6)
        self.play(ShowCreation(rect))
        self.play(FadeOut(rect))


class ShowDotProductMeaning(Scene):
    def construct(self):
        v_vect = Vector(2 * RIGHT, color=YELLOW)
        w_vect = Vector(3 * RIGHT, color=PINK)
        dot = Dot(color=RED)
        dot.shift(DOWN)

        v_vect.angle_tracker = ValueTracker()
        w_vect.angle_tracker = ValueTracker()

        def update_vect(vect):
            target = vect.angle_tracker.get_value()
            vect.rotate(target - vect.get_angle())
            vect.shift(dot.get_center() - vect.get_start())

        v_vect.add_updater(update_vect)
        w_vect.add_updater(update_vect)

        v_label = TexMobject("\\vec{\\textbf{v}}")
        v_label.vect = v_vect
        w_label = TexMobject("\\vec{\\textbf{w}}")
        w_label.vect = w_vect
        for label in v_label, w_label:
            label.match_color(label.vect)
            label.set_stroke(BLACK, 5, background=True)

        def update_label(label):
            target = np.array(label.vect.get_end())
            target += 0.25 * normalize(label.vect.get_vector())
            label.move_to(target)

        v_label.add_updater(update_label)
        w_label.add_updater(update_label)

        title = TexMobject(
            "\\vec{\\textbf{w}}",
            "\\cdot",
            "\\vec{\\textbf{v}}",
            "=",
            "||", "\\vec{\\textbf{w}}", "||",
            "\\cdot",
            "||", "\\vec{\\textbf{v}}", "||",
            "\\cdot",
            "\\cos(\\theta)"
        )
        title.set_color_by_tex_to_color_map({
            "textbf{v}": v_vect.get_color(),
            "textbf{w}": w_vect.get_color(),
        })
        title.to_edge(UP)

        def get_w_line():
            center = dot.get_center()
            direction = w_vect.get_vector()
            return Line(
                center - 3 * direction,
                center + 3 * direction,
                stroke_color=LIGHT_GREY,
                stroke_width=1,
            )
        w_line = always_redraw(get_w_line)

        def get_proj_v():
            center = dot.get_center()
            v = v_vect.get_vector()
            w = w_vect.get_vector()
            w_unit = normalize(w)
            result = Vector(np.dot(v, w_unit) * w_unit)
            result.set_fill(v_vect.get_color(), 0.5)
            result.shift(center - result.get_start())
            return result
        proj_v = always_redraw(get_proj_v)

        def get_proj_line():
            return DashedLine(
                v_vect.get_end(),
                proj_v.get_end(),
                stroke_width=1,
                dash_length=0.025,
            )
        proj_line = always_redraw(get_proj_line)

        template_line = Line(LEFT, RIGHT)

        def get_vect_brace(vect):
            brace = Brace(template_line, UP, buff=SMALL_BUFF)
            brace.set_width(vect.get_length(), stretch=True)
            angle = vect.get_angle() % TAU
            if angle < PI:
                angle += PI
            brace.rotate(angle, about_point=ORIGIN)
            brace.shift(vect.get_center())
            return brace
        w_brace = always_redraw(
            lambda: get_vect_brace(w_vect)
        )
        proj_v_brace = always_redraw(
            lambda: get_vect_brace(proj_v)
        )

        def get_arc():
            center = dot.get_center()
            a1 = w_vect.get_angle()
            a2 = v_vect.get_angle()
            arc = Arc(
                start_angle=a1,
                angle=a2 - a1,
                radius=0.5,
                arc_center=center,
            )
            theta = TexMobject("\\theta")
            p = arc.point_from_proportion(0.5)
            theta.move_to(
                center + 1.5 * (p - center)
            )
            return VGroup(arc, theta)
        arc = always_redraw(get_arc)

        self.add(
            title[:3],
            w_vect, v_vect, dot,
            w_label, v_label,
        )
        self.play(
            v_vect.angle_tracker.set_value, 170 * DEGREES,
            w_vect.angle_tracker.set_value, 45 * DEGREES,
            run_time=2,
        )
        self.wait()
        w_brace.update()
        self.play(
            GrowFromCenter(w_brace),
            Write(title[3:7])
        )

        self.add(w_line, w_vect, w_label, dot)
        self.play(ShowCreation(w_line))
        proj_v.update()
        self.play(
            ShowCreation(proj_line),
            TransformFromCopy(v_vect, proj_v),
        )
        self.add(proj_v, proj_line, dot)
        proj_v_brace.update()
        self.play(
            GrowFromCenter(proj_v_brace),
            FadeInFromDown(title[7:])
        )
        arc.update()
        self.play(Write(arc))
        self.wait()

        for angle in [135, 225, 270, 90, 150]:
            self.play(
                v_vect.angle_tracker.set_value, angle * DEGREES,
                run_time=2
            )
            self.wait()


class FinalComment(Scene):
    def construct(self):
        self.add(TextMobject(
            "Thoughts on what ending should go here?\\\\"
            "See the Patreon post."
        ))


class FourtyFiveDegreeLine(Scene):
    CONFIG = {
        "angle": 45 * DEGREES,
        "label_config": {
            "num_decimal_places": 0,
            "unit": "^\\circ",
            "label_height": 0.3,
        },
        "degrees": True
    }

    def construct(self):
        angle = self.angle
        arc = Arc(angle, radius=1)
        label = DecimalNumber(0, **self.label_config)
        label.set_height(self.label_config["label_height"])
        label.next_to(arc, RIGHT)
        label.shift(0.5 * SMALL_BUFF * UP)
        line1 = Line(ORIGIN, 3 * RIGHT)
        line2 = line1.copy()

        if self.degrees:
            target_value = int(angle / DEGREES)
        else:
            target_value = angle

        self.add(line1, label)
        self.play(
            ChangeDecimalToValue(label, target_value),
            ShowCreation(arc),
            Rotate(line2, angle, about_point=ORIGIN)
        )
        self.wait()


class ArctanSqrtPoint1Angle(FourtyFiveDegreeLine):
    CONFIG = {
        "angle": np.arctan(np.sqrt(0.1)),
    }


class AskAboutAddingThetaToItself(Scene):
    CONFIG = {
        "theta": np.arctan(0.25),
        "wait_time": 0.25,
        "wedge_radius": 3,
        "theta_symbol_scale_val": 0.5,
        "number_height": 0.2,
    }

    def construct(self):
        theta = self.theta
        groups = self.get_groups(theta)
        horizon = self.get_horizon()
        counter = ValueTracker(0)
        dynamic_ineq = self.get_dynamic_inequality(counter)
        semicircle = self.get_semicircle()

        self.add(horizon)
        self.add(dynamic_ineq)

        for n in range(len(groups)):
            counter.set_value(n + 1)
            if n < len(groups) - 1:
                groups[n][-1].set_color(YELLOW)
                if n > 0:
                    groups[n - 1][-1].set_color(WHITE)
            self.add(groups[:n + 1])
            self.add_sound("pen_click", gain=-20)
            self.wait(self.wait_time)
        self.wait(0.5)

        counter.set_value(counter.get_value() - 1)
        self.remove(groups[-1])
        self.add_sound("pen_click", gain=-20)
        self.wait()

        self.play(ShowCreation(semicircle))
        self.play(FadeOut(semicircle))

        self.wait(3)

    def get_group(self, theta):
        # Define group
        wedge_radius = self.wedge_radius
        wedge = VGroup(
            Line(ORIGIN, wedge_radius * RIGHT),
            Line(ORIGIN, wedge_radius * RIGHT).rotate(
                theta, about_point=ORIGIN
            ),
        )
        wedge.set_stroke((WHITE, GREY), 2)
        arc = Arc(theta, radius=1)
        theta_symbol = TexMobject("\\theta")
        tssv = self.theta_symbol_scale_val
        theta_symbol.scale(tssv)
        theta_symbol.next_to(arc, RIGHT, tssv / 2)
        theta_symbol.shift(tssv * SMALL_BUFF * UP)

        return VGroup(wedge, arc, theta_symbol)

    def get_groups(self, theta):
        group = self.get_group(theta)
        angles = [k * theta for k in range(int(PI / theta) + 1)]
        groups = VGroup(*[
            group.copy().rotate(angle, about_point=ORIGIN)
            for angle in angles
        ])
        # colors = it.cycle([BLUE_D, BLUE_B, BLUE_C, GREY_BROWN])
        colors = it.cycle([BLUE_D, GREY_BROWN])
        for n, angle, group, color in zip(it.count(1), angles, groups, colors):
            wedge, arc, symbol = group
            symbol.rotate(-angle)
            arc.set_color(color)
            number = Integer(n)
            number.set_height(self.number_height)
            number.move_to(center_of_mass([
                wedge[0].get_end(),
                wedge[1].get_end(),
            ]))
            group.add(number)
        groups[-1][-1].set_color(RED)

        return groups

    def get_horizon(self):
        horizon = DashedLine(5 * LEFT, 5 * RIGHT)
        horizon.set_stroke(WHITE, 1)
        return horizon

    def get_semicircle(self):
        return Arc(
            start_angle=0,
            angle=PI,
            radius=self.wedge_radius / 2,
            color=YELLOW,
            stroke_width=4,
        )

    def get_inequality(self):
        ineq = TexMobject(
            "N", "\\cdot", "\\theta", "<",
            "\\pi", "=", "3.1415926\\dots"
        )
        N = ineq.get_part_by_tex("N")
        self.pi_symbol = ineq.get_part_by_tex("\\pi")
        N.set_color(YELLOW)
        # ineq[-3:].set_color(BLUE)

        brace = Brace(N, UP, buff=SMALL_BUFF)
        text = brace.get_text("Maximum", buff=SMALL_BUFF)
        group = VGroup(ineq, brace, text)
        group.next_to(ORIGIN, DOWN, MED_LARGE_BUFF)
        return group

    def get_dynamic_inequality(self, counter):
        multiple = Integer(0)
        dot = TexMobject("\\cdot")
        theta_tex = TexMobject("({:.2f})".format(self.theta))
        eq = TexMobject("=")
        value = DecimalNumber(0)
        ineq = TexMobject("<")
        pi = TexMobject("\\pi", "=", "3.1415926\\dots")
        # pi.set_color(BLUE)
        group = VGroup(
            multiple, dot, theta_tex,
            eq, value,
            ineq, pi
        )
        group.arrange(RIGHT, buff=0.2)
        group.next_to(ORIGIN, DOWN, buff=LARGE_BUFF)
        theta_brace = Brace(group[2], DOWN, buff=SMALL_BUFF)
        theta_symbol = theta_brace.get_tex("\\theta")
        group.add(theta_brace, theta_symbol)
        # group.align_to(self.pi_symbol, RIGHT)

        def get_count():
            return int(counter.get_value())

        def get_product():
            return get_count() * self.theta

        def is_greater_than_pi():
            return get_product() > PI

        def get_color():
            return RED if is_greater_than_pi() else YELLOW

        def get_ineq():
            result = TexMobject(
                ">" if is_greater_than_pi() else "<"
            )
            result.set_color(get_color())
            result.move_to(ineq)
            return result
        dynamic_ineq = always_redraw(get_ineq)
        group.remove(ineq)
        group.add(dynamic_ineq)

        multiple.add_updater(lambda m: m.set_value(get_count()))
        multiple.add_updater(lambda m: m.next_to(dot, LEFT, 0.2))
        multiple.add_updater(lambda m: m.set_color(get_color()))
        value.add_updater(lambda m: m.set_value(get_product()))

        return group


class AskAboutAddingThetaToItselfThetaPoint1(AskAboutAddingThetaToItself):
    CONFIG = {
        "theta": 0.1,
        "wait_time": 0.1,
        "theta_symbol_scale_val": 0.25,
        "number_height": 0.15,
    }


class AskAboutAddingThetaToItselfThetaPoint2(AskAboutAddingThetaToItself):
    CONFIG = {
        "theta": 0.2,
        "wait_time": 0.1,
    }


class FinalFormula(Scene):
    def construct(self):
        text = TextMobject("Final answer: ")
        t2c_map = {
            "\\theta": BLUE,
            "m_1": GREEN,
            "m_2": RED,
        }

        formula = TexMobject(
            "\\left\\lfloor",
            "{\\pi", "\\over", "\\theta}",
            "\\right\\rfloor"
        )
        formula.set_color_by_tex_to_color_map(t2c_map)
        group = VGroup(text, formula)
        group.arrange(RIGHT)
        group.scale(1.5)
        group.to_edge(UP)

        self.play(Write(text))
        self.play(FadeInFrom(formula))
        self.play(ShowCreationThenFadeAround(formula))
        self.wait()

        theta_eq = TexMobject(
            "\\theta", "=", "\\arctan", "\\left(",
            "\\sqrt",
            "{{m_2", "\\over", "m_1}}",
            "\\right)"
        )
        theta_eq.set_color_by_tex_to_color_map(t2c_map)
        theta_eq.scale(1.5)
        theta_eq.next_to(group, DOWN, MED_LARGE_BUFF)

        self.play(TransformFromCopy(
            formula.get_part_by_tex("\\theta"),
            theta_eq.get_part_by_tex("\\theta"),
        ))
        self.play(Write(theta_eq[1:]))
        self.wait()


class ReviewWrapper(WrapperScene):
    CONFIG = {"title": "To review:"}


class SurprisedRandy(Scene):
    def construct(self):
        randy = Randolph()
        self.play(randy.change, "surprised", 3 * UR)
        self.play(Blink(randy))
        self.play(randy.change, "confused")
        self.play(Blink(randy))
        self.wait()


class TwoSolutionsWrapper(WrapperScene):
    def construct(self):
        big_rect = self.get_big_rect()
        screen_rects = VGroup(*[
            self.get_screen_rect(height=3)
            for x in range(2)
        ])
        screen_rects.arrange(RIGHT, buff=LARGE_BUFF)
        title = TextMobject("Two solutions")
        title.scale(1.5)
        title.to_edge(UP)
        screen_rects.next_to(title, DOWN, LARGE_BUFF)

        # pi creatures
        pis = VGroup(
            Randolph(color=BLUE_D),
            Randolph(color=BLUE_E),
            Randolph(color=BLUE_B),
            Mortimer().scale(1.2)
        )
        pis.set_height(2)
        pis.arrange(RIGHT, buff=MED_LARGE_BUFF)
        pis.to_edge(DOWN, buff=SMALL_BUFF)

        self.add(big_rect, title, pis)
        self.play(
            LaggedStartMap(
                ShowCreation, screen_rects.copy().set_fill(opacity=0),
                lag_ratio=0.8
            ),
            LaggedStartMap(
                FadeIn, screen_rects,
                lag_ratio=0.8
            ),
            LaggedStartMap(
                ApplyMethod, pis,
                lambda pi: (pi.change, "pondering", screen_rects[0])
            ),
        )
        self.play(Blink(random.choice(pis)))
        self.play(LaggedStartMap(
            ApplyMethod, pis,
            lambda pi: (pi.change, "thinking", screen_rects[1])
        ))
        self.play(Blink(random.choice(pis)))
        self.wait()


class FinalQuote(Scene):
    def construct(self):
        quote_text = """
            A change of perspective\\\\
            is worth 80 IQ points.
        """
        quote_parts = [s for s in quote_text.split(" ") if s]
        quote = TextMobject(
            *quote_parts,
        )
        quote.scale(1.2)
        quote.shift(2 * RIGHT + UP)

        image = ImageMobject("AlanKay")
        image.set_height(6)
        image.to_corner(UL)
        image.shift(2 * LEFT + 0.5 * UP)
        name = TextMobject("Alan Kay")
        name.scale(1.5)
        name.next_to(image, DOWN)
        name.shift_onto_screen()

        self.play(
            FadeInFromDown(image),
            Write(name),
        )
        self.wait()

        for word in quote:
            self.play(ShowWord(word))
            self.wait(0.005 * len(word)**1.5)
        self.wait()


class EndScreen(PatreonEndScreen):
    CONFIG = {
        "specific_patrons": [
            "1stViewMaths",
            "Adam Kozak",
            "Adrian Robinson",
            "Alexis Olson",
            "Ali Yahya",
            "Andreas Benjamin Brössel",
            "Andrew Busey",
            "Ankalagon",
            "Antonio Juarez",
            "Arjun Chakroborty",
            "Art Ianuzzi",
            "Arthur Zey",
            "Awoo",
            "Bernd Sing",
            "Bob Sanderson",
            "Boris Veselinovich",
            "Brian Staroselsky",
            "Britt Selvitelle",
            "Burt Humburg",
            "Chad Hurst",
            "Charles Southerland",
            "Chris Connett",
            "Christian Kaiser",
            "Clark Gaebel",
            "Cooper Jones",
            "D. Sivakumar",
            "Danger Dai",
            "Dave B",
            "Dave Kester",
            "dave nicponski",
            "David Clark",
            "David Gow",
            "Delton Ding",
            "Devarsh Desai",
            "eaglle",
            "emptymachine",
            "Eric Younge",
            "Eryq Ouithaqueue",
            "Evan Phillips",
            "Federico Lebron",
            "Florian Chudigiewitsch",
            "Giovanni Filippi",
            "Graham",
            "Hal Hildebrand",
            "Hitoshi Yamauchi",
            "J",
            "j eduardo perez",
            "Jacob Magnuson",
            "Jameel Syed",
            "James Hughes",
            "Jan Pijpers",
            "Jason Hise",
            "Jeff Linse",
            "Jeff Straathof",
            "John Griffith",
            "John Haley",
            "John Shaughnessy",
            "John V Wertheim",
            "Jonathan Eppele",
            "Jonathan Wilson",
            "Jordan Scales",
            "Joseph John Cox",
            "Joseph Kelly",
            "Juan Benet",
            "Kai-Siang Ang",
            "Kanan Gill",
            "Kaustuv DeBiswas",
            "L0j1k",
            "Lee Redden",
            "Linh Tran",
            "Luc Ritchie",
            "Ludwig Schubert",
            "Lukas -krtek.net- Novy",
            "Lukas Biewald",
            "Magister Mugit",
            "Magnus Dahlström",
            "Magnus Lysfjord",
            "Mark B Bahu",
            "Mark Heising",
            "Mathew Bramson",
            "Mathias Jansson",
            "Matt Langford",
            "Matt Roveto",
            "Matt Russell",
            "Matthew Cocke",
            "Mauricio Collares",
            "Michael Faust",
            "Michael Hardel",
            "Mike Coleman",
            "Mustafa Mahdi",
            "Márton Vaitkus",
            "Nathan Jessurun",
            "Nero Li",
            "Omar Zrien",
            "Owen Campbell-Moore",
            "Peter Ehrnstrom",
            "Peter Mcinerney",
            "Quantopian",
            "Randy C. Will",
            "Richard Barthel",
            "Richard Burgmann",
            "Richard Comish",
            "Ripta Pasay",
            "Rish Kundalia",
            "Robert Teed",
            "Roobie",
            "Roy Larson",
            "Ryan Atallah",
            "Ryan Williams",
            "Samuel D. Judge",
            "Scott Gray",
            "Scott Walter, Ph.D.",
            "Sindre Reino Trosterud",
            "soekul",
            "Solara570",
            "Song Gao",
            "Stevie Metke",
            "Ted Suzman",
            "Tihan Seale",
            "Valeriy Skobelev",
            "Vassili Philippov",
            "Xavier Bernard",
            "Yana Chernobilsky",
            "Yaw Etse",
            "YinYangBalance.Asia",
            "Yu Jun",
            "Zach Cardwell",
        ],
    }


class ClacksSolution2Thumbnail(Scene):
    def construct(self):
        self.add_scene1()
        self.add_scene2()

        arrow = Arrow(
            self.block_word.get_top(),
            self.light_dot.get_bottom(),
            tip_length=0.75,
            rectangular_stem_width=0.2,
            color=RED,
            buff=0.5,
        )
        arrow.add_to_back(arrow.copy().set_stroke(BLACK, 20))
        self.add(arrow)
        return

        arrow = TexMobject("\\Updownarrow")
        arrow.set_height(2)
        arrow.set_color(YELLOW)
        arrow.set_stroke(Color("red"), 2, background=True)
        self.add(arrow)

    def add_scene1(self):
        scene1 = Thumbnail(
            sliding_blocks_config={
                "block1_config": {
                    "label_text": "$100^{d}$ kg",
                    "distance": 8,
                },
            }
        )
        group = Group(*scene1.mobjects)
        group.scale(0.75, about_point=ORIGIN)
        group.shift(1.5 * DOWN + 3 * LEFT)
        scene1.remove(scene1.question)
        self.add(*scene1.mobjects)

        black_rect = FullScreenFadeRectangle(fill_opacity=1)
        black_rect.shift(3.5 * UP)
        self.add(black_rect)

        word = TextMobject("Blocks")
        word.set_color(YELLOW)
        word.scale(3)
        word.to_corner(DR, buff=LARGE_BUFF)
        word.shift(0.5 * LEFT)
        self.block_word = word
        self.add(word)

    def add_scene2(self):
        scene2 = ReflectWorldThroughMirrorNew(
            skip_animations=True,
            file_writer_config={
                "write_to_movie": False,
            },
            end_at_animation_number=18,
            # center=1.5 * DOWN,
            center=ORIGIN,
        )
        worlds = VGroup(scene2.world, *scene2.reflected_worlds)
        mirrors = VGroup(*[rw[1] for rw in worlds])
        mirrors.set_stroke(width=5)
        triangles = VGroup(*[rw[0] for rw in worlds])
        trajectories = VGroup(
            scene2.trajectory,
            *scene2.reflected_trajectories
        )
        trajectories.set_stroke(YELLOW, 1)

        beams1, beams2 = [
            scene2.get_shooting_beam_anims(
                path,
                max_stroke_width=20,
                max_time_width=1,
                num_flashes=50,
            )
            for path in [
                scene2.trajectory,
                scene2.ghost_trajectory,
            ]
        ]
        beams = beams1 + beams2
        beams = beams2
        flashes = VGroup()
        for beam in beams:
            beam.update(0.5)
            flashes.add(beam.mobject)

        dot = self.light_dot = Dot(color=YELLOW, radius=0.1)
        dot.move_to(flashes[0].get_left())
        flashes.add(dot)

        self.add(triangles, mirrors)
        # self.add(randys)
        self.add(trajectories[0].set_stroke(width=2))
        self.add(flashes)

        word = TextMobject("Light beam")
        word.scale(3.5)
        word.set_color(YELLOW)
        # word.set_stroke(BLACK, 25, background=True)
        word.add_to_back(word.copy().set_stroke(
            BLACK, 25,
        ))
        word.next_to(dot, UR)
        word.shift(-word.get_center()[0] * RIGHT)
        word.shift(SMALL_BUFF * RIGHT)
        self.light_word = word
        self.add(word)
