#!/usr/bin/env python3
"""Click to Pick Up Demo - Toggle-based inventory interaction

Interactive controls:
    Left click on item: Pick up item (cursor changes)
    Left click on empty cell: Place item
    Right click: Cancel pickup
    ESC: Return to menu

This demonstrates:
    - Click-to-toggle pickup mode (not hold-to-drag)
    - Cursor sprite following mouse
    - ColorLayer for cell highlighting
    - Inventory organization pattern
"""
import mcrfpy
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


# Item data for sprites
ITEMS = [
    (103, "Shortsword"),
    (104, "Longsword"),
    (117, "Hammer"),
    (119, "Axe"),
    (101, "Buckler"),
    (102, "Shield"),
    (115, "Health Pot"),
    (116, "Mana Pot"),
    (129, "Wand"),
    (130, "Staff"),
    (114, "Str Potion"),
    (127, "Lesser HP"),
]


class ClickPickupDemo:
    """Demo showing click-to-pickup inventory interaction."""

    def __init__(self):
        self.scene = mcrfpy.Scene("demo_click_pickup")
        self.ui = self.scene.children
        self.grid = None
        self.tile_layer = None
        self.color_layer = None

        # Pickup state
        self.held_entity = None
        self.pickup_cell = None
        self.cursor_sprite = None
        self.last_hover_cell = None

        # Track occupied cells
        self.occupied_cells = {}  # (x, y) -> entity

        self.setup()

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

        # Title
        title = mcrfpy.Caption(
            text="Click to Pick Up",
            pos=(512, 30),
            font_size=28,
            fill_color=(255, 255, 255)
        )
        title.outline = 2
        title.outline_color = (0, 0, 0)
        self.ui.append(title)

        # Status caption
        self.status = mcrfpy.Caption(
            text="Click an item to pick it up",
            pos=(512, 70),
            font_size=16,
            fill_color=(180, 180, 180)
        )
        self.ui.append(self.status)

        # Create inventory grid - zoom in constructor for proper centering
        grid_size = (8, 6)
        cell_size = 64
        grid_pixel_size = (grid_size[0] * cell_size, grid_size[1] * cell_size)
        grid_pos = ((1024 - grid_pixel_size[0]) // 2, 140)

        self.grid = mcrfpy.Grid(
            pos=grid_pos,
            size=grid_pixel_size,
            grid_size=grid_size,
            texture=mcrfpy.default_texture,
            zoom=4.0  # 16px * 4 = 64px per cell
        )

        # Get tile layer and fill with slot tiles
        self.tile_layer = self.grid.layers[0]
        self.tile_layer.fill(46)  # Floor/slot tile

        # Add color layer for highlighting
        self.color_layer = self.grid.add_layer('color', z_index=-1)
        # Initialize with slight tint
        for y in range(grid_size[1]):
            for x in range(grid_size[0]):
                self.color_layer.set((x, y), (200, 200, 200, 50))

        # Add event handlers
        self.grid.on_click = self._on_grid_click
        self.grid.on_cell_enter = self._on_cell_enter
        self.grid.on_move = self._on_grid_move

        self.ui.append(self.grid)

        # Populate with items
        self._populate_grid()

        # Create cursor sprite (initially invisible)
        # This is a Frame with a Sprite child, positioned outside the grid
        self.cursor_frame = mcrfpy.Frame(
            pos=(0, 0),
            size=(64, 64),
            fill_color=(0, 0, 0, 0),  # Transparent
            outline=0
        )
        self.cursor_sprite = mcrfpy.Sprite(
            pos=(0, 0),
            texture=mcrfpy.default_texture,
            sprite_index=0
        )
        self.cursor_sprite.scale = 4.0
        self.cursor_sprite.visible = False
        self.cursor_frame.children.append(self.cursor_sprite)
        self.ui.append(self.cursor_frame)

        # Item name display
        self.item_name = mcrfpy.Caption(
            text="",
            pos=(512, 560),
            font_size=18,
            fill_color=(255, 220, 100)
        )
        self.ui.append(self.item_name)

        # Instructions
        instr = mcrfpy.Caption(
            text="Left click: Pick up / Place | Right click: Cancel | ESC to exit",
            pos=(512, 700),
            font_size=14,
            fill_color=(150, 150, 150)
        )
        self.ui.append(instr)

    def _populate_grid(self):
        """Add items to the grid."""
        # Place items in a pattern
        positions = [
            (0, 0), (2, 0), (4, 1), (6, 0),
            (1, 2), (3, 2), (5, 2), (7, 3),
            (0, 4), (2, 4), (4, 5), (6, 5),
        ]

        for i, (x, y) in enumerate(positions):
            if i >= len(ITEMS):
                break
            sprite_idx, name = ITEMS[i]
            entity = mcrfpy.Entity()
            self.grid.entities.append(entity)
            entity.grid_pos = (x, y)  # Use grid_pos for tile coordinates
            entity.sprite_index = sprite_idx
            entity.name = name  # Store name for display
            self.occupied_cells[(x, y)] = entity

    def _get_grid_cell(self, screen_pos):
        """Convert screen position to grid cell coordinates."""
        cell_size = 16 * self.grid.zoom
        x = int((screen_pos[0] - self.grid.x) / cell_size)
        y = int((screen_pos[1] - self.grid.y) / cell_size)
        grid_w, grid_h = self.grid.grid_size
        if 0 <= x < grid_w and 0 <= y < grid_h:
            return (x, y)
        return None

    def _on_grid_click(self, pos, button, action):
        """Handle grid click."""
        if action != mcrfpy.InputState.PRESSED:
            return

        cell = self._get_grid_cell(pos)
        if cell is None:
            return

        x, y = cell

        if button == mcrfpy.MouseButton.RIGHT:
            # Cancel pickup
            if self.held_entity:
                self._cancel_pickup()
            return

        if button != mcrfpy.MouseButton.LEFT:
            return

        if self.held_entity is None:
            # Try to pick up
            if cell in self.occupied_cells:
                self._pickup_item(cell)
        else:
            # Try to place
            if cell not in self.occupied_cells:
                self._place_item(cell)
            elif cell == self.pickup_cell:
                # Clicked on original cell - cancel
                self._cancel_pickup()

    def _pickup_item(self, cell):
        """Pick up item from cell."""
        entity = self.occupied_cells[cell]
        self.held_entity = entity
        self.pickup_cell = cell

        # Hide the entity
        entity.visible = False

        # Mark source cell yellow
        self.color_layer.set(cell, (255, 255, 100, 200))

        # Setup cursor sprite
        self.cursor_sprite.sprite_index = entity.sprite_index
        self.cursor_sprite.visible = True

        # Update status
        name = getattr(entity, 'name', 'Item')
        self.status.text = f"Holding: {name}"
        self.status.fill_color = (100, 200, 255)
        self.item_name.text = name

    def _place_item(self, cell):
        """Place held item in cell."""
        x, y = cell

        # Move entity to new position
        self.held_entity.grid_pos = (x, y)
        self.held_entity.visible = True

        # Update tracking
        del self.occupied_cells[self.pickup_cell]
        self.occupied_cells[cell] = self.held_entity

        # Clear source cell highlight
        self.color_layer.set(self.pickup_cell, (200, 200, 200, 50))

        # Clear hover highlight
        if self.last_hover_cell and self.last_hover_cell != self.pickup_cell:
            self.color_layer.set(self.last_hover_cell, (200, 200, 200, 50))

        # Hide cursor
        self.cursor_sprite.visible = False

        # Update status
        self.status.text = f"Placed at ({x}, {y})"
        self.status.fill_color = (100, 255, 100)
        self.item_name.text = ""

        self.held_entity = None
        self.pickup_cell = None
        self.last_hover_cell = None

    def _cancel_pickup(self):
        """Cancel current pickup operation."""
        if self.held_entity:
            # Restore entity visibility
            self.held_entity.visible = True

            # Clear source cell highlight
            self.color_layer.set(self.pickup_cell, (200, 200, 200, 50))

            # Clear hover highlight
            if self.last_hover_cell and self.last_hover_cell != self.pickup_cell:
                self.color_layer.set(self.last_hover_cell, (200, 200, 200, 50))

            # Hide cursor
            self.cursor_sprite.visible = False

            self.status.text = "Cancelled"
            self.status.fill_color = (200, 150, 100)
            self.item_name.text = ""

            self.held_entity = None
            self.pickup_cell = None
            self.last_hover_cell = None

    def _on_cell_enter(self, cell_pos):
        """Handle cell hover."""
        x, y = int(cell_pos[0]), int(cell_pos[1])
        cell = (x, y)

        # Show item name on hover (when not holding)
        if self.held_entity is None:
            if cell in self.occupied_cells:
                entity = self.occupied_cells[cell]
                name = getattr(entity, 'name', 'Item')
                self.item_name.text = name
            else:
                self.item_name.text = ""
            return

        # Clear previous hover highlight (if different from source)
        if self.last_hover_cell and self.last_hover_cell != self.pickup_cell:
            self.color_layer.set(self.last_hover_cell, (200, 200, 200, 50))

        # Highlight current cell (if different from source)
        if cell != self.pickup_cell:
            if cell in self.occupied_cells:
                self.color_layer.set(cell, (255, 100, 100, 200))  # Red - can't place
            else:
                self.color_layer.set(cell, (100, 255, 100, 200))  # Green - can place

        self.last_hover_cell = cell

    def _on_grid_move(self, pos):
        """Update cursor sprite position.

        Note: #230 - on_move now only receives position, not button/action
        """
        if self.cursor_sprite.visible:
            # Position cursor centered on mouse
            self.cursor_frame.x = pos[0] - 32
            self.cursor_frame.y = pos[1] - 32

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

        if key == mcrfpy.Key.ESCAPE:
            if self.held_entity:
                self._cancel_pickup()
                return

            try:
                from cookbook_main import main
                main()
            except:
                sys.exit(0)

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


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

    # Headless screenshot
    try:
        if mcrfpy.headless_mode():
            from mcrfpy import automation
            # Simulate picking up an item for screenshot
            demo._pickup_item((0, 0))
            demo.cursor_frame.x = 300
            demo.cursor_frame.y = 350

            mcrfpy.Timer("screenshot", lambda rt: (
                automation.screenshot("screenshots/primitives/click_pickup.png"),
                sys.exit(0)
            ), 100)
    except AttributeError:
        pass


if __name__ == "__main__":
    main()
