import * as i0 from '@angular/core';
import { Component, Attribute, Inject, Optional, ViewChild, NgModule } from '@angular/core';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i1$1 from 'ng-circle-progress';
import { CircleProgressComponent, NgCircleProgressModule } from 'ng-circle-progress';
import { PROP_STRING, PROP_ANY, PROP_NUMBER, PROP_BOOLEAN, register, StylableComponent, styler, provideAsWidgetRef, WmComponentsModule } from '@wm/components/base';
import { findValueOf, isDefined } from '@wm/core';
import { isString, isNaN, debounce, isArray, clone, extend } from 'lodash-es';

const registerProps$1 = () => {
    register('wm-progress-bar', new Map([
        ['captionplacement', { value: 'hidden', ...PROP_STRING }],
        ['class', PROP_STRING],
        ['dataset', PROP_ANY],
        ['datavalue', PROP_STRING],
        ['displayformat', PROP_STRING],
        ['hint', PROP_STRING],
        ['arialabel', PROP_STRING],
        ['maxvalue', { value: 100, ...PROP_NUMBER }],
        ['minvalue', { value: 0, ...PROP_NUMBER }],
        ['name', PROP_STRING],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['tabindex', { value: 0, ...PROP_NUMBER }],
        ['type', { value: 'default', ...PROP_STRING }]
    ]));
};

// This function returns the maximum number of decimal digits allowed.
const getDecimalCount = (val) => {
    val = val || '9';
    val = val.replace(/\%$/, '');
    const n = val.lastIndexOf('.');
    return (n === -1) ? 0 : (val.length - n - 1);
};
// returns true if the given value contains '%'
const isPercentageValue = (val) => {
    if (isString(val)) {
        val = val.trim();
        return val.charAt(val.length - 1) === '%';
    }
    return false;
};
const calculatePercent = (value, min = 0, max = 0) => {
    const percent = ((value - min) / (max - min)) * 100;
    if (isNaN(percent)) {
        console.warn('Circle Progress Bar: One of the properties Min, Max or datavalue is not a valid number');
        return 0;
    }
    return Math.abs(percent);
};

