"""
Comprehensive ManimGL API Documentation

This module contains detailed documentation for all ManimGL classes,
extracted from the ManimGL source code to help AI models understand
and generate correct animation code.
"""

MANIM_FULL_DOCS = """
# ManimGL Complete API Reference

This documentation covers all major classes and functions available in ManimGL,
the mathematical animation library used by 3Blue1Brown.

---

## Table of Contents
1. [Scene Classes](#scene-classes)
2. [Mobjects (Mathematical Objects)](#mobjects)
3. [Geometry](#geometry)
4. [Text and LaTeX](#text-and-latex)
5. [Coordinate Systems](#coordinate-systems)
6. [3D Objects](#3d-objects)
7. [Animations](#animations)
8. [Colors and Constants](#colors-and-constants)
9. [Updaters and Trackers](#updaters-and-trackers)
10. [Interactive Features](#interactive-features)

---

## Scene Classes

### Scene (Base Class)
The fundamental canvas for animations. All scenes inherit from this.

```python
from manimlib import *

class MyScene(Scene):
    def construct(self):
        # Your animation code here
        pass
```

**Key Methods:**
| Method | Description |
|--------|-------------|
| `self.play(*animations, run_time=1)` | Play one or more animations |
| `self.wait(duration=1)` | Pause for duration seconds |
| `self.add(*mobjects)` | Add mobjects to scene (no animation) |
| `self.remove(*mobjects)` | Remove mobjects from scene |
| `self.clear()` | Remove all mobjects |
| `self.bring_to_front(*mobjects)` | Move mobjects to front |
| `self.bring_to_back(*mobjects)` | Move mobjects to back |
| `self.get_time()` | Get current scene time |

**Properties:**
- `self.mobjects` - List of all mobjects in scene
- `self.camera` - Camera object
- `self.frame` - Camera frame (for zooming/panning)

### InteractiveScene
Extends Scene with selection, dragging, and live coding capabilities.

```python
class MyInteractiveScene(InteractiveScene):
    def construct(self):
        circle = Circle()
        self.add(circle)
        # Now you can interact with the circle using mouse/keyboard
        self.embed()  # Drop into IPython shell
```

**Additional Features:**
- Click to select mobjects
- Drag to move selected mobjects
- Keyboard shortcuts for common operations

### ThreeDScene
For 3D animations with camera positioning.

```python
class My3DScene(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=75*DEGREES, theta=30*DEGREES)
        axes = ThreeDAxes()
        sphere = Sphere(radius=1)
        self.play(ShowCreation(axes), FadeIn(sphere))
        self.begin_ambient_camera_rotation(rate=0.2)
        self.wait(5)
```

**Camera Methods:**
| Method | Description |
|--------|-------------|
| `self.set_camera_orientation(phi, theta, gamma)` | Set camera angles |
| `self.begin_ambient_camera_rotation(rate)` | Start continuous rotation |
| `self.stop_ambient_camera_rotation()` | Stop rotation |
| `self.move_camera(phi, theta, run_time)` | Animate camera movement |

---

## Mobjects

### Base Mobject Methods
All mobjects share these methods:

**Positioning:**
```python
mob.move_to(point)           # Move center to point
mob.shift(vector)            # Shift by vector (e.g., RIGHT * 2)
mob.to_edge(direction)       # Move to edge (UP, DOWN, LEFT, RIGHT)
mob.to_corner(corner)        # Move to corner (UL, UR, DL, DR)
mob.next_to(other, direction, buff=0.25)  # Position relative to another mobject
mob.align_to(other, direction)  # Align edge with another mobject
mob.center()                 # Move to origin
```

**Transformations:**
```python
mob.scale(factor)            # Scale uniformly
mob.scale(factor, about_point=ORIGIN)  # Scale about a point
mob.stretch(factor, dim)     # Stretch along dimension (0=x, 1=y, 2=z)
mob.rotate(angle)            # Rotate counterclockwise
mob.rotate(angle, axis=OUT)  # Rotate about axis
mob.flip(axis=UP)            # Flip about axis
```

**Styling:**
```python
mob.set_color(color)         # Set overall color
mob.set_fill(color, opacity=1)    # Set fill color and opacity
mob.set_stroke(color, width=4)    # Set stroke color and width
mob.set_opacity(opacity)     # Set overall opacity
mob.fade(darkness)           # Fade (0=normal, 1=invisible)
```

**Information:**
```python
mob.get_center()             # Get center point
mob.get_top(), mob.get_bottom()   # Get edge points
mob.get_left(), mob.get_right()
mob.get_width(), mob.get_height()
mob.get_start(), mob.get_end()    # For lines/paths
```

**Grouping:**
```python
VGroup(mob1, mob2, mob3)     # Group vector mobjects
Group(mob1, mob2, mob3)      # Group any mobjects
mob.copy()                   # Create a copy
```

---

## Geometry

### Basic Shapes

**Circle**
```python
Circle(radius=1, color=BLUE)
Circle(arc_center=ORIGIN)
circle.surround(other_mob)   # Circle around another mobject
```

**Dot**
```python
Dot(point=ORIGIN, radius=0.08, color=WHITE)
SmallDot(point=ORIGIN)       # Smaller dot
```

**Ellipse**
```python
Ellipse(width=2, height=1, color=BLUE)
```

**Arc**
```python
Arc(start_angle=0, angle=TAU/4, radius=1)  # Quarter circle
ArcBetweenPoints(start, end, angle=TAU/4)
```

**Line**
```python
Line(start=LEFT, end=RIGHT, color=WHITE)
DashedLine(start, end, dash_length=0.1)
```

**Arrow**
```python
Arrow(start=LEFT, end=RIGHT)
Arrow(start, end, buff=0.25)  # Buffer from endpoints
Vector(direction)             # Arrow from origin
DoubleArrow(start, end)       # Arrows on both ends
CurvedArrow(start, end, angle=TAU/4)
```

**Polygons**
```python
Polygon(point1, point2, point3)  # Any polygon from points
Triangle()
Square(side_length=2)
Rectangle(width=4, height=2)
RoundedRectangle(width=4, height=2, corner_radius=0.5)
RegularPolygon(n=6)           # Hexagon
```

**Annulus and Sectors**
```python
Annulus(inner_radius=1, outer_radius=2)
Sector(outer_radius=1, inner_radius=0, angle=TAU/4)
AnnularSector(inner_radius=1, outer_radius=2, angle=TAU/4)
```

---

## Text and LaTeX

### Text
```python
Text("Hello World")
Text("Hello", font_size=72)
Text("Hello", font="Arial")
Text("Hello", slant=ITALIC, weight=BOLD)
Text("Hello", color=BLUE)
Text("Hello", t2c={"Hello": RED})  # Color specific text
```

### Tex (LaTeX Math)
```python
Tex(r"E = mc^2")
Tex(r"\\int_0^\\infty e^{-x} dx")
Tex(r"\\frac{d}{dx} f(x)")
Tex(r"\\sqrt{x^2 + y^2}")
Tex(r"\\sum_{n=1}^{\\infty} \\frac{1}{n^2}")
```

### TexText (LaTeX with Text Mode)
```python
TexText("The equation is:")
TexText(r"This is \\textbf{bold}")
```

### Multiple Equations
```python
equations = VGroup(
    Tex(r"a^2 + b^2 = c^2"),
    Tex(r"E = mc^2"),
).arrange(DOWN)
```

### Title and Lists
```python
Title("My Animation", scale_factor=1.0, include_underline=True)
BulletedList("First", "Second", "Third")
```

### Special Symbols
```python
Brace(mobject, direction=DOWN)
BraceText(mobject, "label", direction=DOWN)
```

---

## Coordinate Systems

### Axes
```python
axes = Axes(
    x_range=[-5, 5, 1],      # [min, max, step]
    y_range=[-3, 3, 1],
    width=10,
    height=6,
)
axes.add_coordinate_labels()  # Add number labels

# Create a graph
graph = axes.get_graph(lambda x: x**2)
graph = axes.get_graph(lambda x: np.sin(x), color=BLUE)

# Graph label
label = axes.get_graph_label(graph, r"f(x) = x^2")

# Point on graph
dot = Dot(axes.i2gp(2, graph))  # Point at x=2

# Vertical line to graph
line = axes.get_v_line_to_graph(2, graph)
```

### NumberPlane
```python
plane = NumberPlane(
    x_range=[-5, 5],
    y_range=[-5, 5],
    background_line_style={"stroke_opacity": 0.5}
)
```

### ComplexPlane
```python
plane = ComplexPlane()
# Plot complex number
dot = Dot(plane.n2p(2 + 3j))  # 2 + 3i
```

### NumberLine
```python
number_line = NumberLine(
    x_range=[-5, 5, 1],
    length=10,
    include_numbers=True,
    include_tip=True,
)
# Point on line
dot = Dot(number_line.n2p(3))  # Point at 3
```

### ThreeDAxes
```python
axes = ThreeDAxes(
    x_range=[-5, 5],
    y_range=[-5, 5],
    z_range=[-3, 3],
)
```

---

## 3D Objects

### Basic 3D Shapes
```python
Sphere(radius=1, resolution=(24, 48))
Cube(side_length=2)
Cylinder(radius=1, height=2)
Cone(radius=1, height=2)
Torus(r1=1, r2=0.5)  # r1=major radius, r2=minor radius
Prism(dimensions=[1, 2, 3])
```

### 3D Surfaces
```python
# Parametric surface
surface = ParametricSurface(
    lambda u, v: np.array([u, v, u**2 + v**2]),
    u_range=[-2, 2],
    v_range=[-2, 2],
)

# Function surface
surface = Surface(
    lambda u, v: np.array([u, v, np.sin(u) * np.cos(v)]),
    u_range=[-PI, PI],
    v_range=[-PI, PI],
)
```

### 3D Lines and Arrows
```python
Line3D(start=ORIGIN, end=[1, 2, 3])
Arrow3D(start=ORIGIN, end=[1, 1, 1])
```

### VGroup3D
```python
group = VGroup3D(obj1, obj2, obj3)
```

---

## Animations

### Creation Animations
```python
ShowCreation(mobject)        # Draw the mobject
ShowCreation(mobject, run_time=2)
Write(mobject)               # Write text/latex
DrawBorderThenFill(mobject)  # Draw border, then fill
Uncreate(mobject)            # Reverse of ShowCreation
```

### Fading Animations
```python
FadeIn(mobject)
FadeIn(mobject, shift=UP)    # Fade in while shifting
FadeOut(mobject)
FadeOut(mobject, shift=DOWN)
FadeTransform(mob1, mob2)    # Fade one to another
```

### Transform Animations
```python
Transform(source, target)    # Morph source into target
ReplacementTransform(source, target)  # Replace source with target
TransformMatchingShapes(source, target)  # Smart shape matching
TransformMatchingStrings(tex1, tex2)  # Match LaTeX strings
MoveToTarget(mobject)        # Move to mobject.target
```

### Movement Animations
```python
# Using .animate syntax (recommended)
self.play(mob.animate.shift(RIGHT * 2))
self.play(mob.animate.move_to(ORIGIN))
self.play(mob.animate.scale(2))
self.play(mob.animate.rotate(PI/2))
self.play(mob.animate.set_color(RED))

# Multiple in one
self.play(
    mob.animate.shift(UP).scale(0.5).set_color(BLUE)
)

# Classic animations
self.play(MoveAlongPath(mob, path))
self.play(Rotate(mob, PI))
self.play(Rotating(mob, about_point=ORIGIN))
```

### Indication Animations
```python
Indicate(mobject)            # Flash highlight
Flash(point)                 # Flash at point
CircleIndicate(mobject)      # Circle around
ShowPassingFlash(mobject)    # Flash along path
FlashAround(mobject)         # Flash around perimeter
WiggleOutThenIn(mobject)     # Wiggle
ApplyWave(mobject)           # Wave effect
```

### Growing Animations
```python
GrowFromCenter(mobject)
GrowFromEdge(mobject, edge=DOWN)
GrowFromPoint(mobject, point=ORIGIN)
GrowArrow(arrow)
```

### Composition
```python
# Play simultaneously
self.play(anim1, anim2, anim3)

# Play in sequence
self.play(Succession(anim1, anim2, anim3))

# Lag start
self.play(LaggedStart(anim1, anim2, anim3, lag_ratio=0.5))

# Animation group
self.play(AnimationGroup(anim1, anim2, lag_ratio=0.2))
```

### Animation Parameters
```python
self.play(
    ShowCreation(mob),
    run_time=2,              # Duration in seconds
    rate_func=smooth,        # Easing function
)
```

**Rate Functions:**
- `linear` - Constant speed
- `smooth` - Smooth start and end (default)
- `rush_into` - Fast start, slow end
- `rush_from` - Slow start, fast end
- `there_and_back` - Go there and back
- `double_smooth` - Extra smooth
- `exponential_decay` - Decay curve

---

## Colors and Constants

### Colors
```python
# Primary colors
RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, PINK, TEAL, GOLD, MAROON

# Shades (E=darkest, A=lightest)
BLUE_E, BLUE_D, BLUE_C, BLUE_B, BLUE_A
RED_E, RED_D, RED_C, RED_B, RED_A
GREEN_E, GREEN_D, GREEN_C, GREEN_B, GREEN_A
# ... same for YELLOW, GOLD, TEAL, PURPLE, MAROON

# Neutrals
WHITE, BLACK
GREY_E, GREY_D, GREY_C, GREY_B, GREY_A

# Special
GREY_BROWN, DARK_BROWN, LIGHT_BROWN
LIGHT_PINK
```

### Direction Constants
```python
# Cardinal directions
UP, DOWN, LEFT, RIGHT
IN, OUT  # Z-axis

# Diagonals
UL, UR, DL, DR  # Upper-left, Upper-right, etc.

# Frame edges
TOP, BOTTOM, LEFT_SIDE, RIGHT_SIDE

# Axes
X_AXIS, Y_AXIS, Z_AXIS
ORIGIN
```

### Angle Constants
```python
PI          # 3.14159...
TAU         # 2 * PI
DEGREES     # PI / 180
DEG         # Same as DEGREES

# Usage
45 * DEGREES
PI / 4
```

### Size Constants
```python
SMALL_BUFF      # 0.1
MED_SMALL_BUFF  # 0.25
MED_LARGE_BUFF  # 0.5
LARGE_BUFF      # 1.0

FRAME_WIDTH     # Default ~14.2
FRAME_HEIGHT    # Default 8.0
```

---

## Updaters and Trackers

### ValueTracker
For animating numeric values:

```python
tracker = ValueTracker(0)

# Create mobject that follows tracker
dot = Dot()
dot.add_updater(lambda m: m.move_to(
    axes.c2p(tracker.get_value(), 0)
))

# Animate the value
self.play(tracker.animate.set_value(5), run_time=3)
```

### DecimalNumber
For displaying changing numbers:

```python
number = DecimalNumber(0, num_decimal_places=2)
number.add_updater(lambda m: m.set_value(tracker.get_value()))

# Or with Integer
counter = Integer(0)
counter.add_updater(lambda m: m.set_value(int(tracker.get_value())))
```

### Custom Updaters
```python
# Always updater (runs every frame)
def update_func(mobject, dt):
    mobject.rotate(0.1 * dt)
mob.add_updater(update_func)

# Remove updater
mob.remove_updater(update_func)
mob.clear_updaters()

# Suspend updaters temporarily
mob.suspend_updating()
mob.resume_updating()
```

### follow_path Updater
```python
path = Circle()
dot = Dot()
dot.add_updater(lambda m, dt: m.shift(0.1 * dt * RIGHT))
```

---

## Interactive Features

### Interactive Session Commands
In an interactive session (IPython shell):

```python
# Add/remove objects
add(mobject)
remove(mobject)
clear()

# Animations
play(animation)
wait(duration)

# Access scene
self.mobjects          # All mobjects
self.camera            # Camera
self.frame             # Frame (for zoom/pan)

# Reload code
reload()               # Reload scene module

# Embed IPython
self.embed()           # Drop into shell mid-animation
```

### Mouse/Keyboard in InteractiveScene
```python
class MyInteractive(InteractiveScene):
    def construct(self):
        # Objects are selectable by default
        circle = Circle()
        self.add(circle)

        # Make something not selectable
        bg = FullScreenRectangle()
        bg.fix_in_frame()  # Won't be selected

        self.embed()  # Interact with mouse/keyboard
```

### Camera Frame Manipulation
```python
# Zoom
self.frame.set_height(4)  # Zoom in
self.frame.set_height(16)  # Zoom out

# Pan
self.frame.move_to(RIGHT * 3)

# Animate
self.play(self.frame.animate.set_height(4).move_to(UP * 2))
```

---

## Complete Example

```python
from manimlib import *

class CompleteExample(Scene):
    def construct(self):
        # Title
        title = Text("Mathematical Animation", font_size=60)
        title.to_edge(UP)
        self.play(Write(title))

        # Create axes
        axes = Axes(x_range=[-3, 3], y_range=[-2, 2], width=8, height=5)
        axes.add_coordinate_labels()
        self.play(ShowCreation(axes))

        # Create and animate a graph
        graph = axes.get_graph(lambda x: np.sin(x), color=BLUE)
        graph_label = axes.get_graph_label(graph, r"\\sin(x)")
        self.play(ShowCreation(graph), Write(graph_label))

        # Animate a dot along the graph
        tracker = ValueTracker(-3)
        dot = Dot(color=RED)
        dot.add_updater(lambda m: m.move_to(
            axes.i2gp(tracker.get_value(), graph)
        ))
        self.add(dot)
        self.play(tracker.animate.set_value(3), run_time=4)

        # Transform to cosine
        new_graph = axes.get_graph(lambda x: np.cos(x), color=GREEN)
        new_label = axes.get_graph_label(new_graph, r"\\cos(x)")
        self.play(
            Transform(graph, new_graph),
            Transform(graph_label, new_label),
        )

        self.wait(2)
```

---

## Tips and Best Practices

1. **Use VGroup for organization:**
   ```python
   group = VGroup(obj1, obj2, obj3)
   group.arrange(DOWN, buff=0.5)
   ```

2. **Chain animations with .animate:**
   ```python
   self.play(mob.animate.shift(UP).scale(2).set_color(RED))
   ```

3. **Use run_time for pacing:**
   ```python
   self.play(Transform(a, b), run_time=2)
   ```

4. **Position relative to frame:**
   ```python
   mob.to_edge(UP)
   mob.to_corner(UR)
   ```

5. **Copy mobjects before transforming:**
   ```python
   original = Circle()
   copy = original.copy()
   self.play(Transform(original, Square()))
   # copy still exists as Circle
   ```

6. **Use updaters for dynamic relationships:**
   ```python
   label.add_updater(lambda m: m.next_to(moving_obj, UP))
   ```

---

This reference covers the most commonly used features. For the complete API,
consult the ManimGL source code or use Python's help() function:

```python
from manimlib import *
help(Circle)
help(Transform)
```
"""

