'use strict';

var EventBus = require('../core/EventBus.js');

/* ────────────────────────────────────────────────────────────────
   Multiplayer Local — SplitScreen, PlayerManager, drop-in/out
──────────────────────────────────────────────────────────────── */
/* ── Player Manager ───────────────────────────────────────────── */
class PlayerManager {
    constructor(maxPlayers = 4) {
        this.events = new EventBus.EventBus();
        this.players = new Map();
        this.maxPlayers = maxPlayers;
    }
    get activeCount() {
        let n = 0;
        for (const p of this.players.values())
            if (p.active)
                n++;
        return n;
    }
    getPlayer(index) {
        return this.players.get(index);
    }
    get allPlayers() {
        return Array.from(this.players.values());
    }
    get activePlayers() {
        return this.allPlayers.filter(p => p.active);
    }
    /* ── Drop-in / Drop-out ─────────────────────────────────────── */
    join(config) {
        var _a;
        if (this.players.has(config.index))
            return null;
        if (this.players.size >= this.maxPlayers)
            return null;
        const player = {
            index: config.index,
            name: config.name || `Player ${config.index + 1}`,
            color: config.color,
            inputDevice: config.inputDevice === 'gamepad' ? 'gamepad' : 'keyboard',
            gamepadIndex: (_a = config.gamepadIndex) !== null && _a !== void 0 ? _a : config.index,
            score: 0,
            lives: 3,
            active: true,
            entityId: null,
        };
        this.players.set(config.index, player);
        this.events.emit('player:join', player);
        return player;
    }
    leave(index) {
        const p = this.players.get(index);
        if (!p)
            return;
        p.active = false;
        this.events.emit('player:leave', p);
        this.players.delete(index);
    }
    /** Quick setup for single player (keyboard). */
    setupSingle() {
        this.clear();
        return this.join({
            index: 0,
            name: 'Player 1',
            color: PLAYER_COLORS[0],
            inputDevice: 'keyboard',
        });
    }
    /** Quick setup for local multiplayer. */
    setupLocal(count) {
        this.clear();
        const players = [];
        for (let i = 0; i < Math.min(count, this.maxPlayers); i++) {
            const p = this.join({
                index: i,
                name: `Player ${i + 1}`,
                color: PLAYER_COLORS[i % PLAYER_COLORS.length],
                inputDevice: i === 0 ? 'keyboard' : 'gamepad',
                gamepadIndex: i > 0 ? i - 1 : undefined,
            });
            if (p)
                players.push(p);
        }
        return players;
    }
    clear() {
        this.players.clear();
    }
}
class SplitScreenManager {
    constructor() {
        this._mode = 'shared';
        this._canvasWidth = 1280;
        this._canvasHeight = 720;
        this.viewports = [];
    }
    get mode() {
        return this._mode;
    }
    /** Set screen dimensions (usually from canvas). */
    setCanvasSize(w, h) {
        this._canvasWidth = w;
        this._canvasHeight = h;
        this.rebuildViewports();
    }
    /** Configure split mode for N active players. */
    configure(players, preferredMode) {
        const count = players.filter(p => p.active).length;
        if (preferredMode) {
            this._mode = preferredMode;
        }
        else {
            // Auto-detect best layout
            if (count <= 1)
                this._mode = 'shared';
            else if (count === 2)
                this._mode = 'split-vertical';
            else if (count <= 4)
                this._mode = 'split-quad';
            else if (count <= 6)
                this._mode = 'split-6';
            else if (count <= 9)
                this._mode = 'split-9';
            else
                this._mode = 'split-12';
        }
        this.rebuildViewports();
    }
    buildGrid(cols, rows, maxSlots) {
        const w = this._canvasWidth;
        const h = this._canvasHeight;
        const cw = 1 / cols;
        const ch = 1 / rows;
        const pw = w / cols;
        const ph = h / rows;
        for (let i = 0; i < maxSlots; i++) {
            const col = i % cols;
            const row = Math.floor(i / cols);
            this.viewports.push({
                playerIndex: i,
                rect: { x: col * cw, y: row * ch, width: cw, height: ch },
                pixelRect: { x: Math.round(col * pw), y: Math.round(row * ph), width: Math.round(pw), height: Math.round(ph) },
            });
        }
    }
    rebuildViewports() {
        this.viewports = [];
        const w = this._canvasWidth;
        const h = this._canvasHeight;
        switch (this._mode) {
            case 'shared':
                this.viewports.push({
                    playerIndex: -1,
                    rect: { x: 0, y: 0, width: 1, height: 1 },
                    pixelRect: { x: 0, y: 0, width: w, height: h },
                });
                break;
            case 'split-horizontal':
                this.viewports.push({
                    playerIndex: 0,
                    rect: { x: 0, y: 0, width: 1, height: 0.5 },
                    pixelRect: { x: 0, y: 0, width: w, height: h / 2 },
                }, {
                    playerIndex: 1,
                    rect: { x: 0, y: 0.5, width: 1, height: 0.5 },
                    pixelRect: { x: 0, y: h / 2, width: w, height: h / 2 },
                });
                break;
            case 'split-vertical':
                this.viewports.push({
                    playerIndex: 0,
                    rect: { x: 0, y: 0, width: 0.5, height: 1 },
                    pixelRect: { x: 0, y: 0, width: w / 2, height: h },
                }, {
                    playerIndex: 1,
                    rect: { x: 0.5, y: 0, width: 0.5, height: 1 },
                    pixelRect: { x: w / 2, y: 0, width: w / 2, height: h },
                });
                break;
            case 'split-quad':
                this.buildGrid(2, 2, 4);
                break;
            case 'split-6':
                this.buildGrid(3, 2, 6);
                break;
            case 'split-9':
                this.buildGrid(3, 3, 9);
                break;
            case 'split-12':
                this.buildGrid(4, 3, 12);
                break;
        }
    }
    getViewports() {
        return this.viewports;
    }
    getViewportForPlayer(playerIndex) {
        return this.viewports.find(v => v.playerIndex === playerIndex);
    }
    /** Apply viewport clip/transform to Canvas 2D context before rendering a player's view. */
    applyViewport(ctx, viewport) {
        const r = viewport.pixelRect;
        ctx.save();
        ctx.beginPath();
        ctx.rect(r.x, r.y, r.width, r.height);
        ctx.clip();
        ctx.translate(r.x, r.y);
    }
    /** Restore context after rendering a viewport. */
    restoreViewport(ctx) {
        ctx.restore();
    }
    /** Render divider lines between viewports. */
    renderDividers(ctx, lineColor = '#333', lineWidth = 2) {
        if (this._mode === 'shared')
            return;
        ctx.save();
        ctx.strokeStyle = lineColor;
        ctx.lineWidth = lineWidth;
        const w = this._canvasWidth;
        const h = this._canvasHeight;
        const gridSpec = this.getGridSpec();
        if (gridSpec) {
            const { cols, rows } = gridSpec;
            // Vertical dividers
            for (let c = 1; c < cols; c++) {
                const x = Math.round(w * c / cols);
                ctx.beginPath();
                ctx.moveTo(x, 0);
                ctx.lineTo(x, h);
                ctx.stroke();
            }
            // Horizontal dividers
            for (let r = 1; r < rows; r++) {
                const y = Math.round(h * r / rows);
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(w, y);
                ctx.stroke();
            }
        }
        else if (this._mode === 'split-vertical') {
            ctx.beginPath();
            ctx.moveTo(w / 2, 0);
            ctx.lineTo(w / 2, h);
            ctx.stroke();
        }
        else if (this._mode === 'split-horizontal') {
            ctx.beginPath();
            ctx.moveTo(0, h / 2);
            ctx.lineTo(w, h / 2);
            ctx.stroke();
        }
        ctx.restore();
    }
    /** Get cols/rows for grid-based layouts. */
    getGridSpec() {
        switch (this._mode) {
            case 'split-quad': return { cols: 2, rows: 2 };
            case 'split-6': return { cols: 3, rows: 2 };
            case 'split-9': return { cols: 3, rows: 3 };
            case 'split-12': return { cols: 4, rows: 3 };
            default: return null;
        }
    }
}
/* ── Default player colors ────────────────────────────────────── */
const PLAYER_COLORS = [
    { r: 0.2, g: 0.5, b: 1, a: 1 }, // P1  blue
    { r: 1, g: 0.3, b: 0.3, a: 1 }, // P2  red
    { r: 0.2, g: 0.9, b: 0.3, a: 1 }, // P3  green
    { r: 1, g: 0.8, b: 0.1, a: 1 }, // P4  yellow
    { r: 0.8, g: 0.2, b: 0.9, a: 1 }, // P5  purple
    { r: 1, g: 0.5, b: 0.1, a: 1 }, // P6  orange
    { r: 0.1, g: 0.9, b: 0.9, a: 1 }, // P7  cyan
    { r: 1, g: 0.4, b: 0.7, a: 1 }, // P8  pink
    { r: 0.6, g: 0.4, b: 0.2, a: 1 }, // P9  brown
    { r: 0.7, g: 0.7, b: 0.7, a: 1 }, // P10 silver
    { r: 0.5, g: 1, b: 0.5, a: 1 }, // P11 lime
    { r: 0.9, g: 0.9, b: 0.3, a: 1 }, // P12 gold
];

exports.PLAYER_COLORS = PLAYER_COLORS;
exports.PlayerManager = PlayerManager;
exports.SplitScreenManager = SplitScreenManager;
//# sourceMappingURL=LocalMultiplayer.js.map