const _c0$1 = ["wmProgressBar", ""];
function ProgressBarComponent_div_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 1)(1, "span", 2);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const bar_r1 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵclassMapInterpolate1("multi-bar progress-bar ", bar_r1.cls, "");
    i0.ɵɵstyleProp("width", bar_r1.progressBarWidth);
    i0.ɵɵattribute("aria-valuenow", ctx_r1.datavalue)("aria-valuemin", ctx_r1.minvalue)("aria-valuemax", ctx_r1.maxvalue)("aria-label", ctx_r1.arialabel || "Progress bar");
    i0.ɵɵadvance();
    i0.ɵɵattribute("data-caption-placement", ctx_r1.captionplacement);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(bar_r1.displayValue);
} }
const DEFAULT_CLS$1 = 'progress app-progress';
const WIDGET_CONFIG$1 = { widgetType: 'wm-progress-bar', hostClass: DEFAULT_CLS$1 };
// map of progress-bar type and classes
const TYPE_CLASS_MAP = {
    'default': '',
    'default-striped': 'progress-bar-striped',
    'success': 'progress-bar-success',
    'success-striped': 'progress-bar-success progress-bar-striped',
    'info': 'progress-bar-info',
    'info-striped': 'progress-bar-info progress-bar-striped',
    'warning': 'progress-bar-warning',
    'warning-striped': 'progress-bar-warning progress-bar-striped',
    'danger': 'progress-bar-danger',
    'danger-striped': 'progress-bar-danger progress-bar-striped'
};
class ProgressBarComponent extends StylableComponent {
    static { this.initializeProps = registerProps$1(); }
    constructor(inj, dataset, boundDataset, explicitContext) {
        super(inj, WIDGET_CONFIG$1, explicitContext);
        // progress-bar data, ngFor in the template iterates on this
        this.data = [{
                cls: TYPE_CLASS_MAP.default,
                progressBarWidth: '0%',
                displayValue: '0'
            }];
        // flag which determines whether dataset is provided or not
        this.hasDataset = !!(dataset || boundDataset);
        styler(this.nativeElement, this);
        this._prepareData = debounce(() => this.prepareData(), 50);
    }
    // update the proper classes when there is a change in type
    onTypeChange() {
        if (!this.hasDataset) {
            if (this.data[0]) {
                this.data[0].cls = TYPE_CLASS_MAP[this.type];
            }
        }
    }
    // returns the formatted display value based on the provided displayformat
    getFormattedDisplayVal(val) {
        const format = this.displayformat || '9';
        val = parseFloat('' + val);
        val = (val.toFixed(getDecimalCount(format)));
        if (format && format.includes('%')) {
            val = `${val}%`;
        }
        return val;
    }
    prepareData() {
        // when the dataset is provided, iterate over the dataset to set the proper values in the data
        if (this.dataset && isArray(this.dataset) && this.type && this.datavalue) {
            this.data = this.dataset.map((datum) => {
                const val = findValueOf(datum, this.datavalue).toString();
                let percentVal = val;
                if (val && !val.includes('%')) {
                    percentVal = `${val}%`;
                }
                return {
                    cls: TYPE_CLASS_MAP[findValueOf(datum, this.type)],
                    progressBarWidth: percentVal,
                    displayValue: this.getFormattedDisplayVal(val)
                };
            });
        }
        else {
            // if the dataset is not provided, update the values in the default data
            let width = 0;
            let displayVal = 0;
            if (this.datavalue) {
                if (isPercentageValue(this.datavalue)) {
                    const val = (this.datavalue || '0%');
                    width = displayVal = val;
                }
                else {
                    if (isDefined(this.datavalue)) {
                        const denominator = (+this.maxvalue - +this.minvalue) || 1;
                        const val = ((+this.datavalue - +this.minvalue) * 100) / denominator + '%';
                        width = displayVal = val;
                    }
                }
            }
            this.data[0].displayValue = this.getFormattedDisplayVal(displayVal);
            this.data[0].progressBarWidth = width;
            this.data[0].cls = TYPE_CLASS_MAP[this.type];
        }
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'type') {
            this.onTypeChange();
        }
        else if (key === 'minvalue' || key === 'maxvalue' || key === 'datavalue' || key === 'dataset' || key === 'displayformat') {
            this._prepareData();
        }
        else {
            super.onPropertyChange(key, nv, ov);
        }
    }
    static { this.ɵfac = function ProgressBarComponent_Factory(t) { return new (t || ProgressBarComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵinjectAttribute('dataset'), i0.ɵɵinjectAttribute('dataset.bind'), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProgressBarComponent, selectors: [["", "wmProgressBar", ""]], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(ProgressBarComponent)
            ]), i0.ɵɵInheritDefinitionFeature], attrs: _c0$1, decls: 1, vars: 1, consts: [["role", "progressbar", 3, "class", "width", 4, "ngFor", "ngForOf"], ["role", "progressbar"], [1, "app-progress-label"]], template: function ProgressBarComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵtemplate(0, ProgressBarComponent_div_0_Template, 3, 11, "div", 0);
        } if (rf & 2) {
            i0.ɵɵproperty("ngForOf", ctx.data);
        } }, dependencies: [i1.NgForOf], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ProgressBarComponent, [{
        type: Component,
        args: [{ selector: '[wmProgressBar]', providers: [
                    provideAsWidgetRef(ProgressBarComponent)
                ], template: "<div class=\"multi-bar progress-bar {{bar.cls}}\" *ngFor=\"let bar of data\" [style.width]=\"bar.progressBarWidth\"\n    role=\"progressbar\" [attr.aria-valuenow]=\"datavalue\" [attr.aria-valuemin]=\"minvalue\" [attr.aria-valuemax]=\"maxvalue\"\n     [attr.aria-label]=\"arialabel || 'Progress bar'\">\n    <span class=\"app-progress-label\" [attr.data-caption-placement]=\"captionplacement\">{{bar.displayValue}}</span>\n</div>\n" }]
    }], () => [{ type: i0.Injector }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['dataset']
            }] }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['dataset.bind']
            }] }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], null); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProgressBarComponent, { className: "ProgressBarComponent", filePath: "progress-bar/progress-bar.component.ts", lineNumber: 42 }); })();

const registerProps = () => {
    register('wm-progress-circle', new Map([
        ['captionplacement', { value: 'inside', ...PROP_STRING }],
        ['class', PROP_STRING],
        ['dataset', PROP_ANY],
        ['datavalue', { value: '30', ...PROP_STRING }],
        ['displayformat', { value: '9%', ...PROP_STRING }],
        ['hint', PROP_STRING],
        ['arialabel', PROP_STRING],
        ['maxvalue', { value: 100, ...PROP_NUMBER }],
        ['minvalue', { value: 0, ...PROP_NUMBER }],
        ['name', PROP_STRING],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['subtitle', PROP_STRING],
        ['tabindex', { value: 0, ...PROP_NUMBER }],
        ['title', PROP_STRING],
        ['type', { value: 'default', ...PROP_STRING }]
    ]));
};

