from fluxion import *

class ShapeTransforms(Scene):
    def construct(self):
        # Setup
        self.camera.background_color = "#111111"
        
        # Helper title
        label = Text("Creation Animations", font_size=36).to_edge(UP)
        self.add(label)
        
        # 1. CREATION
        # Create a row of shapes
        s1 = Square(color=BLUE, fill_opacity=0.5)
        s2 = Circle(color=RED, fill_opacity=0.5)
        s3 = Triangle(color=GREEN, fill_opacity=0.5)
        s4 = Star(color=YELLOW, fill_opacity=0.5)
        
        group = VGroup(s1, s2, s3, s4).arrange(RIGHT, buff=1)
        
        self.play(Create(s1))
        self.play(DrawBorderThenFill(s2))
        self.play(GrowFromCenter(s3))
        self.play(FadeIn(s4, shift=UP))
        self.wait(0.5)
        
        # 2. MORPHING
        self.play(
            Transform(label, Text("Morphing", font_size=36).to_edge(UP)),
            FadeOut(group, run_time=0.5)
        )
        
        start_shape = Square(side_length=3, color=BLUE, fill_opacity=0.5)
        self.play(GrowFromCenter(start_shape))
        self.wait(0.5)
        
        # Square -> Circle
        circle = Circle(radius=1.5, color=RED, fill_opacity=0.5)
        self.play(Transform(start_shape, circle))
        self.wait(0.5)
        
        # Circle -> Triangle
        triangle = Triangle(color=GREEN, fill_opacity=0.5).scale(1.5)
        self.play(ReplacementTransform(start_shape, triangle)) # start_shape is now the circle
        self.wait(0.5)
        
        # Triangle -> Star
        star = Star(color=YELLOW, fill_opacity=0.5).scale(1.5)
        self.play(ReplacementTransform(triangle, star))
        self.wait(0.5)
        
        # 3. TRANSITION TYPES
        self.play(
            Transform(label, Text("Transition Types", font_size=36).to_edge(UP)),
            FadeOut(star)
        )
        
        # Setup two squares
        left_sq = Square(color=TEAL, fill_opacity=0.5).shift(LEFT*2)
        right_sq = Square(color=ORANGE, fill_opacity=0.5).shift(RIGHT*2)
        self.add(left_sq, right_sq)
        
        # TransformFromCopy
        # Keeps original, creates new one transforming to target
        target_circle = Circle(color=PURPLE, fill_opacity=0.8)
        self.play(TransformFromCopy(left_sq, target_circle))
        self.play(FadeOut(target_circle))
        
        # ClockwiseTransform
        # Moves target in a curve
        self.play(ClockwiseTransform(left_sq, right_sq.copy().set_color(PINK)))
        self.wait(0.5)
        
        # CounterclockwiseTransform
        self.play(CounterclockwiseTransform(right_sq, left_sq.copy().set_color(CYAN if 'CYAN' in globals() else BLUE)))
        self.wait(0.5)
        
        # 4. REMOVAL
        self.play(
            Transform(label, Text("Removal", font_size=36).to_edge(UP)),
            FadeOut(left_sq), 
            FadeOut(right_sq)
        )
        
        # Create grid to delete
        grid = VGroup(*[Square(side_length=0.5, color=WHITE) for _ in range(9)]).arrange_in_grid(3,3)
        self.play(Create(grid), run_time=1)
        
        # Various removal methods
        self.play(
            ShrinkToCenter(grid[0]),
            FadeOut(grid[1]),
            Uncreate(grid[2]),
            run_time=1.5
        )
        self.play(
            Unwrite(grid[3]), # Usually for Text but works on VMobjects
            grid[4].animate.scale(0),
            FadeOut(grid[5], shift=DOWN),
            run_time=1.5
        )
        self.play(FadeOut(grid[6:]))
        
        # 5. COMPLEX PATHS & STYLE
        self.play(
            Transform(label, Text("Complex Paths & Style", font_size=36).to_edge(UP))
        )
        
        path = Line(LEFT*3, RIGHT*3).set_stroke(opacity=0.2)
        dot = Dot(color=YELLOW).move_to(path.get_start())
        self.add(path, dot)
        
        # MoveAlongPath
        curve = ArcBetweenPoints(LEFT*3, RIGHT*3, angle=PI/2)
        self.play(MoveAlongPath(dot, curve), run_time=2)
        
        # Style change while moving
        self.play(
            dot.animate.scale(5).set_color(RED),
            Rotate(dot, PI),
            run_time=1
        )
        
        self.play(FadeOut(dot), FadeOut(path), FadeOut(label))
        
        # Final
        end = Text("Fluxion Engine", font_size=48)
        self.play(Write(end))
        self.wait(1)
        self.play(FadeOut(end))
