import { Container } from "pixi.js";
import { gsap } from "gsap";
/**
 * RoomCamera class that manage things like the room dragging or detecting if the room is out of bounds.
 *
 * @class
 * @memberof Scuti
 */
export class RoomCamera extends Container {
    /**
     * @param {Room} [room] - The room instance that will be managed by this camera.
     */
    constructor(room) {
        super();
        /**
         * This method is called when the user start dragging the room.
         *
         * @return {void}
         * @private
         */
        this._dragStart = () => {
            this._dragging = true;
        };
        /**
         * This method is called when the user stop dragging the room.
         *
         * @return {void}
         * @private
         */
        this._dragEnd = () => {
            this._dragging = false;
            if (this._isOutOfBounds()) {
                this._centerCamera();
            }
        };
        /**
         * This method is called when the user is moving the dragged room in the canvas.
         *
         * @param {FederatedPointerEvent} [event] - The mouse event.
         * @return {void}
         * @private
         */
        this._dragMove = (event) => {
            if (this._dragging) {
                this._roomContainer.x = Math.floor(this._roomContainer.x + event.movementX);
                this._roomContainer.y = Math.floor(this._roomContainer.y + event.movementY);
            }
        };
        /**
         * Manage pointer down event on the canvas for tile interaction.
         *
         * @return {void}
         * @private
         */
        this._tilePointerDown = (event) => {
            const tile = this._room.tiles.getTileFromGlobal({ x: event.clientX, y: event.clientY });
            if (tile)
                tile.emit("pointerdown");
        };
        /**
         * Manage pointer up event on the canvas for tile interaction.
         *
         * @return {void}
         * @private
         */
        this._tilePointerUp = (event) => {
            const tile = this._room.tiles.getTileFromGlobal({ x: event.clientX, y: event.clientY });
            if (tile)
                tile.emit("pointerup");
        };
        /**
         * Manage pointer move event on the canvas for tile interaction.
         *
         * @return {void}
         * @private
         */
        this._tilePointerMove = (event) => {
            const object = this._room.tiles.getTileFromGlobal({ x: event.clientX, y: event.clientY });
            if (object === undefined)
                return;
            if (this._selectedTile === object) {
                object.emit("pointermove");
            }
            else {
                if (this._selectedTile !== undefined) {
                    this._selectedTile.emit("pointerout");
                }
                if (object !== undefined) {
                    object.emit("pointerover");
                }
                this._selectedTile = object;
            }
        };
        this._room = room;
        /** Initialise the view container */
        this._viewContainer = new Container();
        /** Initialise the room container */
        this._roomContainer = new Container();
        this._roomContainer.addChild(this._room);
        this._viewContainer.addChild(this._roomContainer);
        this.addChild(this._viewContainer);
        /** Handle interactions */
        this._room.engine.application.renderer.events.domElement.addEventListener("pointerdown", this._dragStart);
        this._room.engine.application.renderer.events.domElement.addEventListener("pointerup", this._dragEnd);
        this._room.engine.application.renderer.events.domElement.addEventListener("pointermove", this._dragMove);
        /** Handle tile interactions */
        this._room.engine.application.renderer.events.domElement.addEventListener("pointerdown", this._tilePointerDown);
        this._room.engine.application.renderer.events.domElement.addEventListener("pointerup", this._tilePointerUp);
        this._room.engine.application.renderer.events.domElement.addEventListener("pointermove", this._tilePointerMove);
        this._updateBounds();
        this._centerCamera();
    }
    /**
     * Update the room container bounds.
     *
     * @return {void}
     * @private
     */
    _updateBounds() {
        this._roomContainer.pivot.x = this._room.view.wallLayer.getBounds().x;
        this._roomContainer.pivot.y = this._room.view.wallLayer.getBounds().y;
    }
    /**
     * Tween the room container at the center of the PixiJS view.
     *
     * @return {void}
     * @private
     */
    _centerCamera() {
        gsap.to(this._roomContainer, {
            x: Math.floor(this._room.engine.application.view.width / 2 - this._room.view.width / 2),
            y: Math.floor(this._room.engine.application.view.height / 2 - this._room.view.height / 2),
            duration: 0.8,
            ease: "easeOut",
        });
    }
    /**
     * Indicate if the room container is out of bounds of the PixiJS view.
     *
     * @return {boolean}
     * @private
     */
    _isOutOfBounds() {
        /** Out of bounds on the right */
        if (this._roomContainer.x > this._room.engine.application.view.width)
            return true;
        /** Out of bounds on the left */
        if ((this._roomContainer.x + this._roomContainer.width) < 0)
            return true;
        /** Out of bounds on the bottom */
        if (this._roomContainer.y > this._room.engine.application.view.height)
            return true;
        /** Out of bounds on the top */
        if ((this._roomContainer.y + this._roomContainer.height) < 0)
            return true;
        /** It is not out of bounds */
        return false;
    }
}
//# sourceMappingURL=RoomCamera.js.map