from manim import *

config.background_color = (33, 33, 33)
INPUT = "PFISAWESOME" # Manim does not like spaces unfortunately

class StringReversal(Scene):
    def construct(self):
        # Big string 

        self.string = Text(INPUT, font_size=64, font="Agave Nerd Font Mono")
        
        # Intro animation
        self.play(Write(self.string))
        self.bottom = Text(f"reverse({self.string.text}, start=0, end={len(self.string)-1})", font_size=24, font="Agave Nerd Font Mono")
        self.bottom.to_edge(DOWN).to_edge(LEFT)
        self.play(Write(self.bottom))

        # Call the recursive function
        result = self.reverse(INPUT, 0, len(INPUT) - 1)
        
        # Outro animation
        self.play(Unwrite(self.bottom))
        self.play(FadeToColor(self.string, GREEN))
        self.wait(4)
        self.play(Unwrite(self.string))
        self.wait(1)
    

    def bottom_text(self, text):
        # Update the bottom text
        self.play(
            Transform(
                self.bottom,
                Text(
                    text,
                    font_size=24, 
                    font="Agave Nerd Font Mono"
                ).to_edge(DOWN).to_edge(LEFT)
            )
        )
        self.wait(1)

    # Visual swap
    def swap_chars(self, counter):
        # Indicate the characters we're about to swap
        self.play(
            Indicate(self.string[counter]),
            Indicate(self.string[len(self.string) - counter - 1])
        )    
        
        self.wait(.5)
        # Swap the characters
        self.play(
            Swap(
                self.string[counter],
                self.string[len(self.string) - counter - 1]
            )
        )

        self.wait(1)
    
    
    def reverse(self, string, start, end, counter=0):
        # Color the characters that we're about to swap in bottom text
        self.bottom_text(f"reverse({string}, start={start}, end={end})")

        # Base case: If we've reached the middle of the string
        if start >= end:
            self.play(FadeToColor(self.bottom, GREEN))
            self.play(Unwrite(self.bottom))
            
            # There must be a way to set defaults for text
            success = Text(
                "We reached the base case!",
                font_size=24,
                font="Agave Nerd Font Mono"
            ).to_edge(DOWN).to_edge(LEFT)

            self.play(Write(success))
            self.wait(1)
            self.play(Unwrite(success))
            return string
        
        # Swap first and last chars of string
        string = list(string)
        string[start], string[end] = string[end], string[start]
        string = "".join(string)
        

        self.swap_chars(counter)
        counter += 1
        # Recursively call reverse on the substring
        self.reverse(string, start + 1, end - 1, counter)


    