// #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 { Disableable } from '../../../Behaviors/Disableable';
import { TextFormattable } from '../../../Behaviors/TextFormattable';
import { Themeable } from '../../../Behaviors/Themeable';
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 { TextAlignment } from '../../../Types/TextAlignment';
import { CustomElement } from '../../Abstracts/CustomElement';
import { textElementTemplate } from './TextElementTemplate';
import { textElementCosmopolitanStyle } from './Themes/TextElement.Cosmopolitan';
import { textElementJoyStyle } from './Themes/TextElement.Joy';
import { textElementMemphisStyle } from './Themes/TextElement.Memphis';
// #endregion
/**
 * Text - A fundamental typography component for displaying formatted text content with comprehensive styling options.
 *
 * @description
 * The Text component is a foundational typography element that provides flexible text rendering with
 * built-in formatting capabilities, semantic variant support, and extensive customization options.
 * It serves as the primary text display component across the design system, supporting semantic text
 * roles through variants (headline, title, body, caption), horizontal text alignment (left, center,
 * right, justify), text formatting functions for currency, dates, and custom transformations, and
 * advanced features like truncation, line clamping, and text marking/highlighting. The component
 * integrates deeply with the Variantable, Disableable, TextFormattable, and Themeable behaviors to
 * provide consistent typography across different contexts while maintaining accessibility through
 * proper ARIA roles and semantic HTML structure.
 *
 * @name Text
 * @element mosaik-text
 * @category Primitives
 *
 * @slot text - Primary text content area for displaying formatted text
 *
 * @csspart text - The paragraph element containing the text content
 *
 * @cssprop {String} --text-background-color - The background color of the text container
 * @cssprop {String} --text-border-color - The border color of the text container
 * @cssprop {String} --text-border-radius - The border radius for text container styling
 * @cssprop {String} --text-border-style - The border style for text container
 * @cssprop {String} --text-border-width - The border width for text container
 * @cssprop {String} --text-font-decoration - The text decoration style (underline, line-through, etc.)
 * @cssprop {String} --text-font-family - The font family for text content
 * @cssprop {String} --text-font-letter-spacing - The letter spacing for text content
 * @cssprop {String} --text-font-line-height - The line height for text content
 * @cssprop {String} --text-font-size - The font size for text content
 * @cssprop {String} --text-font-text-decoration - The font text decoration CSS custom property.
 * @cssprop {String} --text-font-text-transform - The font text transform CSS custom property.
 * @cssprop {String} --text-font-transform - The text transformation (uppercase, lowercase, capitalize)
 * @cssprop {String} --text-font-weight - The font weight for text content
 * @cssprop {String} --text-foreground-color - The text color for primary content
 * @cssprop {String} --text-gap - The gap between text elements when multiple
 * @cssprop {String} --text-padding-bottom - The bottom padding for text container
 * @cssprop {String} --text-padding-left - The left padding for text container
 * @cssprop {String} --text-padding-right - The right padding for text container
 * @cssprop {String} --text-padding-top - The top padding for text container
 * @cssprop {String} --text-shadow - The text shadow effect for enhanced visibility
 * @cssprop {String} --text-shadow-blur - The shadow blur CSS custom property.
 * @cssprop {String} --text-shadow-color - The shadow color CSS custom property.
 * @cssprop {String} --text-shadow-offset-x - The shadow offset x CSS custom property.
 * @cssprop {String} --text-shadow-offset-y - The shadow offset y CSS custom property.
 * @cssprop {String} --text-shadow-spread - The shadow spread CSS custom property.
 * @cssprop {String} --text-transition-duration - The animation duration for text changes
 * @cssprop {String} --text-transition-mode - The animation easing mode for text transitions
 * @cssprop {String} --text-transition-property - The CSS properties to animate during transitions
 * @cssprop {String} --text-translate - The translate CSS custom property.
 *
 * @example
 * Basic text content:
 * ```html
 * <mosaik-text>Welcome to our application</mosaik-text>
 * ```
 *
 * @example
 * Text with alignment and variant:
 * ```html
 * <mosaik-text variant="primary" alignment="center">
 *   Centered primary text
 * </mosaik-text>
 * ```
 *
 * @public
 */
