// #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);
};
var ColorEditorInputsElement_1;
import { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import chroma from 'chroma-js';
import { Emit } from '../../../../events/Decorators/EmitDecorator';
import { Disableable } from '../../../Behaviors/Disableable';
import { Focusable } from '../../../Behaviors/Focusable';
import { Sizeable } from '../../../Behaviors/Sizeable';
import { Themeable } from '../../../Behaviors/Themeable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Property } from '../../../Decorators/PropertyDecorator';
import { CustomElement } from '../../Abstracts/CustomElement';
import { ButtonElement } from '../../Buttons/Button/ButtonElement';
import { ButtonGroupElement } from '../../Buttons/Button/ButtonGroupElement';
import { NumberBoxElement } from '../../Inputs/NumberBox/NumberBoxElement';
import { TextBoxElement } from '../../Inputs/TextBox/TextBoxElement';
import { colorEditorInputsElementTemplate } from './ColorEditorInputsElementTemplate';
import { colorEditorInputsElementCosmopolitanStyle } from './Themes/ColorEditorInputsElement.Cosmopolitan';
import { colorEditorInputsElementJoyStyle } from './Themes/ColorEditorInputsElement.Joy';
import { colorEditorInputsElementMemphisStyle } from './Themes/ColorEditorInputsElement.Memphis';
// #endregion
/**
 * Color Editor Inputs - Input fields for editing color values in various formats.
 *
 * @description
 * The Color Editor Inputs component provides text input fields for editing color values
 * in different formats (HEX, RGB, HSL, HSV). Users can toggle between formats using
 * a format switcher button. The component automatically validates and converts values
 * between formats.
 *
 * @name ColorEditorInputs
 * @element mosaik-color-editor-inputs
 * @category Media
 *
 * @csspart input - The text input fields
 * @csspart input-group - Container for each input field and its label
 * @csspart next - The next part.
 * @csspart previous - The previous part.
 *
 * @cssprop {String} --color-editor-inputs-background-color - The editor inputs background color CSS custom property.
 * @cssprop {String} --color-editor-inputs-border-color - The editor inputs border color CSS custom property.
 * @cssprop {String} --color-editor-inputs-border-radius - The editor inputs border radius CSS custom property.
 * @cssprop {String} --color-editor-inputs-border-style - The editor inputs border style CSS custom property.
 * @cssprop {String} --color-editor-inputs-border-width - The editor inputs border width CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-family - The editor inputs font family CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-letter-spacing - The editor inputs font letter spacing CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-line-height - The editor inputs font line height CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-size - The editor inputs font size CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-text-decoration - The editor inputs font text decoration CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-text-transform - The editor inputs font text transform CSS custom property.
 * @cssprop {String} --color-editor-inputs-font-weight - The editor inputs font weight CSS custom property.
 * @cssprop {String} --color-editor-inputs-foreground-color - The editor inputs foreground color CSS custom property.
 * @cssprop {String} --color-editor-inputs-gap - The editor inputs gap CSS custom property.
 * @cssprop {String} --color-editor-inputs-height - The editor inputs height CSS custom property.
 * @cssprop {String} --color-editor-inputs-input-background-color - The editor inputs input background color CSS custom property.
 * @cssprop {String} --color-editor-inputs-input-border-color - The editor inputs input border color CSS custom property.
 * @cssprop {String} --color-editor-inputs-input-border-radius - The editor inputs input border radius CSS custom property.
 * @cssprop {String} --color-editor-inputs-input-border-width - The editor inputs input border width CSS custom property.
 * @cssprop {String} --color-editor-inputs-input-height - The editor inputs input height CSS custom property.
 * @cssprop {String} --color-editor-inputs-label-color - The editor inputs label color CSS custom property.
 * @cssprop {String} --color-editor-inputs-label-font-size - The editor inputs label font size CSS custom property.
 * @cssprop {String} --color-editor-inputs-padding-bottom - The editor inputs padding bottom CSS custom property.
 * @cssprop {String} --color-editor-inputs-padding-left - The editor inputs padding left CSS custom property.
 * @cssprop {String} --color-editor-inputs-padding-right - The editor inputs padding right CSS custom property.
 * @cssprop {String} --color-editor-inputs-padding-top - The editor inputs padding top CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow - The editor inputs shadow CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow-blur - The editor inputs shadow blur CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow-color - The editor inputs shadow color CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow-offset-x - The editor inputs shadow offset x CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow-offset-y - The editor inputs shadow offset y CSS custom property.
 * @cssprop {String} --color-editor-inputs-shadow-spread - The editor inputs shadow spread CSS custom property.
 * @cssprop {String} --color-editor-inputs-transition-duration - The editor inputs transition duration CSS custom property.
 * @cssprop {String} --color-editor-inputs-transition-mode - The editor inputs transition mode CSS custom property.
 * @cssprop {String} --color-editor-inputs-transition-property - The editor inputs transition property CSS custom property.
 * @cssprop {String} --color-editor-inputs-translate - The editor inputs translate CSS custom property.
 * @cssprop {String} --color-editor-inputs-width - The editor inputs width CSS custom property.
 *
 * @fires colorChanged {ColorChangedEvent} - Fired when the color value changes via user input
 * @fires colorFormatChanged {ColorFormatChangedEvent} - Fired when the color format is changed
 *
 * @dependency mosaik-button - The Button element.
 * @dependency mosaik-button-group - The Button Group element.
 * @dependency mosaik-numberbox - The Numberbox element.
 * @dependency mosaik-textbox - The Textbox element.
 *
 * @example
 * Basic usage:
 * ```html
 * <mosaik-color-editor-inputs></mosaik-color-editor-inputs>
 * ```
 *
 * @example
 * With initial color and format:
 * ```html
 * <mosaik-color-editor-inputs color="#ff0000" format="rgb"></mosaik-color-editor-inputs>
 * ```
 *
 * @public
 */
let ColorEditorInputsElement = class ColorEditorInputsElement extends Themeable(Disableable(Focusable(Sizeable(CustomElement)))) {
    static { ColorEditorInputsElement_1 = this; }
    // #region Fields
    static _formatCycle = ['hex', 'rgb', 'hsl', 'hsv', 'lab', 'lch', 'oklab', 'oklch'];
    _colorChanged;
    _colorFormatChanged;
    _color;
    _format;
    _showAlpha;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the ColorEditorInputsElement class.
     *
     * @public
     */
    constructor() {
        super();
        this._colorChanged = new HTMLElementEventEmitter(this, 'colorChanged');
        this._colorFormatChanged = new HTMLElementEventEmitter(this, 'colorFormatChanged');
        this._color = '#ff0000';
        this._format = 'hex';
        this._showAlpha = true;
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `is` property.
     * The `is` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-color-editor-inputs';
    }
    /**
     * Gets or sets the color value.
     *
     * @public
     * @attr
     */
    get color() {
        return this._color;
    }
    set color(value) {
        if (this._color !== value) {
            this._color = value;
            this.requestUpdate('color');
        }
    }
    /**
     * Gets or sets the color format to display.
     *
     * @public
     * @attr
     */
    get format() {
        return this._format;
    }
    set format(value) {
        if (this._format !== value) {
            this._format = value;
            this.requestUpdate('format');
        }
    }
    /**
     * Gets or sets whether to show the alpha input.
     *
     * @public
     */
    get showAlpha() {
        return this._showAlpha;
    }
    set showAlpha(value) {
        if (this._showAlpha !== value) {
            this._showAlpha = value;
            this.requestUpdate('showAlpha');
        }
    }
    /**
     * Called when the color value changes via user input.
     * Provides reference to `IColorChangedEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get colorChanged() {
        return this._colorChanged;
    }
    /**
     * Called when the color format is changed.
     * Provides reference to `IColorFormatChangedEventDetail` as event detail.
     *
     * @public
     * @readonly
     * @eventProperty
     */
    get colorFormatChanged() {
        return this._colorFormatChanged;
    }
    // #endregion
    // #region Methods
    /**
     * Navigates to the previous color format in the cycle.
     *
     * @public
     */
    previousFormat() {
        const currentIndex = ColorEditorInputsElement_1._formatCycle.indexOf(this._format);
        const previousIndex = (currentIndex - 1 + ColorEditorInputsElement_1._formatCycle.length) % ColorEditorInputsElement_1._formatCycle.length;
        this.format = ColorEditorInputsElement_1._formatCycle[previousIndex];
        this._colorFormatChanged.emit({
            format: this._format
        });
    }
    /**
     * Navigates to the next color format in the cycle.
     *
     * @public
     */
    nextFormat() {
        const currentIndex = ColorEditorInputsElement_1._formatCycle.indexOf(this._format);
        const nextIndex = (currentIndex + 1) % ColorEditorInputsElement_1._formatCycle.length;
        this.format = ColorEditorInputsElement_1._formatCycle[nextIndex];
        this._colorFormatChanged.emit({
            format: this._format
        });
    }
    /**
     * Handles HEX input changes.
     *
     * @private
     */
    onHexChange(event) {
        const input = event.target;
        let hex = input.value.trim();
        if (!hex.startsWith('#')) {
            hex = '#' + hex;
        }
        try {
            const chromaColor = chroma(hex);
            const currentAlpha = chroma(this._color).alpha();
            this.color = chromaColor.alpha(currentAlpha).css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch {
            // Invalid hex, don't update
        }
    }
    /**
     * Handles alpha input changes.
     *
     * @private
     */
    onAlphaChange(event) {
        const input = event.target;
        const alpha = Math.max(0, Math.min(100, parseInt(input.value, 10) || 0)) / 100;
        try {
            const chromaColor = chroma(this._color).alpha(alpha);
            this.color = chromaColor.css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles RGB input changes.
     *
     * @private
     */
    onRgbChange(event, channel) {
        const input = event.target;
        const value = Math.max(0, Math.min(255, parseInt(input.value, 10) || 0));
        try {
            const chromaColor = chroma(this._color);
            const [r, g, b] = chromaColor.rgb();
            const a = chromaColor.alpha();
            const newRgb = {
                r,
                g,
                b
            };
            newRgb[channel] = value;
            this.color = chroma(newRgb.r, newRgb.g, newRgb.b).alpha(a)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles HSL input changes.
     *
     * @private
     */
    onHslChange(event, channel) {
        const input = event.target;
        let value = parseInt(input.value, 10) || 0;
        if (channel === 'h') {
            value = Math.max(0, Math.min(360, value));
        }
        else {
            value = Math.max(0, Math.min(100, value)) / 100;
        }
        try {
            const chromaColor = chroma(this._color);
            let [h, s, l] = chromaColor.hsl();
            const a = chromaColor.alpha();
            h = isNaN(h) ? 0 : h;
            if (channel === 'h') {
                h = value;
            }
            else if (channel === 's') {
                s = value;
            }
            else {
                l = value;
            }
            this.color = chroma.hsl(h, s, l).alpha(a)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles HSV input changes.
     *
     * @private
     */
    onHsvChange(event, channel) {
        const input = event.target;
        let value = parseInt(input.value, 10) || 0;
        if (channel === 'h') {
            value = Math.max(0, Math.min(360, value));
        }
        else {
            value = Math.max(0, Math.min(100, value)) / 100;
        }
        try {
            const chromaColor = chroma(this._color);
            let [h, s, v] = chromaColor.hsv();
            const a = chromaColor.alpha();
            h = isNaN(h) ? 0 : h;
            if (channel === 'h') {
                h = value;
            }
            else if (channel === 's') {
                s = value;
            }
            else {
                v = value;
            }
            this.color = chroma.hsv(h, s, v).alpha(a)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles LAB input changes.
     *
     * @private
     */
    onLabChange(event, channel) {
        const input = event.target;
        let value = parseInt(input.value, 10) || 0;
        if (channel === 'l') {
            value = Math.max(0, Math.min(100, value));
        }
        else {
            value = Math.max(-128, Math.min(127, value));
        }
        try {
            const chromaColor = chroma(this._color);
            let [l, a, b] = chromaColor.lab();
            const alpha = chromaColor.alpha();
            if (channel === 'l') {
                l = value;
            }
            else if (channel === 'a') {
                a = value;
            }
            else {
                b = value;
            }
            this.color = chroma.lab(l, a, b).alpha(alpha)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles LCH input changes.
     *
     * @private
     */
    onLchChange(event, channel) {
        const input = event.target;
        let value = parseInt(input.value, 10) || 0;
        if (channel === 'l') {
            value = Math.max(0, Math.min(100, value));
        }
        else if (channel === 'c') {
            value = Math.max(0, Math.min(150, value));
        }
        else {
            value = Math.max(0, Math.min(360, value));
        }
        try {
            const chromaColor = chroma(this._color);
            let [l, c, h] = chromaColor.lch();
            const alpha = chromaColor.alpha();
            h = isNaN(h) ? 0 : h;
            if (channel === 'l') {
                l = value;
            }
            else if (channel === 'c') {
                c = value;
            }
            else {
                h = value;
            }
            this.color = chroma.lch(l, c, h).alpha(alpha)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles OKLAB input changes.
     *
     * @private
     */
    onOklabChange(event, channel) {
        const input = event.target;
        const rawValue = parseFloat(input.value) || 0;
        let value = null;
        if (channel === 'l') {
            value = Math.max(0, Math.min(1, rawValue));
        }
        else {
            value = Math.max(-0.4, Math.min(0.4, rawValue));
        }
        try {
            const chromaColor = chroma(this._color);
            const oklabValues = chromaColor.oklab();
            let [l, a, b] = oklabValues;
            const alpha = chromaColor.alpha();
            if (channel === 'l') {
                l = value;
            }
            else if (channel === 'a') {
                a = value;
            }
            else {
                b = value;
            }
            this.color = chroma.oklab(l, a, b).alpha(alpha)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
    /**
     * Handles OKLCH input changes.
     *
     * @private
     */
    onOklchChange(event, channel) {
        const input = event.target;
        const rawValue = parseFloat(input.value) || 0;
        let value = null;
        if (channel === 'l') {
            value = Math.max(0, Math.min(1, rawValue));
        }
        else if (channel === 'c') {
            value = Math.max(0, Math.min(0.4, rawValue));
        }
        else {
            value = Math.max(0, Math.min(360, rawValue));
        }
        try {
            const chromaColor = chroma(this._color);
            const oklchValues = chromaColor.oklch();
            let [l, c, h] = oklchValues;
            const alpha = chromaColor.alpha();
            h = isNaN(h) ? 0 : h;
            if (channel === 'l') {
                l = value;
            }
            else if (channel === 'c') {
                c = value;
            }
            else {
                h = value;
            }
            this.color = chroma.oklch(l, c, h).alpha(alpha)
                .css();
            this._colorChanged.emit({
                color: this._color,
                format: this._format
            });
        }
        catch { /* Invalid, don't update */ }
    }
};
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ColorEditorInputsElement.prototype, "color", null);
__decorate([
    Attribute({ type: String }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], ColorEditorInputsElement.prototype, "format", null);
__decorate([
    Property({
        type: Boolean,
        useDefault: true
    }),
    __metadata("design:type", Boolean),
    __metadata("design:paramtypes", [Boolean])
], ColorEditorInputsElement.prototype, "showAlpha", null);
__decorate([
    Emit({ eventName: 'colorChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], ColorEditorInputsElement.prototype, "colorChanged", null);
__decorate([
    Emit({ eventName: 'colorFormatChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], ColorEditorInputsElement.prototype, "colorFormatChanged", null);
ColorEditorInputsElement = ColorEditorInputsElement_1 = __decorate([
    Component({
        selector: 'mosaik-color-editor-inputs',
        template: colorEditorInputsElementTemplate,
        themes: {
            joy: colorEditorInputsElementJoyStyle,
            memphis: colorEditorInputsElementMemphisStyle,
            cosmopolitan: colorEditorInputsElementCosmopolitanStyle
        },
        imports: [
            TextBoxElement,
            NumberBoxElement,
            ButtonElement,
            ButtonGroupElement
        ]
    }),
    __metadata("design:paramtypes", [])
], ColorEditorInputsElement);
export { ColorEditorInputsElement };
//# sourceMappingURL=ColorEditorInputsElement.js.map