// #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 { Labelable } from '../../../Behaviors/Labelable';
import { Orientable } from '../../../Behaviors/Orientable';
import { Variantable } from '../../../Behaviors/Variantable';
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { Watch } from '../../../Decorators/WatchDecorator';
import { MeterRange } from '../../../Types/MeterRange';
import { RangeBaseElement } from '../Abstracts/RangeBaseElement';
import { meterRingElementTemplate } from './MeterRingElementTemplate';
import { meterRingElementJoyStyle } from './Themes/MeterRingElement.Joy';
import { meterRingElementRetroStyle } from './Themes/MeterRingElement.Retro';
import { meterRingElementCosmopolitanStyle } from './Themes/MeterRingElement.Cosmopolitan';
import { Themeable } from '../../../Behaviors/Themeable';
// #endregion
/**
 * The `{@link MeterRingElement}` element.
 *
 * @public
 */
let MeterRingElement = class MeterRingElement extends Themeable(Variantable(Orientable(Disableable(Labelable(RangeBaseElement))))) {
    // #region Fields
    _thickness;
    _radius;
    _high;
    _low;
    _optimum;
    _percent;
    _range;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._thickness = 4;
        this._radius = 16;
        this._high = 0;
        this._low = 0;
        this._optimum = 0;
        this._percent = 0;
        this._range = MeterRange.Normal;
    }
    // #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-meter-ring';
    }
    /**
     * Gets or sets the thickness property.
     *
     * @public
     * @attr
     */
    get thickness() {
        return this._thickness;
    }
    set thickness(value) {
        if (this._thickness !== value) {
            this._thickness = value;
            this.requestUpdate('thickness');
        }
    }
    /**
     * @public
     * @attr
     */
    get radius() {
        return this._radius;
    }
    set radius(value) {
        if (this._radius !== value) {
            this._radius = value;
            this.requestUpdate('radius');
        }
    }
    /**
     * Gets or sets the `high` property.
     *
     * @public
     * @attr
     */
    get high() {
        return this._high;
    }
    set high(value) {
        if (this._high !== value) {
            this._high = value;
            this.requestUpdate('high');
        }
    }
    /**
     * Gets or sets the `low` property.
     *
     * @public
     * @attr
     */
    get low() {
        return this._low;
    }
    set low(value) {
        if (this._low !== value) {
            this._low = value;
            this.requestUpdate('low');
        }
    }
    /**
     * Gets or sets the `optimum` property.
     *
     * @public
     * @attr
     */
    get optimum() {
        return this._optimum;
    }
    set optimum(value) {
        if (this._optimum !== value) {
            this._optimum = value;
            this.requestUpdate('optimum');
        }
    }
    /**
     * @private
     * @readonly
     */
    get percent() {
        return this._percent;
    }
    /**
     * @private
     * @hidden
     * @readonly
     */
    get diameter() {
        return this._radius * 2;
    }
    /**
     * Gets or sets the `range` property.
     *
     * @public
     * @readonly
     * @attr
     */
    get range() {
        return this._range;
    }
    set range(value) {
        if (this._range !== value) {
            this._range = value;
            this.requestUpdate('range');
        }
    }
    // #endregion
    // #region Methods
    /**
     * @protected
     * @override
     */
    onValueChanged(prev, next) {
        super.onValueChanged(prev, next);
        this._percent = this.max <= this.min
            ? Number.NaN
            : (this.value - this.min) / (this.max - this.min);
    }
    onPropertyChanged() {
        let range = MeterRange.Normal;
        if (this.value < this.low) {
            range = MeterRange.Low;
        }
        else if (this.value >= this.high) {
            range = MeterRange.High;
        }
        else if (this.value >= this.optimum) {
            range = MeterRange.Optimum;
        }
        this.range = range;
    }
    /**
     * @private
     */
    getCircumference() {
        return 2 * Math.PI * this.radius;
    }
    /**
     * @private
     */
    getOffset() {
        const circumference = this.getCircumference();
        const offset = circumference - (((this.value - this.min) / (this.max - this.min)) * circumference);
        return offset + this.thickness;
    }
};
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], MeterRingElement.prototype, "thickness", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], MeterRingElement.prototype, "radius", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], MeterRingElement.prototype, "high", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], MeterRingElement.prototype, "low", null);
__decorate([
    Attribute({ type: Number }),
    __metadata("design:type", Number),
    __metadata("design:paramtypes", [Number])
], MeterRingElement.prototype, "optimum", null);
__decorate([
    Attribute({ type: MeterRange }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], MeterRingElement.prototype, "range", null);
__decorate([
    Watch('value'),
    Watch('minimum'),
    Watch('maximum'),
    Watch('low'),
    Watch('high'),
    Watch('optimum'),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", void 0)
], MeterRingElement.prototype, "onPropertyChanged", null);
MeterRingElement = __decorate([
    Component({
        selector: 'mosaik-meter-ring',
        template: meterRingElementTemplate,
        themes: {
            joy: meterRingElementJoyStyle,
            retro: meterRingElementRetroStyle,
            cosmopolitan: meterRingElementCosmopolitanStyle
        },
        imports: []
    }),
    __metadata("design:paramtypes", [])
], MeterRingElement);
export { MeterRingElement };
//# sourceMappingURL=MeterRingElement.js.map