// #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 { RendererServiceLocator } from '../../../../Dom/Renderer';
import { Emit } from '../../../../Events/Decorators/EmitDecorator';
import { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import { CssAspectRatio, CssLength } from '@breadstone/mosaik-themes';
import { Dimensionable } from '../../../Behaviors/Dimensionable';
import { Disableable } from '../../../Behaviors/Disableable';
import { Variantable } from '../../../Behaviors/Variantable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { ImageFit } from '../../../Types/ImageFit';
import { ImageLegendPosition } from '../../../Types/ImageLegendPosition';
import { CustomElement } from '../../Abstracts/CustomElement';
import { TextElement } from '../../Primitives/Text/TextElement';
import { ProgressRingElement } from '../../Ranges/ProgressRing/ProgressRingElement';
import { IconElement } from '../Icon/IconElement';
import { imageElementTemplate } from './ImageElementTemplate';
import { imageElementJoyStyle } from './Themes/ImageElement.Joy';
import { imageElementRetroStyle } from './Themes/ImageElement.Retro';
import { imageElementCosmopolitanStyle } from './Themes/ImageElement.Cosmopolitan';
import { Themeable } from '../../../Behaviors/Themeable';
// #endregion
/**
 * Image - A visual representation of a picture, illustration, or graphic.
 *
 * @element mosaik-image
 *
 * @slot - The default content slot.
 * @slot empty - The empty state slot.
 * @slot failed - The empty state slot.
 * @slot pending - The empty state slot.
 * @slot legend - The legend slot.
 *
 * @csspart image - The image part.
 * @csspart placeholder - The placeholder part.
 * @csspart legend - The legend part.
 * @csspart content - The content part.
 *
 * @fires loaded - Fired when the element is loaded.
 * @fires failed - Fired when the element is failed.
 *
 * @public
 */
let ImageElement = class ImageElement extends Themeable(Disableable(Variantable(Dimensionable(CustomElement)))) {
    // #region Fields
    _loaded;
    _failed;
    _alt;
    _src;
    _srcset;
    _state;
    _fit;
    _showFailed;
    _showEmpty;
    _showPending;
    _legend;
    _legendPosition;
    _ratio;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._alt = '';
        this._src = '';
        this._srcset = '';
        this._state = 'done';
        this._fit = ImageFit.Cover;
        this._showFailed = false;
        this._showEmpty = false;
        this._showPending = false;
        this._legend = '';
        this._legendPosition = ImageLegendPosition.None;
        this._ratio = 'auto';
        this._loaded = new HTMLElementEventEmitter(this, 'loaded');
        this._failed = new HTMLElementEventEmitter(this, 'failed');
    }
    // #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-image';
    }
    /**
     * Gets or sets the `alt` property.
     *
     * @public
     * @attr
     */
    get alt() {
        return this._alt;
    }
    set alt(value) {
        if (this._alt !== value) {
            this._alt = value;
            this.requestUpdate('alt');
        }
    }
    /**
     * Gets or sets the `src` property.
     *
     * @public
     * @attr
     */
    get src() {
        return this._src;
    }
    set src(value) {
        if (this._src !== value) {
            this._src = value;
            this.requestUpdate('src');
        }
    }
    /**
     * Gets or sets the `srcset` property.
     *
     * @public
     * @attr
     */
    get srcset() {
        return this._srcset;
    }
    set srcset(value) {
        if (this._srcset !== value) {
            this._srcset = value;
            this.requestUpdate('srcset');
        }
    }
    /**
     * Gets or sets the `showFailed` property.
     *
     * @public
     */
    get showFailed() {
        return this._showFailed;
    }
    set showFailed(value) {
        if (this._showFailed !== value) {
            this._showFailed = value;
            this.requestUpdate('showFailed');
        }
    }
    /**
     * Gets or sets the `showEmpty` property.
     *
     * @public
     */
    get showEmpty() {
        return this._showEmpty;
    }
    set showEmpty(value) {
        if (this._showEmpty !== value) {
            this._showEmpty = value;
            this.requestUpdate('showEmpty');
        }
    }
    /**
     * Gets or sets the `showEmpty` property.
     *
     * @public
     */
    get showPending() {
        return this._showPending;
    }
    set showPending(value) {
        if (this._showPending !== value) {
            this._showPending = value;
            this.requestUpdate('showPending');
        }
    }
    /**
     * Gets or sets the `fit` property.
     *
     * @public
     * @attr
     */
    get fit() {
        return this._fit;
    }
    set fit(value) {
        if (this._fit !== value) {
            this._fit = value;
            this.requestUpdate('fit');
        }
    }
    /**
     * Gets or sets the `legend` property.
     *
     * @public
     * @attr
     */
    get legend() {
        return this._legend;
    }
    set legend(value) {
        if (this._legend !== value) {
            this._legend = value;
            this.requestUpdate('legend');
        }
    }
    /**
     * Gets or sets the `legendPosition` property.
     *
     * @public
     * @attr
     */
    get legendPosition() {
        return this._legendPosition;
    }
    set legendPosition(value) {
        if (this._legendPosition !== value) {
            this._legendPosition = value;
            this.requestUpdate('legendPosition');
        }
    }
    /**
      * Returns the `state` property.
      *
      * @public
      * @readonly
      */
    get state() {
        return this._state;
    }
    set state(value) {
        if (this._state !== value) {
            this._state = value;
            this.requestUpdate('state');
        }
    }
    /**
     * Gets or sets the `ratio` property.
     *
     * @public
     * @attr
     */
    get ratio() {
        return this._ratio;
    }
    set ratio(value) {
        if (this._ratio !== value) {
            this._ratio = value;
            this.requestUpdate('ratio');
        }
    }
    /**
     * Called when the image is loaded.
     * Provides reference to `IEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get loaded() {
        return this._loaded;
    }
    /**
     * Called when the image load is failed.
     * Provides reference to `IEventDetail<ThisParameterType>` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get failed() {
        return this._failed;
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     */
    onWidthPropertyChanged(_prev, next) {
        RendererServiceLocator.current.setStyle(this, 'min-width', next);
        RendererServiceLocator.current.setStyle(this, 'width', next);
    }
    /**
     * @protected
     */
    onHeightPropertyChanged(_prev, next) {
        RendererServiceLocator.current.setStyle(this, 'min-height', next);
        RendererServiceLocator.current.setStyle(this, 'height', next);
    }
    /**
     * @protected
     */
    onRatioPropertyChanged(_prev, next) {
        if (next !== undefined) {
            RendererServiceLocator.current.setStyle(this, '--image-aspect-ratio', next);
        }
        else {
            RendererServiceLocator.current.removeStyle(this, '--image-aspect-ratio');
        }
    }
    /**
     * @template
     * @protected
     */
    onImageError() {
        this.state = 'failed';
        this._failed.emit();
    }
    /**
     * @template
     * @protected
     */
    onImageLoad() {
        this.state = 'done';
        this._loaded.emit();
    }
};
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "alt", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "src", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "srcset", null);
__decorate([
    Property({ type: Boolean }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], ImageElement.prototype, "showFailed", null);
__decorate([
    Property({ type: Boolean }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], ImageElement.prototype, "showEmpty", null);
__decorate([
    Property({ type: Boolean }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], ImageElement.prototype, "showPending", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "fit", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "legend", null);
__decorate([
    Attribute({ type: ImageLegendPosition }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "legendPosition", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "state", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ImageElement.prototype, "ratio", null);
__decorate([
    Emit(),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], ImageElement.prototype, "loaded", null);
__decorate([
    Emit(),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], ImageElement.prototype, "failed", null);
__decorate([
    Watch('width'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], ImageElement.prototype, "onWidthPropertyChanged", null);
__decorate([
    Watch('height'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], ImageElement.prototype, "onHeightPropertyChanged", null);
__decorate([
    Watch('ratio'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], ImageElement.prototype, "onRatioPropertyChanged", null);
ImageElement = __decorate([
    Component({
        selector: 'mosaik-image',
        template: imageElementTemplate,
        themes: {
            joy: imageElementJoyStyle,
            retro: imageElementRetroStyle,
            cosmopolitan: imageElementCosmopolitanStyle
        },
        imports: [
            TextElement,
            IconElement,
            ProgressRingElement
        ]
    }),
    __metadata("design:paramtypes", [])
], ImageElement);
export { ImageElement };
//# sourceMappingURL=ImageElement.js.map