// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import { Emit } from '../../../../events/Decorators/EmitDecorator';
import { Themeable } from '../../../Behaviors/Themeable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { CustomElement } from '../../Abstracts/CustomElement';
import { designerElementTemplate } from './DesignerElementTemplate';
import { DesignerMode } from './IDesignerElementProps';
import { designerElementCosmopolitanStyle } from './Themes/DesignerElement.Cosmopolitan';
import { designerElementJoyStyle } from './Themes/DesignerElement.Joy';
import { designerElementMemphisStyle } from './Themes/DesignerElement.Memphis';
// #endregion
/**
 * The default frame size.
 *
 * @private
 */
const DEFAULT_FRAME_SIZE = { width: 1024, height: 1024 };
/**
 * Designer - The root coordination component for the design environment.
 *
 * @description
 * The Designer component provides the top-level context for a designer
 * workspace, managing designer-wide state, layer management in controlled
 * and uncontrolled patterns, and frame sizing context consumed by descendants.
 * It establishes the structural foundation for canvas-based editing surfaces.
 *
 * @name Designer
 * @element mosaik-designer
 * @category Layouts
 *
 * @slot - Default slot for the primary workspace structure (mosaik-designer-content)
 * @slot header - Generic extension slot for header content such as toolbars
 * @slot before-content - Generic extension slot before the main content area
 * @slot after-content - Generic extension slot after the main content area
 * @slot footer - Generic extension slot for footer content such as status bars
 *
 * @cssprop {String} --designer-transition-duration - Transition duration for animated state changes
 * @cssprop {String} --designer-transition-mode - Transition timing function
 * @cssprop {String} --designer-transition-property - Transition properties to animate
 *
 * @dependency {DesignerContentElement} - Content region for the canvas
 * @dependency {DesignerCanvasElement} - Zoomable and pannable canvas surface
 * @dependency {DesignerFrameElement} - Artboard-like design surface
 *
 * @fires layersChanged {DesignerLayersChangedEvent} - Fired when the layers change via user action
 *
 * @example
 * Minimal designer workspace with a canvas and frame:
 * ```html
 * <mosaik-designer>
 *   <mosaik-designer-content>
 *     <mosaik-designer-canvas>
 *       <mosaik-designer-frame></mosaik-designer-frame>
 *     </mosaik-designer-canvas>
 *   </mosaik-designer-content>
 * </mosaik-designer>
 * ```
 *
 * @example
 * Designer workspace with header toolbar and footer status bar:
 * ```html
 * <mosaik-designer>
 *   <mosaik-stack slot="header" orientation="horizontal">
 *     <mosaik-button label="Save"></mosaik-button>
 *   </mosaik-stack>
 *   <mosaik-designer-content>
 *     <mosaik-designer-canvas>
 *       <mosaik-designer-frame></mosaik-designer-frame>
 *     </mosaik-designer-canvas>
 *   </mosaik-designer-content>
 *   <mosaik-text slot="footer" text="Ready"></mosaik-text>
 * </mosaik-designer>
 * ```
 *
 * @public
 */
let DesignerElement = class DesignerElement extends Themeable(CustomElement) {
    // #region Fields
    _layersChanged;
    _defaultLayers;
    _layers;
    _internalLayers;
    _frameSize;
    _mode;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the {@link DesignerElement} class.
     *
     * @public
     */
    constructor() {
        super();
        this._defaultLayers = null;
        this._layers = null;
        this._internalLayers = [];
        this._frameSize = DEFAULT_FRAME_SIZE;
        this._mode = DesignerMode.None;
        this._layersChanged = new HTMLElementEventEmitter(this, 'layersChanged');
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-designer';
    }
    /**
     * Gets or sets the `defaultLayers` property.
     * Used for uncontrolled mode. Sets the initial layers.
     *
     * @public
     */
    get defaultLayers() {
        return this._defaultLayers;
    }
    set defaultLayers(value) {
        if (this._defaultLayers !== value) {
            this._defaultLayers = value;
            if (this._layers === null && value !== null) {
                this._internalLayers = [...value];
            }
            this.requestUpdate('defaultLayers');
        }
    }
    /**
     * Gets or sets the `layers` property.
     * Used for controlled mode. When set, the designer uses this as the source of truth.
     *
     * @public
     */
    get layers() {
        return this._layers;
    }
    set layers(value) {
        if (this._layers !== value) {
            this._layers = value;
            this.requestUpdate('layers');
        }
    }
    /**
     * Gets or sets the `frameSize` property.
     * Defines the size of the inner design frame.
     *
     * @public
     */
    get frameSize() {
        return this._frameSize;
    }
    set frameSize(value) {
        if (this._frameSize !== value) {
            this._frameSize = value;
            this.requestUpdate('frameSize');
        }
    }
    /**
     * Gets or sets the `mode` property.
     * Controls the selection behavior: 'none', 'single', or 'multiple'.
     *
     * @public
     * @attr
     */
    get mode() {
        return this._mode;
    }
    set mode(value) {
        if (this._mode !== value) {
            this._mode = value;
            this.requestUpdate('mode');
        }
    }
    /**
     * Returns the resolved layers, respecting controlled vs uncontrolled mode.
     *
     * @public
     * @readonly
     */
    get resolvedLayers() {
        return this._layers ?? this._internalLayers;
    }
    /**
     * Called when the layers change via user action.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get layersChanged() {
        return this._layersChanged;
    }
    // #endregion
    // #region Methods
    /**
     * Updates the layers from a user action.
     * In uncontrolled mode, updates internal state directly.
     * In controlled mode, emits the change for the parent to handle.
     *
     * @public
     */
    updateLayers(newLayers) {
        if (this._layers !== null) {
            this._layersChanged.emit(newLayers);
        }
        else {
            this._internalLayers = newLayers;
            this._layersChanged.emit(newLayers);
            this.requestUpdate('resolvedLayers');
        }
    }
};
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], DesignerElement.prototype, "defaultLayers", null);
__decorate([
    Property({ type: Array }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], DesignerElement.prototype, "layers", null);
__decorate([
    Property({ type: Object }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], DesignerElement.prototype, "frameSize", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], DesignerElement.prototype, "mode", null);
__decorate([
    Emit({ eventName: 'layersChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], DesignerElement.prototype, "layersChanged", null);
DesignerElement = __decorate([
    Component({
        selector: 'mosaik-designer',
        template: designerElementTemplate,
        themes: {
            joy: designerElementJoyStyle,
            memphis: designerElementMemphisStyle,
            cosmopolitan: designerElementCosmopolitanStyle
        },
        imports: []
    }),
    __metadata("design:paramtypes", [])
], DesignerElement);
export { DesignerElement };
//# sourceMappingURL=DesignerElement.js.map