const _c0 = ["wmProgressCircle", ""];
const DEFAULT_CLS = 'progress app-progress circle';
const WIDGET_CONFIG = { widgetType: 'wm-progress-circle', hostClass: DEFAULT_CLS };
const DEFAULT_OPTIONS = {
    responsive: true,
    innerStrokeWidth: 10,
    outerStrokeWidth: 10,
    unitsFontSize: '15',
    space: -10,
    toFixed: 0,
    maxPercent: 100,
    showSubtitle: false,
    clockwise: true,
    startFromZero: false,
    renderOnClick: false,
    innerStrokeColor: '',
    outerStrokeColor: ''
};
// map of progress-bar type and classes
const TYPE_CLASS_MAP_PC = {
    'default': '',
    'success': 'progress-circle-success',
    'info': 'progress-circle-info',
    'warning': 'progress-circle-warning',
    'danger': 'progress-circle-danger',
};
class ProgressCircleComponent extends StylableComponent {
    static { this.initializeProps = registerProps(); }
    constructor(inj, explicitContext) {
        super(inj, WIDGET_CONFIG, explicitContext);
        styler(this.nativeElement, this);
        this.options = clone(DEFAULT_OPTIONS);
        this.redraw = debounce(this._redraw, 100);
    }
    _redraw() {
        this.circleRef.render();
        // Select the <tspan> element that contains the percentage value
        let tspanElement = $(this.nativeElement).find('svg text tspan:first');
        this.displayValue = this.options.showUnits ? tspanElement?.text() + '%' : tspanElement?.text();
    }
    ngAfterViewInit() {
        super.ngAfterViewInit();
        this.invokeEventCallback('beforerender', { '$event': {} });
        this.options = Object.assign(this.circleRef.options, this.options);
    }
    getDefaultOptions() {
        return this.options;
    }
    getLib() {
        return 'ng-circle-progress';
    }
    overrideDefaults(options) {
        extend(this.options, options);
    }
    updateDisplayValueFormat() {
        // show title and subtitle only when captionplacement is 'inside'
        this.options.showTitle = this.options.showSubtitle = (this.captionplacement === 'inside');
        // show units when title value is empty and captionplacement is 'inside'
        this.options.showUnits = !this.title && this.options.showTitle && isPercentageValue(this.displayformat);
        this.options.toFixed = getDecimalCount(this.displayformat);
        if (this.options.showTitle) {
            this.options.title = this.title || 'auto';
            this.options.showSubtitle = !!this.subtitle;
            this.options.subtitle = this.subtitle || '';
        }
        this.redraw();
    }
    onPropertyChange(key, nv, ov) {
        switch (key) {
            case 'type':
                this.$element.removeClass(TYPE_CLASS_MAP_PC[ov]);
                this.$element.addClass(TYPE_CLASS_MAP_PC[nv]);
                break;
            case 'minvalue':
            case 'maxvalue':
            case 'datavalue':
                if (isPercentageValue(this.datavalue)) {
                    this.percentagevalue = parseFloat(this.datavalue);
                }
                else {
                    this.percentagevalue = calculatePercent(parseFloat(this.datavalue), this.minvalue, this.maxvalue);
                }
                break;
            case 'displayformat':
            case 'captionplacement':
            case 'title':
            case 'subtitle':
                this.updateDisplayValueFormat();
                break;
        }
        super.onPropertyChange(key, nv, ov);
    }
    static { this.ɵfac = function ProgressCircleComponent_Factory(t) { return new (t || ProgressCircleComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProgressCircleComponent, selectors: [["", "wmProgressCircle", ""]], viewQuery: function ProgressCircleComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(CircleProgressComponent, 7);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.circleRef = _t.first);
        } }, exportAs: ["wmProgressCircle"], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(ProgressCircleComponent)
            ]), i0.ɵɵInheritDefinitionFeature], attrs: _c0, decls: 1, vars: 2, consts: [[3, "percent", "options"]], template: function ProgressCircleComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelement(0, "circle-progress", 0);
        } if (rf & 2) {
            i0.ɵɵproperty("percent", ctx.percentagevalue)("options", ctx.options);
        } }, dependencies: [i1$1.CircleProgressComponent], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ProgressCircleComponent, [{
        type: Component,
        args: [{ selector: '[wmProgressCircle]', providers: [
                    provideAsWidgetRef(ProgressCircleComponent)
                ], exportAs: 'wmProgressCircle', template: "<circle-progress [percent]=\"percentagevalue\" [options]=\"options\"></circle-progress>\n" }]
    }], () => [{ type: i0.Injector }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], { circleRef: [{
            type: ViewChild,
            args: [CircleProgressComponent, { static: true }]
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProgressCircleComponent, { className: "ProgressCircleComponent", filePath: "progress-circle/progress-circle.component.ts", lineNumber: 47 }); })();

const components = [
    ProgressBarComponent,
    ProgressCircleComponent
];
class ProgressModule {
    static { this.ɵfac = function ProgressModule_Factory(t) { return new (t || ProgressModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: ProgressModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
            NgCircleProgressModule,
            WmComponentsModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ProgressModule, [{
        type: NgModule,
        args: [{
                imports: [
                    CommonModule,
                    NgCircleProgressModule,
                    WmComponentsModule
                ],
                declarations: [...components],
                exports: [...components]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(ProgressModule, { declarations: [ProgressBarComponent,
        ProgressCircleComponent], imports: [CommonModule,
        NgCircleProgressModule,
        WmComponentsModule], exports: [ProgressBarComponent,
        ProgressCircleComponent] }); })();

/**
 * Generated bundle index. Do not edit.
 */

export { ProgressBarComponent, ProgressCircleComponent, ProgressModule, TYPE_CLASS_MAP, TYPE_CLASS_MAP_PC };
//# sourceMappingURL=index.mjs.map
