// #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 { Equals } from '../../../Equality/Equals';
import { BreakpointAlias } from '../../../Layout/Breakpoint/BreakpointAlias';
import { BreakpointController } from '../../../Layout/Breakpoint/BreakpointController';
import { Theme2Element } from '../../../Theming/Theme2Element';
import { Slottable } from '../../Behaviors/Slottable';
import { Themeable } from '../../Behaviors/Themeable';
import { Attribute } from '../../Decorators/AttributeDecorator';
import { Component } from '../../Decorators/ComponentDecorator';
import { Property } from '../../Decorators/PropertyDecorator';
import { Watch } from '../../Decorators/WatchDecorator';
import { CustomElement } from '../Abstracts/CustomElement';
import { DrawerElement } from '../Overlays/Drawer/DrawerElement';
import { appElementTemplate } from './AppElementTemplate';
import { AppHeaderElement } from './AppHeaderElement';
import { appElementCosmopolitanStyle } from './Themes/AppElement.Cosmopolitan';
import { appElementJoyStyle } from './Themes/AppElement.Joy';
import { appElementMemphisStyle } from './Themes/AppElement.Memphis';
// #endregion
/**
 * App - A comprehensive application shell component that provides the foundation layout structure for modern web applications.
 *
 * @description
 * Creates a complete application framework with integrated navigation drawers, headers, content areas, and responsive
 * layout management. Handles breakpoint-aware design, theme management, and provides structured slots for organizing
 * application navigation, branding, actions, and primary content in a cohesive shell architecture.
 *
 * @name AppElement
 * @element mosaik-app
 * @category Shell
 *
 * @slot content - Main content area for primary application content and views
 * @slot footer - Footer area for secondary information, links, and application metadata
 * @slot header - The header slot.
 * @slot headerActions - The headerActions slot.
 * @slot headerLogo - The headerLogo slot.
 * @slot headerMenu - The headerMenu slot.
 * @slot nav - Navigation drawer content area for primary navigation links and menu items
 *
 * @csspart content - Main content wrapper for application views and functionality
 * @csspart drawer - Navigation drawer container for side navigation elements
 * @csspart header - Application header section containing branding and navigation controls
 * @csspart nav - Navigation area within the drawer for menu items and links
 *
 * @cssprop {Color} --app-background-color - Background color for the application shell
 * @cssprop {String} --app-border-radius - The border radius CSS custom property.
 * @cssprop {String} --app-content-offset-top - The content offset top CSS custom property.
 * @cssprop {String} --app-drawer-height - The drawer height CSS custom property.
 * @cssprop {String} --app-drawer-width - Width of the navigation drawer when expanded
 * @cssprop {String} --app-font-family - The font family CSS custom property.
 * @cssprop {String} --app-font-letter-spacing - The font letter spacing CSS custom property.
 * @cssprop {String} --app-font-line-height - The font line height CSS custom property.
 * @cssprop {String} --app-font-size - The font size CSS custom property.
 * @cssprop {String} --app-font-text-decoration - The font text decoration CSS custom property.
 * @cssprop {String} --app-font-text-transform - The font text transform CSS custom property.
 * @cssprop {String} --app-font-weight - The font weight CSS custom property.
 * @cssprop {String} --app-foreground-color - The foreground color CSS custom property.
 * @cssprop {String} --app-gap - The gap CSS custom property.
 * @cssprop {String} --app-line-thickness - The line thickness CSS custom property.
 * @cssprop {String} --app-padding-bottom - The padding bottom CSS custom property.
 * @cssprop {String} --app-padding-left - The padding left CSS custom property.
 * @cssprop {String} --app-padding-right - The padding right CSS custom property.
 * @cssprop {String} --app-padding-top - The padding top CSS custom property.
 * @cssprop {String} --app-shadow - The shadow CSS custom property.
 * @cssprop {String} --app-shadow-blur - The shadow blur CSS custom property.
 * @cssprop {String} --app-shadow-color - The shadow color CSS custom property.
 * @cssprop {String} --app-shadow-offset-x - The shadow offset x CSS custom property.
 * @cssprop {String} --app-shadow-offset-y - The shadow offset y CSS custom property.
 * @cssprop {String} --app-shadow-spread - The shadow spread CSS custom property.
 * @cssprop {String} --app-transition-duration - The transition duration CSS custom property.
 * @cssprop {String} --app-transition-mode - The transition mode CSS custom property.
 * @cssprop {String} --app-transition-property - The transition property CSS custom property.
 * @cssprop {String} --app-translate - The translate CSS custom property.
 *
 * @dependency mosaik-app-header - The App Header element.
 * @dependency mosaik-drawer - The Drawer element.
 * @dependency mosaik-drawer-container - The Drawer Container element.
 * @dependency mosaik-drawer-content - The Drawer Content element.
 * @dependency mosaik-theme2 - The Theme2 element.
 *
 * @example
 * Basic application shell:
 * ```html
 * <mosaik-app>
 *   <nav slot="nav">
 *     <a href="/dashboard">Dashboard</a>
 *     <a href="/settings">Settings</a>
 *   </nav>
 *   <main slot="content">
 *     <p>Welcome to the application.</p>
 *   </main>
 * </mosaik-app>
 * ```
 *
 * @example
 * App with navigation and header:
 * ```html
 * <mosaik-app has-nav has-header>
 *   <mosaik-app-header></mosaik-app-header>
 *   <nav slot="nav">
 *     <a href="/">Home</a>
 *     <a href="/about">About</a>
 *   </nav>
 *   <main slot="content">
 *     <p>Application content here.</p>
 *   </main>
 *   <footer slot="footer">
 *     <p>© 2024 My Company.</p>
 *   </footer>
 * </mosaik-app>
 * ```
 *
 * @public
 */
