/**
 * Controller responsible for managing hover detection and timing logic.
 *
 * This class encapsulates:
 * - Hover delay handling (mouse must stay still for a short time)
 * - Pause delay handling (hover event is fired after a pause)
 * - Tracking of the currently hovered entity
 * - Dispatching hover/unhover events
 *
 * It intentionally does **not** know anything about rendering, input devices,
 * or UI frameworks. All such responsibilities are delegated to `AcEdHoverHost`.
 */
var AcEdHoverController = /** @class */ (function () {
    /**
     * Creates a new hover controller.
     *
     * @param host - View host providing spatial picking and visual feedback hooks
     * @param hoverEvent - Event manager used to dispatch hover events
     * @param unhoverEvent - Event manager used to dispatch unhover events
     * @param hoverDelay - Delay (ms) before hover detection starts after mouse move
     * @param pauseDelay - Delay (ms) before firing hover event after hover is detected
     */
    function AcEdHoverController(host, hoverEvent, unhoverEvent, hoverDelay, pauseDelay) {
        if (hoverDelay === void 0) { hoverDelay = 500; }
        if (pauseDelay === void 0) { pauseDelay = 500; }
        this.host = host;
        this.hoverEvent = hoverEvent;
        this.unhoverEvent = unhoverEvent;
        this.hoverDelay = hoverDelay;
        this.pauseDelay = pauseDelay;
        /**
         * Timer used to delay hover detection.
         *
         * This prevents excessive spatial queries while the mouse is moving
         * continuously.
         */
        this.hoverTimer = null;
        /**
         * Timer used to detect a pause over a hovered entity.
         *
         * Once triggered, a formal hover event is dispatched.
         */
        this.pauseTimer = null;
        /**
         * Object id of the entity currently considered hovered.
         *
         * A value of `null` indicates no entity is hovered.
         */
        this.hoveredId = null;
    }
    /**
     * Handles mouse movement events.
     *
     * This method should be called whenever the mouse moves in the view.
     * It restarts the hover detection timer, ensuring hover logic is only
     * evaluated after the mouse stops moving for a short period.
     *
     * @param x - Mouse X coordinate in world space
     * @param y - Mouse Y coordinate in world space
     */
    AcEdHoverController.prototype.handleMouseMove = function (x, y) {
        var _this = this;
        this.clearHoverTimer();
        this.hoverTimer = setTimeout(function () {
            _this.hoverAt(x, y);
        }, this.hoverDelay);
    };
    /**
     * Clears any active hover state.
     *
     * This immediately unhovers the current entity (if any) and cancels
     * pending pause timers.
     *
     * Typically called when:
     * - View mode changes
     * - Mouse leaves the canvas
     * - Input acquisition starts
     */
    AcEdHoverController.prototype.clear = function () {
        this.setHoveredId(null);
        this.clearPauseTimer();
    };
    /**
     * Disposes the controller and releases all timers.
     *
     * This should be called when the owning view is destroyed to avoid
     * dangling timers and memory leaks.
     */
    AcEdHoverController.prototype.dispose = function () {
        this.clearHoverTimer();
        this.clearPauseTimer();
    };
    /**
     * Performs a hover test at the specified world coordinate.
     *
     * Executes a spatial pick and updates the hovered entity based on
     * the result.
     *
     * @param x - X coordinate in world space
     * @param y - Y coordinate in world space
     */
    AcEdHoverController.prototype.hoverAt = function (x, y) {
        var results = this.host.pick({ x: x, y: y });
        if (results.length > 0) {
            this.setHoveredId(results[0].id);
        }
        else {
            this.clear();
        }
    };
    /**
     * Updates the currently hovered entity.
     *
     * This method ensures:
     * - Proper unhover callbacks and events are fired
     * - New hover callbacks are invoked
     * - Pause timer is started for hover event dispatch
     *
     * @param newId - New hovered object id, or `null` to clear hover
     */
    AcEdHoverController.prototype.setHoveredId = function (newId) {
        if (this.hoveredId) {
            this.unhoverEvent.dispatch({
                id: this.hoveredId,
                x: this.host.curMousePos.x,
                y: this.host.curMousePos.y
            });
            this.host.onUnhover(this.hoveredId);
        }
        this.hoveredId = newId;
        if (newId) {
            this.startPauseTimer(newId);
            this.host.onHover(newId);
        }
    };
    /**
     * Starts the pause timer used to confirm a hover.
     *
     * Once the pause duration elapses, a hover event is dispatched,
     * indicating that the cursor has remained over the entity long
     * enough to be considered an intentional hover.
     *
     * @param id - Object id of the hovered entity
     */
    AcEdHoverController.prototype.startPauseTimer = function (id) {
        var _this = this;
        this.clearPauseTimer();
        this.pauseTimer = setTimeout(function () {
            _this.hoverEvent.dispatch({
                id: id,
                x: _this.host.curMousePos.x,
                y: _this.host.curMousePos.y
            });
        }, this.pauseDelay);
    };
    /**
     * Clears the hover detection timer, if active.
     */
    AcEdHoverController.prototype.clearHoverTimer = function () {
        if (this.hoverTimer) {
            clearTimeout(this.hoverTimer);
            this.hoverTimer = null;
        }
    };
    /**
     * Clears the pause timer, if active.
     */
    AcEdHoverController.prototype.clearPauseTimer = function () {
        if (this.pauseTimer) {
            clearTimeout(this.pauseTimer);
            this.pauseTimer = null;
        }
    };
    return AcEdHoverController;
}());
export { AcEdHoverController };
//# sourceMappingURL=AcEdHoverController.js.map