// #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';
// #endregion
/**
 * App - A container component that manages the layout and structure of the application, typically including
 *       navigation drawers, headers, and main content areas.
 *
 * @description
 * The App component provides a wrapper for the main layout of an application. It includes support for navigation
 * drawers, headers, and a content area, allowing for a consistent and customizable structure. This component is useful
 * for applications that require a flexible layout with integrated navigation and content management.
 *
 * @name App
 * @element mosaik-app
 * @category Shell
 *
 * @csspart header - The header section of the App, often used for titles or app branding.
 * @csspart content - The main content area of the App.
 * @csspart drawer - The part of the App responsible for the navigation drawer.
 * @csspart nav - The navigation part of the App, used for placing navigation links or menus.
 *
 * @dependency {DrawerElement} - The Drawer element used for navigation.
 * @dependency {AppHeaderElement} - The App Header element for displaying the application header.
 * @dependency {Theme2Element} - The Theme element for applying theming and styling.
 *
 * @slot nav - The slot for navigation elements.
 * @slot menu - The slot for menu items.
 * @slot logo - The slot for the application logo or branding.
 * @slot actions - The slot for action buttons or icons.
 * @slot content - The main content area of the App.
 * @slot footer - The footer area of the App, typically used for additional information or links.
 *
 * @example
 * ```html
 * <mosaik-app>
 *   <div slot="nav">
 *   </div>
 *   <div slot="menu">
 *   </div>
 *   <div slot="logo">
 *   </div>
 *   <div slot="actions">
 *   </div>
 *   <div slot="content">
 *     <!-- Main content area here -->
 *   </div>
 *   <div slot="footer">
 *     <!-- Footer content here -->
 *   </div>
 * </mosaik-app>
 * ```
 *
 * @public
 */
let AppElement = class AppElement extends Themeable(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)) {
            // if (value) {
            //     value = Observable.observe(value, (next) => {
            //         this.applyTheme(next);
            //     });
            // }
            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._isNavOpen;
    }
    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 `drawerElement` property.
     *
     * @hidden
     * @protected
     * @readonly
     */
    get drawer() {
        return this._drawerElement;
    }
    /**
     * 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
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        this._contentElement = this.getTemplatePart('content');
        this._headerElement = this.getTemplatePart('header');
        this._drawerElement = this.getTemplatePart('drawer');
    }
};
__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);
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