let AppElement = class AppElement extends Themeable(Slottable(CustomElement)) {
    // #region Fields
    _breakpointController;
    _drawerElement;
    _headerElement;
    _contentElement;
    _theme;
    _isNavOpen;
    _hasNav;
    _isMobile;
    _hasHeader;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._theme = null;
        this._isNavOpen = false;
        this._hasNav = false;
        this._isMobile = false;
        this._hasHeader = false;
        this._breakpointController = new BreakpointController(this, {
            query: BreakpointAlias.LessThanMedium,
            callback: (match) => {
                this.isMobile = match;
            }
        });
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     * The `is` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-app';
    }
    /**
     * Gets or sets the `theme` property.
     *
     * @public
     */
    get theme() {
        return this._theme;
    }
    set theme(value) {
        if (!Equals.areObjectsEqual(this._theme, value)) {
            this._theme = value;
            this.requestUpdate('theme');
        }
    }
    /**
     * Gets or sets the `isNavOpen` property.
     *
     * @public
     * @attr
     */
    get isNavOpen() {
        return this._isNavOpen;
    }
    set isNavOpen(value) {
        if (this._isNavOpen !== value) {
            this._isNavOpen = value;
            this.requestUpdate('isNavOpen');
        }
    }
    /**
     * Gets or sets the `hasNav` property.
     *
     * @public
     * @attr
     */
    get hasNav() {
        return this._hasNav;
    }
    set hasNav(value) {
        if (this._hasNav !== value) {
            this._hasNav = value;
            this.requestUpdate('hasNav');
        }
    }
    /**
     * Gets or sets the `isMobile` property.
     *
     * @public
     * @readonly
     * @attr
     */
    get isMobile() {
        return this._isMobile;
    }
    set isMobile(value) {
        if (this._isMobile !== value) {
            this._isMobile = value;
            this.requestUpdate('isMobile');
        }
    }
    /**
     * Gets or sets the `hasHeader` property.
     *
     * @public
     * @readonly
     * @attr
     */
    get hasHeader() {
        return this._hasHeader;
    }
    set hasHeader(value) {
        if (this._hasHeader !== value) {
            this._hasHeader = value;
            this.requestUpdate('isMobile');
        }
    }
    /**
     * Returns the `appHeaderElement` property.
     *
     * @hidden
     * @protected
     * @readonly
     */
    get header() {
        return this._headerElement;
    }
    /**
     * Returns the `contentElement` property.
     *
     * @hidden
     * @protected
     * @readonly
     */
    get content() {
        return this._contentElement;
    }
    // #endregion
    // #region Methods
    /**
     * Toggles the navigation drawer.
     *
     * @public
     */
    toggleNavigation() {
        this.isNavOpen = !this.isNavOpen;
    }
    /**
     * Opens the navigation drawer.
     *
     * @public
     */
    openNavigation() {
        this.isNavOpen = true;
    }
    /**
     * Closes the navigation drawer.
     *
     * @public
     */
    closeNavigation() {
        this.isNavOpen = false;
    }
    onSlotChanges(slotName) {
        if (slotName === 'header') {
            const headerElements = this.getSlotAssignments('header')
                .filter((x) => x instanceof AppHeaderElement);
            if (headerElements.length > 0) {
                this._headerElement = headerElements[0];
                this.hasHeader = true;
            }
            else {
                this.hasHeader = false;
            }
        }
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        this._contentElement = this.getTemplatePart('content');
        this._headerElement = this.getTemplatePart('header');
        this._drawerElement = this.getTemplatePart('drawer');
    }
    /**
     * @protected
     */
    onIsNavOpenPropertyChanged(_prev, next) {
        this._headerElement.isToggled = next ?? false;
    }
};
__decorate([
    Property({ type: Object }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], AppElement.prototype, "theme", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], AppElement.prototype, "isNavOpen", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], AppElement.prototype, "hasNav", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], AppElement.prototype, "isMobile", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], AppElement.prototype, "hasHeader", null);
__decorate([
    Watch('isNavOpen', { waitUntilFirstUpdate: true }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Boolean, Boolean]),
    __metadata("design:returntype", void 0)
], AppElement.prototype, "onIsNavOpenPropertyChanged", null);
AppElement = __decorate([
    Component({
        selector: 'mosaik-app',
        template: appElementTemplate,
        themes: {
            joy: appElementJoyStyle,
            memphis: appElementMemphisStyle,
            cosmopolitan: appElementCosmopolitanStyle
        },
        imports: [
            DrawerElement,
            AppHeaderElement,
            Theme2Element
        ]
    }),
    __metadata("design:paramtypes", [])
], AppElement);
export { AppElement };
//# sourceMappingURL=AppElement.js.map