// #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 { BreakpointAlias } from '../../../Layout/Breakpoint/BreakpointAlias';
import { BreakpointController } from '../../../Layout/Breakpoint/BreakpointController';
import { Theme2Element } from '../../../Theming/Theme2Element';
import { Attribute } from '../../Decorators/AttributeDecorator';
import { Component } from '../../Decorators/ComponentDecorator';
import { CustomElement } from '../Abstracts/CustomElement';
import { DrawerElement } from '../Overlays/Drawer/DrawerElement';
import { appElementTemplate } from './AppElementTemplate';
import { AppHeaderElement } from './AppHeaderElement';
import { appElementJoyStyle } from './Themes/AppElement.Joy';
import { appElementRetroStyle } from './Themes/AppElement.Retro';
import { appElementCosmopolitanStyle } from './Themes/AppElement.Cosmopolitan';
import { Themeable } from '../../Behaviors/Themeable';
import { Property } from '../../Decorators/PropertyDecorator';
import { Equals } from '../../../Equality/Equals';
import { Slottable } from '../../Behaviors/Slottable';
import { Watch } from '../../Decorators/WatchDecorator';
// #endregion
/**
 * App - A comprehensive application shell component that provides the foundation layout structure for modern web applications.
 *
 * 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 nav - Navigation drawer content area for primary navigation links and menu items
 * @slot menu - Menu area for contextual actions and secondary navigation
 * @slot logo - Application branding area for logos, titles, and identity elements
 * @slot actions - Action buttons area for global application actions and controls
 * @slot content - Main content area for primary application content and views
 * @slot footer - Footer area for secondary information, links, and application metadata
 *
 * @csspart header - Application header section containing branding and navigation controls
 * @csspart content - Main content wrapper for application views and functionality
 * @csspart drawer - Navigation drawer container for side navigation elements
 * @csspart nav - Navigation area within the drawer for menu items and links
 * @csspart overlay - Drawer overlay for mobile and responsive interactions
 * @csspart backdrop - Background overlay for modal drawer interactions
 *
 * @cssprop --app-header-height - Height of the application header bar
 * @cssprop --app-drawer-width - Width of the navigation drawer when expanded
 * @cssprop --app-breakpoint-mobile - Mobile breakpoint threshold for responsive behavior
 * @cssprop --app-breakpoint-tablet - Tablet breakpoint threshold for layout changes
 * @cssprop --app-breakpoint-desktop - Desktop breakpoint for full layout display
 * @cssprop --app-background-color - Background color for the application shell
 * @cssprop --app-surface-color - Surface color for elevated application areas
 * @cssprop --app-drawer-background - Background color for the navigation drawer
 * @cssprop --app-header-background - Background color for the application header
 *
 * @dependency DrawerElement - For navigation drawer functionality and responsive behavior
 * @dependency AppHeaderElement - For application header management and branding display
 * @dependency Theme2Element - For comprehensive theme management and styling coordination
 * @dependency BreakpointController - For responsive design and layout adaptation
 *
 * @example
 * ```html
 * <!-- Complete application shell -->
 * <mosaik-app theme="joy" responsive="true">
 *   <mosaik-icon slot="logo" data="company-logo"></mosaik-icon>
 *   <mosaik-text slot="logo">My Application</mosaik-text>
 *
 *   <nav slot="nav">
 *     <mosaik-list>
 *       <mosaik-list-item value="dashboard">
 *         <mosaik-icon slot="prefix" data="home"></mosaik-icon>
 *         Dashboard
 *       </mosaik-list-item>
 *       <mosaik-list-item value="analytics">
 *         <mosaik-icon slot="prefix" data="chart-bar"></mosaik-icon>
 *         Analytics
 *       </mosaik-list-item>
 *       <mosaik-list-item value="settings">
 *         <mosaik-icon slot="prefix" data="cog"></mosaik-icon>
 *         Settings
 *       </mosaik-list-item>
 *     </mosaik-list>
 *   </nav>
 *
 *   <div slot="actions">
 *     <mosaik-button appearance="ghost" onclick="openSearch()">
 *       <mosaik-icon data="search"></mosaik-icon>
 *     </mosaik-button>
 *     <mosaik-button appearance="ghost" onclick="showNotifications()">
 *       <mosaik-icon data="bell"></mosaik-icon>
 *       <mosaik-badge slot="overlay" value="3"></mosaik-badge>
 *     </mosaik-button>
 *     <mosaik-avatar onclick="showProfile()" src="user-avatar.jpg"></mosaik-avatar>
 *   </div>
 *
 *   <main slot="content">
 *     <router-outlet></router-outlet>
 *   </main>
 *
 *   <footer slot="footer">
 *     <mosaik-text variant="caption">© 2024 My Company. All rights reserved.</mosaik-text>
 *   </footer>
 * </mosaik-app>
 *
 * <!-- Minimal app shell -->
 * <mosaik-app drawer-mode="overlay">
 *   <h1 slot="logo">Simple App</h1>
 *   <div slot="content">
 *     <h2>Welcome to the application</h2>
 *   </div>
 * </mosaik-app>
 *
 * <!-- Dashboard layout -->
 * <mosaik-app theme="cosmopolitan" drawer-collapsed="false">
 *   <div slot="logo">
 *     <img src="logo.png" alt="Dashboard" />
 *   </div>
 *
 *   <div slot="menu">
 *     <mosaik-combo label="Workspace" value="current">
 *       <mosaik-combo-item value="current">Current Project</mosaik-combo-item>
 *       <mosaik-combo-item value="archived">Archived Projects</mosaik-combo-item>
 *     </mosaik-combo>
 *   </div>
 *
 *   <div slot="content">
 *     <mosaik-chart type="line" title="Performance Metrics"></mosaik-chart>
 *   </div>
 * </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 `{@link is}` property.
     * The `{@link 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,
            retro: appElementRetroStyle,
            cosmopolitan: appElementCosmopolitanStyle
        },
        imports: [
            DrawerElement,
            AppHeaderElement,
            Theme2Element
        ]
    }),
    __metadata("design:paramtypes", [])
], AppElement);
export { AppElement };
//# sourceMappingURL=AppElement.js.map