let TextElement = class TextElement extends Themeable(Variantable(Disableable(TextFormattable(CustomElement)))) {
    // #region Fields
    _text;
    _truncate;
    _wrap;
    _maxLength;
    _maxLines;
    _readonly;
    _alignment;
    _marker;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `TextElement` class.
     *
     * @public
     */
    constructor() {
        super();
        this._text = {
            rawValue: '',
            value: ''
        };
        this._truncate = false;
        this._wrap = false;
        this._maxLength = null;
        this._maxLines = null;
        this._readonly = false;
        this._alignment = TextAlignment.Left;
        this._marker = null;
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     *
     * @public
     * @static
     * @readonly
    */
    static get is() {
        return 'mosaik-text';
    }
    /**
     * Gets or sets the `text` property.
     *
     * @public
     */
    get text() {
        return this._text.value;
    }
    set text(value) {
        if (this._text.rawValue !== value) {
            this._text.rawValue = value ?? '';
            this.requestUpdate('text');
        }
    }
    /**
     * Gets or sets the `truncate` property.
     *
     * @public
     * @attr
     */
    get truncate() {
        return this._truncate;
    }
    set truncate(value) {
        if (this._truncate !== value) {
            this._truncate = value;
            this.requestUpdate('truncate');
        }
    }
    /**
     * Gets or sets the `wrap` property.
     *
     * @public
     * @attr
     */
    get wrap() {
        return this._wrap;
    }
    set wrap(value) {
        if (this._wrap !== value) {
            this._wrap = value;
            this.requestUpdate('wrap');
        }
    }
    /**
     * Gets or sets the `maxLength` property.
     *
     * @public
     * @attr
     */
    get maxLength() {
        return this._maxLength;
    }
    set maxLength(value) {
        if (this._maxLength !== value) {
            this._maxLength = value;
            this.requestUpdate('maxLength');
        }
    }
    /**
     * Gets or sets the `maxLines` property.
     *
     * @public
     * @attr
     */
    get maxLines() {
        return this._maxLines;
    }
    set maxLines(value) {
        if (this._maxLines !== value) {
            this._maxLines = value;
            this.requestUpdate('maxLines');
        }
    }
    /**
     * Gets or sets the `readonly` property.
     *
     * @public
     * @attr
     */
    get readonly() {
        return this._readonly;
    }
    set readonly(value) {
        if (this._readonly !== value) {
            this._readonly = value;
            this.requestUpdate('readonly');
        }
    }
    /**
     * Gets or sets the `alignment` property.
     *
     * Possible values are:
     * * `center` - centers the text horizontally within the element
     * * `justify` - stretches the text to fill the width of the element, adjusting spacing as needed
     * * `left` - aligns the text to the left edge of the element (default)
     * * `right` - aligns the text to the right edge of the element
     *
     * @public
     * @attr
     */
    get alignment() {
        return this._alignment;
    }
    set alignment(value) {
        if (this._alignment !== value) {
            this._alignment = value;
            this.requestUpdate('alignment');
        }
    }
    /**
     * Gets or sets the `marker` property.
     *
     * @public
     * @attr
     */
    get marker() {
        return this._marker;
    }
    set marker(value) {
        if (this._marker !== value) {
            this._marker = value;
            this.requestUpdate('marker');
        }
    }
    // #endregion
    // #region Methods
    /**
     * Mark the `text` by the given `value`. If the value is a boolean `true`, the text will be marked completely.
     *
     * @public
     */
    mark(value) {
        if (typeof value === 'boolean') {
            this.text = `<mark part="marker">${this._text.value}</mark>`;
        }
        else {
            this.text = this._text.value.replace(new RegExp(value, 'gi'), '<mark part="marker">$&</mark>');
        }
    }
    /**
     * Trim the `text` by the given `maxLength`.
     *
     * @template
     * @private
     */
    tryTrim() {
        if (!this._text.rawValue) {
            return '';
        }
        if (this._maxLength === null) {
            return this._text.value;
        }
        if (this.formatter) {
            const text = this._text.value;
            const truncatedText = this._maxLength === undefined || this._maxLength === null
                ? text
                : text.substring(0, this._maxLength);
            // Check for incomplete HTML tags at the end
            const match = (/<[^>]*$/).exec(truncatedText);
            if (match) {
                // If there's an incomplete HTML tag, remove it to maintain valid HTML structure
                return truncatedText.substring(0, truncatedText.lastIndexOf(match[0]));
            }
        }
        const text = this._text.value;
        return this._maxLength === undefined || this._maxLength === null
            ? text
            : text.length <= this._maxLength
                ? text
                : text.substring(0, this._maxLength).trim();
    }
    /**
     * @protected
     */
    onTextPropertyChanged(_prev, _next) {
        const fn = this.formatter;
        this._text.value = this.formatter
            ? fn(this._text.rawValue)
            : this._text.rawValue;
    }
    /**
     * @protected
     */
    onFormatterPropertyChanged(_prev, next) {
        if (next) {
            const fn = next;
            this._text.value = fn(this._text.rawValue);
        }
    }
    /**
     * @protected
     */
    onMarkerPropertyChanged(_prev, next) {
        if (next === null || next === undefined || next === false) {
            // unmark, if it is marked
            const isMarked = (/<mark part="marker">(.*?)<\/mark>/gi).test(this._text.value);
            if (!isMarked) {
                return;
            }
            this.text = this._text.value.replace(/<mark part="marker">(.*?)<\/mark>/gi, '$1');
            return;
        }
        this.mark(next);
    }
};
__decorate([
    Property({ type: String }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], TextElement.prototype, "text", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], TextElement.prototype, "truncate", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], TextElement.prototype, "wrap", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], TextElement.prototype, "maxLength", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], TextElement.prototype, "maxLines", null);
__decorate([
    Attribute({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], TextElement.prototype, "readonly", null);
__decorate([
    Attribute({ type: TextAlignment }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], TextElement.prototype, "alignment", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], TextElement.prototype, "marker", null);
__decorate([
    Watch('text'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String]),
    __metadata("design:returntype", void 0)
], TextElement.prototype, "onTextPropertyChanged", null);
__decorate([
    Watch('formatter'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], TextElement.prototype, "onFormatterPropertyChanged", null);
__decorate([
    Watch('marker'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object, Object]),
    __metadata("design:returntype", void 0)
], TextElement.prototype, "onMarkerPropertyChanged", null);
TextElement = __decorate([
    Component({
        selector: 'mosaik-text',
        template: textElementTemplate,
        themes: {
            joy: textElementJoyStyle,
            memphis: textElementMemphisStyle,
            cosmopolitan: textElementCosmopolitanStyle
        },
        host: {
            role: 'text'
        },
        imports: []
    }),
    __metadata("design:paramtypes", [])
], TextElement);
export { TextElement };
//# sourceMappingURL=TextElement.js.map