#!/usr/bin/env python3
"""Animation Chain/Group Demo - Complex animation orchestration

Interactive controls:
    1: Run sequential chain demo
    2: Run parallel group demo
    3: Run callback demo
    4: Run looping demo
    5: Run combined demo
    R: Reset all animations
    ESC: Exit demo
"""
import mcrfpy
import sys

# Add parent to path for imports
sys.path.insert(0, str(__file__).rsplit('/', 2)[0])
from lib.anim_utils import (
    AnimationChain, AnimationGroup, delay, callback,
    fade_in, fade_out, slide_in_from_left, shake
)


class AnimationDemo:
    def __init__(self):
        self.scene = mcrfpy.Scene("animation_demo")
        self.ui = self.scene.children
        self.demo_frames = []
        self.active_animations = []
        self.setup()

    def setup(self):
        """Build the demo scene."""
        # Background
        bg = mcrfpy.Frame(
            pos=(0, 0),
            size=(1024, 768),
            fill_color=mcrfpy.Color(20, 20, 25)
        )
        self.ui.append(bg)

        # Title
        title = mcrfpy.Caption(
            text="Animation Chain/Group Demo",
            pos=(512, 30),
            font_size=28,
            fill_color=mcrfpy.Color(255, 255, 255)
        )
        title.outline = 2
        title.outline_color = mcrfpy.Color(0, 0, 0)
        self.ui.append(title)

        # Create demo areas
        self._create_chain_demo()
        self._create_group_demo()
        self._create_callback_demo()
        self._create_loop_demo()
        self._create_combined_demo()

        # Status display
        self.status = mcrfpy.Caption(
            text="Press 1-5 to run demos, R to reset",
            pos=(50, 700),
            font_size=16,
            fill_color=mcrfpy.Color(100, 200, 100)
        )
        self.ui.append(self.status)

        # Instructions
        instr = mcrfpy.Caption(
            text="1: Chain | 2: Group | 3: Callback | 4: Loop | 5: Combined | R: Reset | ESC: Exit",
            pos=(50, 730),
            font_size=14,
            fill_color=mcrfpy.Color(120, 120, 120)
        )
        self.ui.append(instr)

    def _create_chain_demo(self):
        """Create the sequential chain demo area."""
        # Label
        label = mcrfpy.Caption(
            text="1. Sequential Chain",
            pos=(50, 80),
            font_size=16,
            fill_color=mcrfpy.Color(150, 150, 150)
        )
        self.ui.append(label)

        # Description
        desc = mcrfpy.Caption(
            text="Move right -> wait -> move down -> wait -> move left",
            pos=(50, 100),
            font_size=12,
            fill_color=mcrfpy.Color(100, 100, 100)
        )
        self.ui.append(desc)

        # Animated frame
        self.chain_frame = mcrfpy.Frame(
            pos=(50, 130),
            size=(60, 60),
            fill_color=mcrfpy.Color(100, 150, 200),
            outline_color=mcrfpy.Color(150, 200, 255),
            outline=2
        )
        self.demo_frames.append(('chain', self.chain_frame, (50, 130)))
        self.ui.append(self.chain_frame)

    def _create_group_demo(self):
        """Create the parallel group demo area."""
        # Label
        label = mcrfpy.Caption(
            text="2. Parallel Group",
            pos=(350, 80),
            font_size=16,
            fill_color=mcrfpy.Color(150, 150, 150)
        )
        self.ui.append(label)

        # Description
        desc = mcrfpy.Caption(
            text="Move + resize + change color simultaneously",
            pos=(350, 100),
            font_size=12,
            fill_color=mcrfpy.Color(100, 100, 100)
        )
        self.ui.append(desc)

        # Animated frame
        self.group_frame = mcrfpy.Frame(
            pos=(350, 130),
            size=(60, 60),
            fill_color=mcrfpy.Color(200, 100, 100),
            outline_color=mcrfpy.Color(255, 150, 150),
            outline=2
        )
        self.demo_frames.append(('group', self.group_frame, (350, 130)))
        self.ui.append(self.group_frame)

    def _create_callback_demo(self):
        """Create the callback demo area."""
        # Label
        label = mcrfpy.Caption(
            text="3. Callbacks",
            pos=(650, 80),
            font_size=16,
            fill_color=mcrfpy.Color(150, 150, 150)
        )
        self.ui.append(label)

        # Description
        desc = mcrfpy.Caption(
            text="Each step triggers a callback",
            pos=(650, 100),
            font_size=12,
            fill_color=mcrfpy.Color(100, 100, 100)
        )
        self.ui.append(desc)

        # Animated frame
        self.callback_frame = mcrfpy.Frame(
            pos=(650, 130),
            size=(60, 60),
            fill_color=mcrfpy.Color(100, 200, 100),
            outline_color=mcrfpy.Color(150, 255, 150),
            outline=2
        )
        self.demo_frames.append(('callback', self.callback_frame, (650, 130)))
        self.ui.append(self.callback_frame)

        # Callback counter display
        self.callback_counter = mcrfpy.Caption(
            text="Callbacks: 0",
            pos=(720, 160),
            font_size=12,
            fill_color=mcrfpy.Color(100, 200, 100)
        )
        self.ui.append(self.callback_counter)

    def _create_loop_demo(self):
        """Create the looping demo area."""
        # Label
        label = mcrfpy.Caption(
            text="4. Looping",
            pos=(50, 280),
            font_size=16,
            fill_color=mcrfpy.Color(150, 150, 150)
        )
        self.ui.append(label)

        # Description
        desc = mcrfpy.Caption(
            text="Continuous back-and-forth animation",
            pos=(50, 300),
            font_size=12,
            fill_color=mcrfpy.Color(100, 100, 100)
        )
        self.ui.append(desc)

        # Animated frame
        self.loop_frame = mcrfpy.Frame(
            pos=(50, 330),
            size=(40, 40),
            fill_color=mcrfpy.Color(200, 200, 100),
            outline_color=mcrfpy.Color(255, 255, 150),
            outline=2
        )
        self.demo_frames.append(('loop', self.loop_frame, (50, 330)))
        self.ui.append(self.loop_frame)

        self.loop_chain = None

    def _create_combined_demo(self):
        """Create the combined demo area."""
        # Label
        label = mcrfpy.Caption(
            text="5. Combined (Chain of Groups)",
            pos=(350, 280),
            font_size=16,
            fill_color=mcrfpy.Color(150, 150, 150)
        )
        self.ui.append(label)

        # Description
        desc = mcrfpy.Caption(
            text="Multiple frames animating in complex patterns",
            pos=(350, 300),
            font_size=12,
            fill_color=mcrfpy.Color(100, 100, 100)
        )
        self.ui.append(desc)

        # Multiple animated frames
        self.combined_frames = []
        colors = [
            mcrfpy.Color(200, 100, 150),
            mcrfpy.Color(150, 100, 200),
            mcrfpy.Color(100, 150, 200),
        ]
        for i, color in enumerate(colors):
            frame = mcrfpy.Frame(
                pos=(350 + i * 70, 330),
                size=(50, 50),
                fill_color=color,
                outline=1
            )
            self.combined_frames.append(frame)
            self.demo_frames.append(('combined', frame, (350 + i * 70, 330)))
            self.ui.append(frame)

    def run_chain_demo(self):
        """Run the sequential chain demo."""
        self.status.text = "Running: Sequential Chain"

        chain = AnimationChain(
            (self.chain_frame, "x", 200, 0.5),
            delay(0.3),
            (self.chain_frame, "y", 200, 0.5),
            delay(0.3),
            (self.chain_frame, "x", 50, 0.5),
            callback=lambda: setattr(self.status, 'text', 'Chain complete!')
        )
        chain.start()
        self.active_animations.append(chain)

    def run_group_demo(self):
        """Run the parallel group demo."""
        self.status.text = "Running: Parallel Group"

        group = AnimationGroup(
            (self.group_frame, "x", 500, 1.0),
            (self.group_frame, "w", 100, 1.0),
            (self.group_frame, "h", 100, 1.0),
            callback=lambda: setattr(self.status, 'text', 'Group complete!')
        )
        group.start()
        self.active_animations.append(group)

    def run_callback_demo(self):
        """Run the callback demo."""
        self.status.text = "Running: Callbacks"
        self.callback_count = 0

        def increment_counter():
            self.callback_count += 1
            self.callback_counter.text = f"Callbacks: {self.callback_count}"

        chain = AnimationChain(
            callback(increment_counter),
            (self.callback_frame, "x", 750, 0.3),
            callback(increment_counter),
            delay(0.2),
            callback(increment_counter),
            (self.callback_frame, "y", 200, 0.3),
            callback(increment_counter),
            (self.callback_frame, "x", 650, 0.3),
            callback(increment_counter),
            callback=lambda: setattr(self.status, 'text', f'Callback demo complete! ({self.callback_count} callbacks)')
        )
        chain.start()
        self.active_animations.append(chain)

    def run_loop_demo(self):
        """Run the looping demo."""
        self.status.text = "Running: Looping (press R to stop)"

        # Stop any existing loop
        if self.loop_chain:
            self.loop_chain.stop()

        self.loop_chain = AnimationChain(
            (self.loop_frame, "x", 250, 1.0),
            (self.loop_frame, "x", 50, 1.0),
            loop=True
        )
        self.loop_chain.start()
        self.active_animations.append(self.loop_chain)

    def run_combined_demo(self):
        """Run the combined demo with chain of groups."""
        self.status.text = "Running: Combined"

        # First, all frames slide down together
        # Then, each one bounces back up sequentially
        frame1, frame2, frame3 = self.combined_frames

        chain = AnimationChain(
            # Phase 1: All move down together (as a group effect via separate chains)
            (frame1, "y", 450, 0.5),
            delay(0.1),
            (frame2, "y", 450, 0.5),
            delay(0.1),
            (frame3, "y", 450, 0.5),
            delay(0.5),
            # Phase 2: Spread out horizontally
            (frame1, "x", 320, 0.3),
            (frame3, "x", 520, 0.3),
            delay(0.5),
            # Phase 3: All return home
            (frame1, "x", 350, 0.3),
            (frame1, "y", 330, 0.3),
            delay(0.1),
            (frame2, "y", 330, 0.3),
            delay(0.1),
            (frame3, "x", 490, 0.3),
            (frame3, "y", 330, 0.3),
            callback=lambda: setattr(self.status, 'text', 'Combined demo complete!')
        )
        chain.start()
        self.active_animations.append(chain)

    def reset_all(self):
        """Reset all animations to initial state."""
        # Stop all active animations
        for anim in self.active_animations:
            if hasattr(anim, 'stop'):
                anim.stop()
        self.active_animations.clear()

        if self.loop_chain:
            self.loop_chain.stop()
            self.loop_chain = None

        # Reset positions
        for name, frame, (orig_x, orig_y) in self.demo_frames:
            frame.x = orig_x
            frame.y = orig_y
            if name == 'group':
                frame.w = 60
                frame.h = 60

        # Reset callback counter
        self.callback_count = 0
        self.callback_counter.text = "Callbacks: 0"

        self.status.text = "All animations reset"

    def on_key(self, key, state):
        """Handle keyboard input."""
        if state != mcrfpy.InputState.PRESSED:
            return

        if key == mcrfpy.Key.ESCAPE:
            sys.exit(0)
        elif key == mcrfpy.Key.NUM_1:
            self.run_chain_demo()
        elif key == mcrfpy.Key.NUM_2:
            self.run_group_demo()
        elif key == mcrfpy.Key.NUM_3:
            self.run_callback_demo()
        elif key == mcrfpy.Key.NUM_4:
            self.run_loop_demo()
        elif key == mcrfpy.Key.NUM_5:
            self.run_combined_demo()
        elif key == mcrfpy.Key.R:
            self.reset_all()

    def activate(self):
        """Activate the demo scene."""
        self.scene.on_key = self.on_key
        mcrfpy.current_scene = self.scene


def main():
    """Run the animation demo."""
    demo = AnimationDemo()
    demo.activate()

    # Headless mode: capture screenshot and exit
    try:
        if mcrfpy.headless_mode():
            from mcrfpy import automation
            # Run a quick demo then screenshot
            demo.run_chain_demo()
            mcrfpy.Timer("screenshot", lambda rt: (
                automation.screenshot("screenshots/features/animation_chain_demo.png"),
                sys.exit(0)
            ), 500)
    except AttributeError:
        pass


if __name__ == "__main__":
    main()
