import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { EventEmitter, Attribute, Self, Optional, Input, Output, Component, ViewEncapsulation, isDevMode, NgZone, ChangeDetectorRef, ContentChildren, ChangeDetectionStrategy, NgModule } from '@angular/core';
import { NgControl } from '@angular/forms';
import { Subject, defer, merge } from 'rxjs';
import { take, switchMap, startWith, takeUntil } from 'rxjs/operators';
import { NtFormFieldControl } from '@ng-tangram/components/forms';
import { CommonModule } from '@angular/common';

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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
let uniqueId = 0;
class NtRadioChange {
    constructor(source, selected) {
        this.source = source;
        this.selected = selected;
    }
}
let NtRadioComponent = class NtRadioComponent {
    constructor(tabIndex, ngControl) {
        this.ngControl = ngControl;
        this.id = `nt-radio-${uniqueId++}`;
        this._disabled = false;
        this._readonly = false;
        this._checked = false;
        this._name = this.id;
        this.change = new EventEmitter();
        this._onChange = () => { };
        this._onTouched = () => { };
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
        this.tabIndex = parseInt(tabIndex) || 0;
    }
    set value(value) { this._value = value; }
    get value() { return this._value; }
    set disabled(value) { this._disabled = coerceBooleanProperty(value); }
    get disabled() { return this._disabled; }
    set readonly(value) { this._readonly = coerceBooleanProperty(value); }
    get readonly() { return this._readonly; }
    get checked() { return this._checked; }
    set checked(value) { this._checked = coerceBooleanProperty(value); }
    set name(value) { this._name = value; }
    get name() { return this._name; }
    writeValue(value) {
        this._checked = !!value;
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this.disabled = isDisabled;
    }
    _onInputClick(event) {
        event.stopPropagation();
    }
    _onInputChange(event) {
        event.stopPropagation();
        this._checked = true;
        this._emitChangeEvent();
    }
    _emitChangeEvent() {
        const event = new NtRadioChange(this, this.checked);
        this._onChange(this.checked);
        this._onTouched();
        this.change.emit(event);
    }
};
NtRadioComponent.ctorParameters = () => [
    { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
    { type: NgControl, decorators: [{ type: Self }, { type: Optional }] }
];
__decorate([
    Input()
], NtRadioComponent.prototype, "value", null);
__decorate([
    Input()
], NtRadioComponent.prototype, "disabled", null);
__decorate([
    Input()
], NtRadioComponent.prototype, "readonly", null);
__decorate([
    Input()
], NtRadioComponent.prototype, "checked", null);
__decorate([
    Input()
], NtRadioComponent.prototype, "name", null);
__decorate([
    Output()
], NtRadioComponent.prototype, "change", void 0);
NtRadioComponent = __decorate([
    Component({
        selector: 'nt-radio',
        encapsulation: ViewEncapsulation.None,
        template: "<label class=\"nt-radio-layout\">\n  <div class=\"nt-radio-input-container\">\n    <input class=\"cdk-visually-hidden\"\n      type=\"radio\"\n      [name]=\"name\"\n      [tabIndex]=\"tabIndex\"\n      [disabled]=\"disabled\"\n      [checked]=\"checked\"\n      (change)=\"_onInputChange($event)\"\n      (click)=\"_onInputClick($event)\">\n    <div class=\"nt-radio-input\"></div>\n  </div>\n  <span class=\"nt-radio-label\">\n    <ng-content></ng-content>\n  </span>\n</label>\n",
        host: {
            'class': 'nt-radio',
            '[class.nt-radio-disabled]': 'disabled'
        }
    }),
    __param(0, Attribute('tabindex')),
    __param(1, Self()), __param(1, Optional())
], NtRadioComponent);

var __decorate$1 = (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 __param$1 = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var NtRadioGroupComponent_1;
function getNtRdioGroupNonFunctionValueError() {
    return Error('`compareWith` must be a function.');
}
let uniqueId$1 = 0;
let NtRadioGroupComponent = NtRadioGroupComponent_1 = class NtRadioGroupComponent extends NtFormFieldControl {
    constructor(_ngZone, _changeDetectorRef, ngControl) {
        super();
        this._ngZone = _ngZone;
        this._changeDetectorRef = _changeDetectorRef;
        this.ngControl = ngControl;
        this.id = `nt-radio-group-${uniqueId$1++}`;
        this._destroy = new Subject();
        this._disabled = false;
        this._readonly = false;
        this._required = false;
        this._name = this.id;
        this._compareWith = (o1, o2) => o1 === o2;
        this.checkedChanges = defer(() => {
            if (this.radios) {
                return merge(...this.radios.map(item => item.change));
            }
            return this._ngZone.onStable
                .asObservable()
                .pipe(take(1), switchMap(() => this.checkedChanges));
        });
        this._onChange = () => { };
        this._onTouched = () => { };
        if (this.ngControl) {
            this.ngControl.valueAccessor = this;
        }
    }
    get value() { return this._value; }
    set disabled(value) { this._disabled = coerceBooleanProperty(value); }
    get disabled() { return this._disabled; }
    get required() { return this._required; }
    set required(value) { this._required = coerceBooleanProperty(value); }
    set readonly(value) { this._readonly = coerceBooleanProperty(value); }
    get readonly() { return this._readonly; }
    get name() { return this._name; }
    set name(value) {
        this._name = value;
        this._updateRadioButtonNames();
    }
    set compareWith(fn) {
        if (typeof fn !== 'function') {
            throw getNtRdioGroupNonFunctionValueError();
        }
        else {
            this._compareWith = fn;
        }
    }
    ngAfterViewInit() {
        this.radios.changes.pipe(startWith(null), takeUntil(this._destroy)).subscribe(() => {
            this._resetRadios();
            this._initializeChecked();
        });
    }
    ngOnDestroy() {
        this._destroy.next();
        this._destroy.complete();
    }
    writeValue(value) {
        if (this.radios) {
            this._setCheckedByValue(value);
        }
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    focus() {
        if (!this.disabled) {
            this._onTouched();
        }
    }
    _initializeChecked() {
        Promise.resolve().then(() => {
            this._updateRadioButtonNames();
            this._setCheckedByValue(this.ngControl ? this.ngControl.value : this.value);
        });
    }
    _resetRadios() {
        const changedOrDestroyed = merge(this.radios.changes, this._destroy);
        this.checkedChanges.pipe(takeUntil(changedOrDestroyed)).subscribe(change => {
            this._setValues(change.source);
        });
        merge(...this.radios.map(item => item.change))
            .pipe(takeUntil(changedOrDestroyed))
            .subscribe(() => {
            this._changeDetectorRef.markForCheck();
        });
    }
    _setCheckedByValue(value) {
        this._value = value;
        this.radios.forEach(item => item.checked = false);
        this._checkedValue(value);
        this._changeDetectorRef.markForCheck();
    }
    _checkedValue(value) {
        const correspondingItem = this.radios.find((item) => {
            try {
                return item.value != null && this._compareWith(item.value, value);
            }
            catch (error) {
                if (isDevMode()) {
                    console.warn(error);
                }
                return false;
            }
        });
        if (correspondingItem) {
            correspondingItem.checked = true;
        }
        return correspondingItem;
    }
    _setValues(radio) {
        this._value = radio.value;
        this._onChange(this._value);
        this._onTouched();
        this._changeDetectorRef.markForCheck();
    }
    _updateRadioButtonNames() {
        if (this.radios) {
            this.radios.forEach(radio => {
                radio.name = this.name;
            });
        }
    }
};
NtRadioGroupComponent.ctorParameters = () => [
    { type: NgZone },
    { type: ChangeDetectorRef },
    { type: NgControl, decorators: [{ type: Self }, { type: Optional }] }
];
__decorate$1([
    Input()
], NtRadioGroupComponent.prototype, "disabled", null);
__decorate$1([
    Input()
], NtRadioGroupComponent.prototype, "required", null);
__decorate$1([
    Input()
], NtRadioGroupComponent.prototype, "readonly", null);
__decorate$1([
    Input()
], NtRadioGroupComponent.prototype, "name", null);
__decorate$1([
    ContentChildren(NtRadioComponent)
], NtRadioGroupComponent.prototype, "radios", void 0);
__decorate$1([
    Input()
], NtRadioGroupComponent.prototype, "compareWith", null);
NtRadioGroupComponent = NtRadioGroupComponent_1 = __decorate$1([
    Component({
        selector: 'nt-radio-group',
        template: '<ng-content></ng-content>',
        encapsulation: ViewEncapsulation.None,
        changeDetection: ChangeDetectionStrategy.OnPush,
        providers: [
            { provide: NtFormFieldControl, useExisting: NtRadioGroupComponent_1 }
        ],
        host: {
            'class': 'nt-radio-group'
        }
    }),
    __param$1(2, Self()), __param$1(2, Optional())
], NtRadioGroupComponent);

var __decorate$2 = (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;
};
let NtRadioModule = class NtRadioModule {
};
NtRadioModule = __decorate$2([
    NgModule({
        imports: [CommonModule],
        exports: [NtRadioComponent, NtRadioGroupComponent],
        declarations: [NtRadioComponent, NtRadioGroupComponent],
    })
], NtRadioModule);

export { NtRadioChange, NtRadioComponent, NtRadioGroupComponent, NtRadioModule, getNtRdioGroupNonFunctionValueError };
//# sourceMappingURL=radio.js.map
