import { TemporalMixinInterface } from "../elements/EFTemporal.js";
import { CanvasElementData } from "./api/types.js";
import { SelectionContext } from "./selection/selectionContext.js";
import { PanZoomTransform } from "../elements/EFPanZoom.js";
import "./overlays/SelectionOverlay.js";
import "../gui/EFOverlayLayer.js";
import "../gui/EFTransformHandles.js";
import * as lit29 from "lit";
import { LitElement } from "lit";
import * as lit_html27 from "lit-html";

//#region src/canvas/EFCanvas.d.ts
declare const EFCanvas_base: typeof LitElement;
/**
 * =============================================================================
 * COORDINATE SYSTEM AND DIMENSION CALCULATION PRINCIPLES
 * =============================================================================
 *
 * This canvas system uses a unified approach for calculating element positions
 * and dimensions that works correctly regardless of CSS transforms (rotation,
 * scale, etc.), zoom level, or nesting depth.
 *
 * TWO KEY DOM APIS WITH DIFFERENT BEHAVIORS:
 *
 * 1. offsetWidth / offsetHeight
 *    - Returns the element's LAYOUT dimensions (CSS box model)
 *    - These are the dimensions BEFORE any CSS transforms are applied
 *    - UNAFFECTED by: rotation, scale, skew, or any other transform
 *    - UNAFFECTED by: parent transforms (including zoom scale)
 *    - AFFECTED by: CSS width/height properties, padding, border
 *    - Units: CSS pixels in the element's own coordinate space
 *
 *    Example: A 200x100px element rotated 45° still has offsetWidth=200, offsetHeight=100
 *    Example: A 200x100px element in a 2x zoomed canvas still has offsetWidth=200, offsetHeight=100
 *
 *    USE FOR: Getting the actual dimensions of an element in canvas coordinates
 *
 * 2. getBoundingClientRect()
 *    - Returns the element's visual BOUNDING BOX on screen
 *    - This is the axis-aligned rectangle that fully contains the transformed element
 *    - AFFECTED by: rotation (bounding box grows), scale, all transforms
 *    - AFFECTED by: parent transforms (including zoom scale)
 *    - Units: Screen pixels (viewport coordinates)
 *
 *    Example: A 200x100px element rotated 45° has bounding box ~212x212px
 *    Example: A 200x100px element in a 2x zoomed canvas has bounding rect 400x200px
 *
 *    USE FOR: Getting the visual center position (center of bounding box = element center)
 *    NOT FOR: Getting actual dimensions (bounding box ≠ actual size when rotated)
 *
 * THE UNIFIED CALCULATION METHOD:
 *
 * For ANY element (rotated, scaled, nested, etc.):
 *
 * 1. DIMENSIONS: Use offsetWidth/offsetHeight
 *    - These give us the true dimensions in canvas coordinates
 *    - No division by scale needed - they're already in canvas space
 *
 * 2. CENTER POSITION: Use getBoundingClientRect() center
 *    - screenCenterX = rect.left + rect.width / 2
 *    - screenCenterY = rect.top + rect.height / 2
 *    - The center of the bounding box IS the element's center
 *    - This is true for ANY rotation (rotation around center keeps center fixed)
 *
 * 3. TOP-LEFT POSITION: Calculate from center and dimensions
 *    - canvasX = canvasCenter.x - width / 2
 *    - canvasY = canvasCenter.y - height / 2
 *
 * WHY THIS WORKS UNIVERSALLY:
 *
 * - offsetWidth/Height are defined by CSS spec to be unaffected by transforms
 * - The center of any shape is preserved under rotation around that center
 * - This mathematical relationship holds for ALL transform combinations
 * - No special cases needed for rotation, scale, or nesting
 *
 * COMMON MISTAKES TO AVOID:
 *
 * ❌ Using getBoundingClientRect().width for dimensions (wrong when rotated)
 * ❌ Dividing offsetWidth by scale (offsetWidth is already in canvas coords)
 * ❌ Using getBoundingClientRect().left/top for position (wrong when rotated)
 * ❌ Having different code paths for rotated vs non-rotated elements
 *
 * =============================================================================
 */