# Individual topic help strings
HELP_TOPICS = {
    "scene": """
# Scene Classes

## Scene (Base)
The fundamental animation canvas.

```python
class MyScene(Scene):
    def construct(self):
        circle = Circle()
        self.play(ShowCreation(circle))
        self.wait()
```

**Methods:**
- `self.play(*animations, run_time=1)` - Play animations
- `self.wait(duration=1)` - Wait
- `self.add(*mobjects)` - Add without animation
- `self.remove(*mobjects)` - Remove without animation
- `self.clear()` - Clear all
- `self.bring_to_front(*mobjects)` - Bring to front
- `self.bring_to_back(*mobjects)` - Send to back

**Properties:**
- `self.mobjects` - All mobjects in scene
- `self.camera` - Camera object
- `self.frame` - Camera frame

## ThreeDScene
For 3D animations.

```python
class My3D(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(phi=75*DEGREES, theta=30*DEGREES)
        self.begin_ambient_camera_rotation(rate=0.2)
```

## InteractiveScene
For mouse/keyboard interaction.

```python
class MyInteractive(InteractiveScene):
    def construct(self):
        self.add(Circle())
        self.embed()  # Drop into IPython
```
""",
    "mobjects": """
# Mobjects (Mathematical Objects)

## Positioning
```python
mob.move_to(point)              # Move center
mob.shift(direction)            # Shift by vector
mob.to_edge(UP)                 # To edge
mob.to_corner(UL)               # To corner
mob.next_to(other, DOWN)        # Relative position
mob.center()                    # To origin
```

## Transformations
```python
mob.scale(2)                    # Scale
mob.rotate(PI/4)                # Rotate
mob.flip(axis=UP)               # Mirror
mob.stretch(2, dim=0)           # Stretch in x
```

## Styling
```python
mob.set_color(BLUE)
mob.set_fill(RED, opacity=0.5)
mob.set_stroke(WHITE, width=4)
mob.set_opacity(0.5)
```

## Getters
```python
mob.get_center()
mob.get_width(), mob.get_height()
mob.get_top(), mob.get_bottom()
mob.get_left(), mob.get_right()
```

## Groups
```python
VGroup(mob1, mob2, mob3)
group.arrange(DOWN, buff=0.5)
group.arrange_in_grid(rows=2, cols=3)
```
""",
    "animations": """
# Animations

## Creation
```python
ShowCreation(mob)     # Draw
Write(mob)            # Write text
FadeIn(mob)           # Fade in
FadeIn(mob, shift=UP) # Fade with shift
Uncreate(mob)         # Reverse draw
```

## Transform
```python
Transform(a, b)                    # Morph a to b
ReplacementTransform(a, b)         # Replace a with b
TransformMatchingShapes(a, b)      # Smart matching
MoveToTarget(mob)                  # Move to mob.target
```

## Movement (using .animate)
```python
self.play(mob.animate.shift(RIGHT))
self.play(mob.animate.move_to(ORIGIN))
self.play(mob.animate.scale(2))
self.play(mob.animate.rotate(PI/2))
self.play(mob.animate.set_color(RED))
```

## Indication
```python
Indicate(mob)         # Highlight
Flash(point)          # Flash
CircleIndicate(mob)   # Circle around
WiggleOutThenIn(mob)  # Wiggle
```

## Composition
```python
AnimationGroup(a1, a2, lag_ratio=0.5)
Succession(a1, a2, a3)
LaggedStart(a1, a2, a3)
```

## Parameters
```python
self.play(anim, run_time=2, rate_func=smooth)
```

Rate functions: linear, smooth, rush_into, rush_from, there_and_back
""",
    "transforms": """
# Transform Animations

## Basic Transforms
```python
Transform(source, target)
# Morphs source to look like target. Source mobject changes.

ReplacementTransform(source, target)
# Removes source, adds target. Common for equation work.

TransformMatchingShapes(source, target)
# Matches similar shapes automatically.
```

## Text Transforms
```python
TransformMatchingStrings(tex1, tex2)
# Matches LaTeX substrings.

TransformMatchingTex(tex1, tex2)
# For Tex mobjects specifically.
```

## Using .target
```python
mob.generate_target()
mob.target.shift(UP).scale(2)
self.play(MoveToTarget(mob))
```

## Example: Equation Transform
```python
eq1 = Tex(r"a^2 + b^2")
eq2 = Tex(r"c^2")
self.play(Write(eq1))
self.play(TransformMatchingShapes(eq1, eq2))
```
""",
    "text": """
# Text and LaTeX

## Text
```python
Text("Hello World")
Text("Hello", font_size=72)
Text("Hello", font="Arial")
Text("Hello", color=BLUE)
Text("Hello", slant=ITALIC)
Text("Hello", weight=BOLD)
```

## Colored Substrings
```python
Text("Hello World", t2c={"Hello": RED, "World": BLUE})
```

## LaTeX Math
```python
Tex(r"E = mc^2")
Tex(r"\\frac{a}{b}")
Tex(r"\\int_0^1 x^2 dx")
Tex(r"\\sqrt{x}")
Tex(r"\\sum_{i=1}^n i")
```

## LaTeX Text Mode
```python
TexText("Hello")
TexText(r"\\textbf{Bold} and \\textit{italic}")
```

## Multi-line
```python
equations = VGroup(
    Tex(r"a^2 + b^2 = c^2"),
    Tex(r"E = mc^2"),
).arrange(DOWN)
```

## Brace
```python
brace = Brace(mobject, DOWN)
label = brace.get_tex("x")
```
""",
    "graphs": """
# Coordinate Systems and Graphs

## Axes
```python
axes = Axes(
    x_range=[-5, 5, 1],    # [min, max, step]
    y_range=[-3, 3, 1],
    width=10,
    height=6,
)
axes.add_coordinate_labels()
self.play(ShowCreation(axes))
```

## Plotting Functions
```python
# Basic graph
graph = axes.get_graph(lambda x: x**2, color=BLUE)
self.play(ShowCreation(graph))

# With label
label = axes.get_graph_label(graph, r"f(x) = x^2")

# Parametric
graph = axes.get_parametric_curve(
    lambda t: [np.cos(t), np.sin(t)],
    t_range=[0, TAU]
)
```

## Points and Lines
```python
# Point on graph at x=2
point = Dot(axes.i2gp(2, graph))

# Vertical line to graph
v_line = axes.get_v_line_to_graph(2, graph)

# Horizontal line
h_line = axes.get_h_line_to_point(axes.c2p(2, 1))
```

## Area Under Curve
```python
area = axes.get_area(graph, x_range=[0, 2])
```

## NumberPlane (Grid)
```python
plane = NumberPlane()
```

## NumberLine
```python
line = NumberLine(x_range=[-5, 5, 1], include_numbers=True)
dot = Dot(line.n2p(3))  # Point at 3
```
""",
    "3d": """
# 3D Scenes and Objects

## ThreeDScene Setup
```python
class My3D(ThreeDScene):
    def construct(self):
        self.set_camera_orientation(
            phi=75*DEGREES,    # Angle from z-axis
            theta=30*DEGREES   # Rotation around z
        )
```

## Camera Control
```python
self.set_camera_orientation(phi, theta)
self.begin_ambient_camera_rotation(rate=0.2)
self.stop_ambient_camera_rotation()
self.move_camera(phi=60*DEGREES, run_time=2)
```

## 3D Axes
```python
axes = ThreeDAxes(
    x_range=[-5, 5],
    y_range=[-5, 5],
    z_range=[-3, 3],
)
```

## 3D Objects
```python
Sphere(radius=1)
Cube(side_length=2)
Cylinder(radius=1, height=2)
Cone(base_radius=1, height=2)
Torus(r1=1, r2=0.5)
Prism(dimensions=[1, 2, 3])
```

## 3D Surfaces
```python
surface = ParametricSurface(
    lambda u, v: [u, v, np.sin(u) * np.cos(v)],
    u_range=[-PI, PI],
    v_range=[-PI, PI],
)
```

## 3D Lines
```python
Line3D(start=ORIGIN, end=[1, 2, 3])
Arrow3D(start=ORIGIN, end=[1, 1, 1])
```
""",
    "interactive": """
# Interactive Mode

## Starting Interactive Session
Run manimgl without a scene to get a blank interactive scene:
```bash
manimgl
```

Or from within a scene:
```python
self.embed()  # Drops into IPython shell
```

## Available Commands
```python
# Add/remove objects
add(circle)
remove(circle)
clear()

# Animations
play(ShowCreation(circle))
wait(2)

# Scene access
self.mobjects     # All mobjects
self.camera       # Camera
self.frame        # Frame
```

## Creating Objects
```python
circle = Circle(color=BLUE)
add(circle)
play(circle.animate.shift(UP * 2))
```

## Frame Control (Zoom/Pan)
```python
# Zoom
self.frame.set_height(4)   # Zoom in
self.frame.set_height(16)  # Zoom out

# Pan
self.frame.move_to(RIGHT * 3)

# Animate
play(self.frame.animate.set_height(6).move_to(UP))
```

## InteractiveScene Features
Objects are selectable/draggable by default.
- Click to select
- Drag to move
- Keyboard shortcuts available

## Useful Patterns
```python
# Iterate and modify
for mob in self.mobjects:
    play(mob.animate.scale(1.5))

# Save current state
checkpoint_paste()

# Reload scene file
reload()
```
""",
    "colors": """
# Colors

## Basic Colors
RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, PINK, TEAL, GOLD, MAROON

## Shades (E=darkest, A=lightest)
```
BLUE_E  BLUE_D  BLUE_C  BLUE_B  BLUE_A
 dark <----------------> light
```

Same for: RED, GREEN, YELLOW, GOLD, TEAL, PURPLE, MAROON

## Neutrals
WHITE, BLACK, GREY
GREY_E, GREY_D, GREY_C, GREY_B, GREY_A

## Special
GREY_BROWN, DARK_BROWN, LIGHT_BROWN, LIGHT_PINK

## Usage
```python
circle = Circle(color=BLUE)
circle.set_color(RED)
circle.set_fill(YELLOW, opacity=0.5)
circle.set_stroke(GREEN, width=4)
```

## Gradients
```python
mob.set_color_by_gradient(BLUE, GREEN, YELLOW)
```
""",
    "coordinates": """
# Coordinate System

## Frame
- Origin (0, 0, 0) at center
- X increases RIGHT
- Y increases UP
- Z increases OUT (toward viewer)

## Direction Constants
```python
UP, DOWN, LEFT, RIGHT
IN, OUT (Z-axis)
UL, UR, DL, DR (diagonals)
```

## Frame Boundaries
```python
TOP, BOTTOM, LEFT_SIDE, RIGHT_SIDE
FRAME_WIDTH ≈ 14.2
FRAME_HEIGHT = 8.0
```

## Useful Positions
```python
mob.to_edge(UP)           # Top edge
mob.to_corner(UR)         # Upper right
mob.to_edge(LEFT, buff=1) # Left with buffer
```

## Angles
```python
PI = 3.14159...
TAU = 2 * PI
DEGREES = PI / 180
DEG = DEGREES

# Usage
45 * DEGREES
PI / 4
```

## Buffers (spacing)
```python
SMALL_BUFF = 0.1
MED_SMALL_BUFF = 0.25
MED_LARGE_BUFF = 0.5
LARGE_BUFF = 1.0
```
""",
}

