// #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
/**
 * Range Base - An abstract foundation for single-value range controls with minimum and maximum constraints.
 *
 * @description
 * The RangeBaseElement provides the core functionality for range-based input controls that
 * allow users to select a single numeric value within a defined minimum and maximum boundary.
 * This abstract base class handles value state management, range constraint enforcement, and
 * reactive value change notifications. It serves as the foundation for concrete implementations
 * such as sliders, progress bars, rating controls, and other single-value range selectors.
 * The element automatically validates values against the configured range and emits events
 * when values change, enabling seamless integration with form systems and reactive data flows.
 *
 * @name Range Base
 * @category Ranges
 *
 * @fires rangeValueChanged {RangeValueChangedEvent} - Fired when the value property changes, providing both old and new numeric 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 custom slider:
 * ```typescript
 * class SliderElement extends RangeBaseElement {
 *   constructor() {
 *     super();
 *     this.min = 0;
 *     this.max = 100;
 *     this.value = 50;
 *   }
 * }
 * ```
 *
 * @example
 * Basic usage with value change tracking:
 * ```typescript
 * const slider = new MySliderElement();
 * slider.min = 0;
 * slider.max = 10;
 * slider.value = 5;
 * slider.valueChanged.subscribe(({ oldValue, newValue }) => {
 *   console.log(`Value changed from ${oldValue} to ${newValue}`);
 * });
 * ```
 *
 * @example
 * Listening to range value changes:
 * ```typescript
 * const control = document.querySelector('my-range');
 * control.addEventListener('rangeValueChanged', (event) => {
 *   const { oldValue, newValue } = event.detail;
 *   console.log('Range adjusted:', oldValue, '→', newValue);
 * });
 * ```
 *
 * @example
 * Setting range constraints:
 * ```typescript
 * const rating = new MyRatingElement();
 * rating.min = 1;
 * rating.max = 5;
 * rating.value = 3; // Default rating
 * ```
 *
 * @public
 * @abstract
 */
export class RangeBaseElement extends Rangeable(Valueable(CustomElement)) {
    // #region Fields
    _rangeValueChanged;
    _value;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `RangeBaseElement` class.
     *
     * @remarks
     * This constructor must be public, otherwise it doesn't work with mixins/behaviors.
     *
     * @public
     */
    constructor() {
        super();
        this.min = 0;
        this.max = 1;
        this._value = 0;
        this._rangeValueChanged = 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.onRangeValueChanged(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 rangeValueChanged() {
        return this._rangeValueChanged;
    }
    // #endregion
    // #region Methods
    /**
     * This method is invoked when the Value property changes.
     *
     * @protected
     */
    onRangeValueChanged(prev, next) {
        this._value = next;
        this._rangeValueChanged.emit({
            oldValue: prev,
            newValue: next
        });
        this.requestUpdate('value');
    }
}
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], RangeBaseElement.prototype, "value", null);
__decorate([
    Emit({ eventName: 'rangeValueChanged' }),
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [])
], RangeBaseElement.prototype, "rangeValueChanged", null);
//# sourceMappingURL=RangeBaseElement.js.map