/**
 * Main canvas container element.
 * Manages existing elements (EF* elements, divs, etc.) and provides selection functionality.
 */
declare class EFCanvas extends EFCanvas_base {
  static styles: lit29.CSSResult[];
  panZoomTransform?: PanZoomTransform;
  elementIdAttribute: string;
  enableTransformHandles: boolean;
  /**
   * When true, the overlay RAF loop skips all layout-thrashing work
   * (transform handles, metadata updates). Used during playback to
   * avoid competing with the canvas render pipeline for CPU time.
   */
  paused: boolean;
  private elementRegistry;
  private elementMetadata;
  private selectionController;
  private overlayLayer;
  private selectionOverlay;
  private transformHandlesMap;
  private overlayRafId;
  private isDragging;
  private dragStarted;
  private dragStartPos;
  private dragStartCanvasPos;
  private dragStartElementPositions;
  private draggedElementId;
  private capturedPointerId;
  private readonly DRAG_THRESHOLD;
  private isBoxSelecting;
  private boxSelectStart;
  private boxSelectModifierKeys;
  private emptySpaceClickPos;
  private selectionChangeHandler?;
  private elementHoverHandlers;
  private _activeRootTemporal;
  selectionContext: SelectionContext;
  /**
   * The currently highlighted (hovered) element.
   * This is the source of truth for highlight state across all panels
   * (canvas, hierarchy, timeline).
   */
  highlightedElement: HTMLElement | null;
  constructor();
  connectedCallback(): void;
  disconnectedCallback(): void;
  /**
   * Setup mutation observer to track element additions/removals.
   */
  private setupElementTracking;
  /**
   * Try to register an element, auto-generating an ID if needed.
   * Public method for external use (e.g., hierarchy selection).
   */
  tryRegisterElement(element: HTMLElement): void;
  /**
   * Register an element for canvas management.
   * @throws Error if element does not have an ID
   */
  registerElement(element: HTMLElement, id?: string): string;
  /**
   * Unregister an element.
   */
  unregisterElement(element: HTMLElement | string): void;
  /**
   * Setup hover event listeners for an element to update highlightedElement.
   * The canvas is the source of truth for highlight state.
   */
  private setupElementHoverListeners;
  /**
   * Set the highlighted element. Called by canvas hover handlers
   * and by external panels (hierarchy, timeline) when user hovers items.
   */
  setHighlightedElement(element: HTMLElement | null): void;
  /**
   * Remove hover event listeners for an element.
   */
  private removeElementHoverListeners;
  /**
   * Update element metadata from DOM.
   *
   * UNIFIED APPROACH - works for ALL elements regardless of rotation, scale, or nesting:
   *
   * 1. DIMENSIONS: Always use offsetWidth/offsetHeight
   *    - These are layout dimensions in the element's coordinate space
   *    - Unaffected by CSS transforms (rotation, scale, etc.)
   *    - Already in canvas coordinates (no scale division needed)
   *
   * 2. CENTER POSITION: Always use getBoundingClientRect() center
   *    - The center of the bounding box IS the element's center (transform-origin: center)
   *    - Works correctly for rotated elements (center is rotation-invariant)
   *    - Convert to canvas coordinates using screenToCanvas()
   *
   * 3. TOP-LEFT POSITION: Calculate from center and dimensions
   *    - x = centerX - width/2
   *    - y = centerY - height/2
   */
  private updateElementMetadata;
  /**
   * Hit test - find elements intersecting with bounds.
   * @param bounds - DOMRect in canvas coordinate space (from SelectionModel.boxSelectBounds)
   */
  private hitTest;
  /**
   * Handle pointer down events.
   * Only handles events when clicking on elements. Otherwise, lets panzoom handle it.
   */
  private handlePointerDown;
  /**
   * Handle pointer move events.
   */
  private handlePointerMove;
  /**
   * Handle pointer up events.
   */
  private handlePointerUp;
  /**
   * Setup listener for selection changes to update data-selected attributes.
   */
  private setupSelectionListener;
  /**
   * Remove selection change listener.
   */
  private removeSelectionListener;
  /**
   * Get the root temporal element containing the current selection.
   * Returns null if no element is selected or the selected element has no root temporal.
   */
  get activeRootTemporal(): (TemporalMixinInterface & HTMLElement) | null;
  /**
   * Update data-selected attributes on elements based on current selection.
   * This enables pure CSS styling of selected elements.
   */
  private updateSelectionAttributes;
  /**
   * Update element position in canvas coordinates.
   * Unified approach: Always calculate relative to parent (or .canvas-content for direct children).
   * For direct children, parent position is (0, 0), so relative = absolute (no-op).
   *
   * For nested elements, we read parent's current position from DOM (not metadata) to ensure
   * we're always calculating relative to the actual current position.
   */
  updateElementPosition(elementId: string, x: number, y: number): void;
  /**
   * Get element metadata.
   */
  getElementData(elementId: string): CanvasElementData | null;
  /**
   * Get all element data.
   */
  getAllElementsData(): CanvasElementData[];
  /**
   * Convert screen coordinates to canvas coordinates (for API).
   */
  screenToCanvasCoords(screenX: number, screenY: number): {
    x: number;
    y: number;
  };
  /**
   * Convert canvas coordinates to screen coordinates (for API).
   */
  canvasToScreenCoords(canvasX: number, canvasY: number): {
    x: number;
    y: number;
  };
  /**
   * Setup overlay layer as sibling of panzoom (outside panzoom, same level as panzoom).
   */
  private setupOverlayLayer;
  /**
   * Cleanup overlay layer if we created it.
   */
  private cleanupOverlayLayer;
  /**
   * Setup selection overlay as sibling of panzoom (outside panzoom, same level as panzoom).
   * This ensures the overlay maintains 1:1 pixel ratio regardless of zoom level.
   */
  private setupSelectionOverlay;
  /**
   * Cleanup selection overlay if we created it.
   */
  private cleanupSelectionOverlay;
  /**
   * Start RAF loop for overlay layer sync and transform handles updates.
   */
  private wasPaused;
  private startOverlayRafLoop;
  /**
   * Stop RAF loop.
   */
  private stopOverlayRafLoop;
  /**
   * Update transform handles for selected elements.
   * For multiple selections, shows a single set of handles for the bounding box.
   */
  private updateTransformHandles;
  /**
   * Update transform handles bounds for an element.
   */
  private updateTransformHandlesBounds;
  /**
   * Handle transform handles bounds-change event for multi-selection.
   * Updates all selected elements proportionally.
   */
  private handleMultiSelectionTransformHandlesBoundsChange;
  private lastMultiSelectionRotation;
  private multiSelectionRotationCenter;
  private multiSelectionResizeInitial;
  /**
   * Handle transform handles rotation-change event for multiple selected elements.
   * Rotates all elements around the center of the bounding box.
   */
  private handleMultiSelectionTransformHandlesRotationChange;
  /**
   * Handle transform handles bounds-change event for single element.
   * Converts bounds from overlay-relative screen coordinates to canvas coordinates.
   */
  private handleTransformHandlesBoundsChange;
  /**
   * Handle transform handles rotation-change event for single element.
   */
  private handleTransformHandlesRotationChange;
  /**
   * Cleanup transform handles.
   */
  private cleanupTransformHandles;
  render(): lit_html27.TemplateResult<1>;
}
declare global {
  interface HTMLElementTagNameMap {
    "ef-canvas": EFCanvas;
  }
}
//#endregion
export { EFCanvas };
//# sourceMappingURL=EFCanvas.d.ts.map