# Example code templates
EXAMPLE_TEMPLATES = {
    "basic_shapes": """from manimlib import *

class BasicShapes(Scene):
    def construct(self):
        # Create shapes
        circle = Circle(color=BLUE, radius=1)
        square = Square(color=RED, side_length=1.5)
        triangle = Triangle(color=GREEN)

        # Position them
        shapes = VGroup(circle, square, triangle)
        shapes.arrange(RIGHT, buff=1)

        # Animate
        self.play(ShowCreation(circle))
        self.play(ShowCreation(square))
        self.play(ShowCreation(triangle))
        self.wait()
""",
    "transform_demo": """from manimlib import *

class TransformDemo(Scene):
    def construct(self):
        # Start with circle
        circle = Circle(color=BLUE, fill_opacity=0.5)
        self.play(ShowCreation(circle))
        self.wait()

        # Transform to square
        square = Square(color=RED, fill_opacity=0.5)
        self.play(Transform(circle, square))
        self.wait()

        # Transform to triangle
        triangle = Triangle(color=GREEN, fill_opacity=0.5)
        self.play(Transform(circle, triangle))
        self.wait()
""",
    "text_latex": """from manimlib import *

class TextAndLatex(Scene):
    def construct(self):
        # Simple text
        title = Text("Mathematical Beauty", font_size=60, color=YELLOW)
        title.to_edge(UP)
        self.play(Write(title))

        # LaTeX equation
        equation = Tex(r"e^{i\\pi} + 1 = 0", font_size=72)
        self.play(Write(equation))
        self.wait()

        # Transform equation
        new_eq = Tex(r"e^{i\\theta} = \\cos\\theta + i\\sin\\theta", font_size=48)
        self.play(TransformMatchingShapes(equation, new_eq))
        self.wait()
""",
    "graph_animation": """from manimlib import *
import numpy as np

class GraphAnimation(Scene):
    def construct(self):
        # Create axes
        axes = Axes(
            x_range=[-3, 3, 1],
            y_range=[-2, 2, 1],
            width=10,
            height=6,
        )
        axes.add_coordinate_labels()
        self.play(ShowCreation(axes))

        # Plot sine
        sin_graph = axes.get_graph(np.sin, color=BLUE)
        sin_label = axes.get_graph_label(sin_graph, r"\\sin(x)")
        self.play(ShowCreation(sin_graph), Write(sin_label))

        # Animate dot along curve
        tracker = ValueTracker(-3)
        dot = Dot(color=RED)
        dot.add_updater(lambda m: m.move_to(axes.i2gp(tracker.get_value(), sin_graph)))
        self.add(dot)
        self.play(tracker.animate.set_value(3), run_time=4)
        self.wait()
""",
    "value_tracker": """from manimlib import *

class ValueTrackerDemo(Scene):
    def construct(self):
        # Number line
        line = NumberLine(x_range=[-5, 5, 1], length=10, include_numbers=True)
        self.play(ShowCreation(line))

        # Value tracker
        tracker = ValueTracker(0)

        # Dot follows tracker
        dot = Dot(color=RED, radius=0.15)
        dot.add_updater(lambda m: m.move_to(line.n2p(tracker.get_value())))

        # Label shows value
        label = DecimalNumber(0, num_decimal_places=2, font_size=36)
        label.add_updater(lambda m: m.set_value(tracker.get_value()))
        label.add_updater(lambda m: m.next_to(dot, UP))

        self.add(dot, label)

        # Animate
        self.play(tracker.animate.set_value(4), run_time=2)
        self.play(tracker.animate.set_value(-3), run_time=2)
        self.play(tracker.animate.set_value(0), run_time=1)
        self.wait()
""",
    "3d_demo": """from manimlib import *

class ThreeDDemo(ThreeDScene):
    def construct(self):
        # Set camera
        self.set_camera_orientation(phi=75*DEGREES, theta=30*DEGREES)

        # Create axes
        axes = ThreeDAxes()
        self.play(ShowCreation(axes))

        # Create 3D objects
        sphere = Sphere(radius=1, color=BLUE, opacity=0.7)
        cube = Cube(side_length=1.5, color=RED, opacity=0.7)
        cube.shift(RIGHT * 3)

        self.play(FadeIn(sphere), FadeIn(cube))

        # Rotate camera
        self.begin_ambient_camera_rotation(rate=0.3)
        self.wait(5)
        self.stop_ambient_camera_rotation()
        self.wait()
""",
    "updater_pattern": """from manimlib import *

class UpdaterPattern(Scene):
    def construct(self):
        # Moving circle
        circle = Circle(color=BLUE)
        circle.shift(LEFT * 3)

        # Arrow always points at circle
        arrow = Arrow(ORIGIN, RIGHT)
        arrow.add_updater(lambda m: m.put_start_and_end_on(
            ORIGIN, circle.get_center()
        ))

        # Label always next to circle
        label = Text("Target", font_size=24)
        label.add_updater(lambda m: m.next_to(circle, UP))

        self.add(circle, arrow, label)

        # Animate circle movement
        self.play(circle.animate.shift(RIGHT * 6), run_time=3)
        self.play(circle.animate.shift(UP * 2), run_time=2)
        self.play(circle.animate.move_to(LEFT * 2 + DOWN), run_time=2)
        self.wait()
""",
    "interactive_session": """# Commands for interactive ManimGL session
# Run: manimgl (without arguments)

# Create objects
circle = Circle(color=BLUE)
square = Square(color=RED)
add(circle)

# Animate
play(ShowCreation(circle))
play(circle.animate.shift(UP * 2))
play(circle.animate.scale(1.5).set_color(GREEN))

# Transform
play(Transform(circle, square))

# Multiple animations
play(
    circle.animate.shift(LEFT),
    run_time=2
)

# Frame control (zoom/pan)
self.frame.set_height(4)  # Zoom in
play(self.frame.animate.move_to(RIGHT * 2))

# Clear and start over
clear()
""",
}


