// #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 QrCreator from 'qr-creator';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { QRErrorCorrection } from '../../../Types/QRErrorCorrection';
import { CustomElement } from '../../Abstracts/CustomElement';
import { qrCodeElementTemplate } from './QRCodeElementTemplate';
import { qrCodeElementJoyStyle } from './Themes/QRCodeElement.Joy';
import { qrCodeElementRetroStyle } from './Themes/QRCodeElement.Retro';
import { qrCodeElementCosmopolitanStyle } from './Themes/QRCodeElement.Cosmopolitan';
import { Themeable } from '../../../Behaviors/Themeable';
// #endregion
/**
 * The `{@link QRCodeElement}` element.
 *
 * @public
 */
let QRCodeElement = class QRCodeElement extends Themeable(CustomElement) {
    // #region Fields
    _canvas;
    _text;
    _radius;
    _dimension;
    _errorCorrection;
    _backgroundColor;
    _foregroundColor;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._text = '';
        this._radius = 0;
        this._dimension = 200;
        this._errorCorrection = QRErrorCorrection.H;
        this._backgroundColor = null;
        this._foregroundColor = null;
    }
    // #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-qrcode';
    }
    /**
     * Gets or sets the `text` property.
     *
     * @public
     */
    get text() {
        return this._text;
    }
    set text(value) {
        if (this._text !== value) {
            this._text = value;
            this.requestUpdate('text');
        }
    }
    /**
     * Gets or sets the `radius` property.
     *
     * @public
     */
    get radius() {
        return this._radius;
    }
    set radius(value) {
        if (this._radius !== value) {
            this._radius = value;
            this.requestUpdate('radius');
        }
    }
    /**
     * Gets or sets the `dimension` property.
     *
     * @public
     */
    get dimension() {
        return this._dimension;
    }
    set dimension(value) {
        if (this._dimension !== value) {
            this._dimension = value;
            this.requestUpdate('dimension');
        }
    }
    /**
     * Gets or sets the `errorCorrection` property.
     *
     * @public
     * @attr
     */
    get errorCorrection() {
        return this._errorCorrection;
    }
    set errorCorrection(value) {
        if (this._errorCorrection !== value) {
            this._errorCorrection = value;
            this.requestUpdate('errorCorrection');
        }
    }
    /**
     * Gets or sets the `backgroundColor` property of the QR code.
     * If not set (`null` or `undefind`), the background color will respect the CSS variable `--qr-code-background-color`.
     *
     * @public
     * @attr
     */
    get backgroundColor() {
        return this._backgroundColor;
    }
    set backgroundColor(value) {
        if (this._backgroundColor !== value) {
            this._backgroundColor = value;
            this.requestUpdate('backgroundColor');
        }
    }
    /**
     * Gets or sets the `foregroundColor` property of the QR code.
     * If not set (`null` or `undefind`), the fill color will respect the CSS variable `--qr-code-foreground-color`.
     *
     * @public
     * @attr
     */
    get foregroundColor() {
        return this._foregroundColor;
    }
    set foregroundColor(value) {
        if (this._foregroundColor !== value) {
            this._foregroundColor = value;
            this.requestUpdate('foregroundColor');
        }
    }
    // #endregion
    // #region Methods
    /**
     * Returns qr code image as data URL (see https://mdn.io/todataurl for the list of possible paramters).
     *
     * @public
     */
    toDataURL(imageType, quality) {
        // save image as data URL
        return this._canvas.toDataURL(imageType, quality);
    }
    /**
     * Returns qr code image as data URL trimmed from white space.
     *
     * @public
     */
    toBlob() {
        return this.dataURLToBlob(this._canvas.toDataURL());
    }
    /**
     * @protected
     * @override
     */
    onApplyTemplate() {
        super.onApplyTemplate();
        this._canvas = this.getTemplatePart('canvas');
        this.invalidate();
    }
    /**
     * @protected
     */
    onTextPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @protected
     */
    onRadiusPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @protected
     */
    onDimensionPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @protected
     */
    onErrorCorrectionPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @protected
     */
    onBackgroundColorPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @protected
     */
    onForegroundColorPropertyChanged(_prev, _next) {
        if (!this.hasUpdated) {
            return;
        }
        this.invalidate();
    }
    /**
     * @private
     */
    invalidate() {
        const backgroundColor = this._backgroundColor ?? this.computedStyleMap().get('--qr-code-background-color')
            ?.toString() ?? '';
        const foregroundColor = this._foregroundColor ?? this.computedStyleMap().get('--qr-code-foreground-color')
            ?.toString() ?? '';
        QrCreator.render({
            fill: foregroundColor,
            background: backgroundColor,
            text: this._text,
            radius: this._radius,
            ecLevel: this._errorCorrection,
            size: this._dimension * 2
        }, this._canvas);
    }
    /**
     * @private
     */
    dataURLToBlob(dataURL) {
        const parts = dataURL.split(',');
        if (parts.length !== 2) {
            const mimeType = (parts.at(0) ?? '').split(':')[1] ?? '';
            const b64 = atob(parts.at(1) ?? '');
            let n = b64.length;
            const u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = b64.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mimeType });
        }
        return new Blob();
    }
};
__decorate([
    Property({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], QRCodeElement.prototype, "text", null);
__decorate([
    Property({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], QRCodeElement.prototype, "radius", null);
__decorate([
    Property({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], QRCodeElement.prototype, "dimension", null);
__decorate([
    Attribute({ type: QRErrorCorrection }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], QRCodeElement.prototype, "errorCorrection", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], QRCodeElement.prototype, "backgroundColor", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], QRCodeElement.prototype, "foregroundColor", null);
__decorate([
    Watch('text'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onTextPropertyChanged", null);
__decorate([
    Watch('radius'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Number, Number]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onRadiusPropertyChanged", null);
__decorate([
    Watch('dimension'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Number, Number]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onDimensionPropertyChanged", null);
__decorate([
    Watch('errorCorrection'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onErrorCorrectionPropertyChanged", null);
__decorate([
    Watch('backgroundColor'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onBackgroundColorPropertyChanged", null);
__decorate([
    Watch('foregroundColor'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], QRCodeElement.prototype, "onForegroundColorPropertyChanged", null);
QRCodeElement = __decorate([
    Component({
        selector: 'mosaik-qrcode',
        template: qrCodeElementTemplate,
        themes: {
            joy: qrCodeElementJoyStyle,
            retro: qrCodeElementRetroStyle,
            cosmopolitan: qrCodeElementCosmopolitanStyle
        },
        imports: []
    }),
    __metadata("design:paramtypes", [])
], QRCodeElement);
export { QRCodeElement };
//# sourceMappingURL=QRCodeElement.js.map