// #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 { HTMLElementEventEmitter } from '@breadstone/mosaik-elements';
import { Emit } from '../../../../events/Decorators/EmitDecorator';
import { Rangeable } from '../../../Behaviors/Rangeable';
import { Valueable } from '../../../Behaviors/Valueable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { CustomElement } from '../../Abstracts/CustomElement';
// #endregion
/**
 * Multi Range Base - An abstract foundation for range controls supporting both single and multiple values.
 *
 * @description
 * The MultiRangeBaseElement serves as the abstract base class for range controls that allow
 * users to select either a single numeric value or multiple values (arrays) within a defined
 * minimum and maximum range. This element combines value management with range constraints,
 * providing reactive value change notifications and automatic boundary enforcement. It is
 * designed to be extended by concrete implementations like multi-thumb sliders, dual-value
 * range pickers, or interval selectors that require flexible value representation.
 *
 * @name Multi Range Base
 * @category Ranges
 *
 * @fires rangeValueChanged {RangeValueChangedEvent} - Fired when the value property changes, providing both old and new values
 * @fires changed {PropertyChangedEvent} - Fired when any property changes
 * @fires connected {ConnectedEvent} - Fired when the element is connected to the DOM
 *
 * @example
 * Extending for a dual-thumb slider:
 * ```typescript
 * class DualSliderElement extends MultiRangeBaseElement {
 *   constructor() {
 *     super();
 *     this.min = 0;
 *     this.max = 100;
 *     this.value = [25, 75]; // Two thumb positions
 *   }
 * }
 * ```
 *
 * @example
 * Single value mode:
 * ```typescript
 * const rangeElement = new MyMultiRangeElement();
 * rangeElement.value = 50; // Single numeric value
 * rangeElement.min = 0;
 * rangeElement.max = 100;
 * ```
 *
 * @example
 * Multiple value mode:
 * ```typescript
 * const rangeElement = new MyMultiRangeElement();
 * rangeElement.value = [20, 40, 60, 80]; // Array of values
 * rangeElement.valueChanged.subscribe(({ oldValue, newValue }) => {
 *   console.log('Values changed from', oldValue, 'to', newValue);
 * });
 * ```
 *
 * @example
 * Listening to value changes:
 * ```typescript
 * const slider = document.querySelector('my-multi-range');
 * slider.addEventListener('rangeValueChanged', (event) => {
 *   console.log('Previous value:', event.detail.oldValue);
 *   console.log('New value:', event.detail.newValue);
 * });
 * ```
 *
 * @public
 * @abstract
 */
export class MultiRangeBaseElement extends Rangeable(Valueable(CustomElement)) {
    // #region Fields
    _valueChanged;
    _value;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `MultiRangeBaseElement` class.
     *
     * @remarks
     * This constructor must be public, otherwise it doesn't work with mixins/behaivors.
     *
     * @public
     */
    constructor() {
        super();
        this.min = 0;
        this.max = 1;
        this._value = 0;
        this._valueChanged = new HTMLElementEventEmitter(this, 'rangeValueChanged');
    }
    // #endregion
    // #region Properties
    /**
     * Specifies the value of the `Range`.
     *
     * @public
     * @attr
     */
    get value() {
        return this._value;
    }
    set value(value) {
        if (this._value !== value) {
            this.onValueChanged(this._value, value);
        }
    }
    /**
     * Called when the value is changed.
     * Provides reference to the `IChangedEventDetail` with old and new value as event argument.
     *
     * @public
     * @eventProperty
     * @readonly
     */
    get valueChanged() {
        return this._valueChanged;
    }
    // #endregion
    // #region Methods
    /**
     * This method is invoked when the Value property changes.
     *
     * @protected
     */
    onValueChanged(prev, next) {
        this._value = next;
        this._valueChanged.emit({
            oldValue: prev,
            newValue: next
        });
        this.requestUpdate('value');
    }
}
__decorate([
    Attribute({ type: Object }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], MultiRangeBaseElement.prototype, "value", null);
__decorate([
    Emit({ eventName: 'rangeValueChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], MultiRangeBaseElement.prototype, "valueChanged", null);
//# sourceMappingURL=MultiRangeBaseElement.js.map