def get_full_documentation() -> str:
    """Return the complete ManimGL documentation."""
    return MANIM_FULL_DOCS


def get_topic_help(topic: str) -> str:
    """Get help for a specific topic."""
    topic_lower = topic.lower().strip()

    if topic_lower in HELP_TOPICS:
        return HELP_TOPICS[topic_lower]

    # Try partial matching
    for key, content in HELP_TOPICS.items():
        if topic_lower in key or key in topic_lower:
            return content

    # Return available topics
    topics = ", ".join(sorted(HELP_TOPICS.keys()))
    return f"""Topic '{topic}' not found.

Available topics: {topics}

For comprehensive documentation, use topic 'full' or 'all'.

For specific class help, try in Python:
```python
from manimlib import *
help(Circle)
help(Transform)
```
"""


def get_example_template(name: str) -> str:
    """Get an example code template."""
    name_lower = name.lower().replace("-", "_").replace(" ", "_")

    if name_lower in EXAMPLE_TEMPLATES:
        return EXAMPLE_TEMPLATES[name_lower]

    # Try partial matching
    for key, code in EXAMPLE_TEMPLATES.items():
        if name_lower in key or key in name_lower:
            return code

    # Return available templates
    templates = ", ".join(sorted(EXAMPLE_TEMPLATES.keys()))
    return f"""Example '{name}' not found.

Available examples: {templates}

Use get_example_code with one of these names.
"""
