import * as tslib_1 from "tslib";
import { Component, Input, Output, EventEmitter, Optional, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ElementRef, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { BoxGroupComponent } from './box-group';
import { uuid as getUUID } from '../util/uuid';
import { addClass } from '../util/dom';
import { OnChange } from '../core/decorators';
import { coerceBooleanProperty } from '../util/coerce';
/*
 * Provider Expression that allows component to register as a ControlValueAccessor.
 * This allows it to support [(ngModel)].
 * @docs-private
 */
var BOX_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(function () { return InputBoxComponent; }),
    multi: true
};
/**
 * A single checkbox or radiobox
 */
var InputBoxComponent = /** @class */ (function () {
    /**
     * box component constructor
     *
     * @param {BoxGroupComponent?} parentBox - find parent box group component and inject it
     */
    function InputBoxComponent(parentBox, _el, _cd) {
        this._el = _el;
        this._cd = _cd;
        /** When the box state change, emit a change event with a boolean value */
        this.change = new EventEmitter();
        /** to enable [(checked)] style, we need to add a checkedChange event */
        this.checkedChange = new EventEmitter();
        /**
         * box type: either 'checkbox' or 'radio'
         * @default checkbox
         */
        this.type = 'checkbox';
        /**
         * input name, used to group radio inputs
         * @docs-private
         */
        this.uuid = getUUID();
        /**
         * Whether the box is disabled
         * @default false
         */
        this.disabled = false;
        /**
         * Whether the box is checked
         * @default false
         */
        this.checked = false;
        /**
         * Whether the box is intermediate
         * @default false
         */
        this.intermediate = false;
        /**
         * extra theme class
         * @default ''
         */
        this.theme = '';
        this._parentBox = parentBox;
    }
    InputBoxComponent.prototype.ngOnInit = function () {
        // when child onInit, it can get parent and parent binded properties
        // if using within boxgroup, set child box type and name
        if (this._parentBox) {
            this.type = this._parentBox.type;
            this.uuid = this._parentBox.uuid;
            this.disabled = this.disabled || this._parentBox.disabled;
            var value = (this._parentBox.value || []);
            this.checked = value.indexOf(this.value) !== -1 || this.checked;
        }
    };
    InputBoxComponent.prototype.ngAfterViewInit = function () {
        if (this.theme) {
            addClass(this._el.nativeElement, "nb-checkbox-" + this.theme);
        }
    };
    /**
     * input checked change event
     *
     * @param {boolean} checked - whether the input is checked
     * @param {Event} event - original change event, to prevent input default change event
     * @docs-private
     */
    InputBoxComponent.prototype.onChange = function (checked, event) {
        if (this.disabled) {
            return;
        }
        if (this._parentBox) {
            this._parentBox.select(this.value);
        }
        else {
            this.checked = checked;
            this.intermediate = false;
            this.change.emit(checked);
            this.checkedChange.emit(checked);
            this._updateFormModel();
        }
        this.preventCheckboxDefaultEvent(event);
    };
    /**
     * Prevent input default change event
     *
     * @param {Event} event - original change event, to prevent input default change event
     * @docs-private
     */
    InputBoxComponent.prototype.onInputChange = function (event) {
        this.preventCheckboxDefaultEvent(event);
    };
    /**
     * Prevent default click event
     *
     * @param {Event} event - original change event, to prevent input default change event
     * @docs-private
     */
    InputBoxComponent.prototype.preventCheckboxDefaultEvent = function (event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        }
        else {
            event.returnValue = false;
        }
    };
    /**
     * Registers a callback that will be triggered when the value has changed.
     * Implemented as part of ControlValueAccessor.
     * @param fn On change callback function.
     */
    InputBoxComponent.prototype.registerOnChange = function (fn) {
        this._onModelChange = fn;
    };
    /**
     * Registers a callback that will be triggered when the control has been touched.
     * Implemented as part of ControlValueAccessor.
     * @param fn On touch callback function.
     */
    InputBoxComponent.prototype.registerOnTouched = function (fn) {
        this._onTouch = fn;
    };
    /**
     * Sets the model value. Implemented as part of ControlValueAccessor.
     * @param value Value to be set to the model.
     */
    InputBoxComponent.prototype.writeValue = function (value) {
        this.checked = coerceBooleanProperty(value);
        this._cd.markForCheck();
    };
    /**
     * Toggles the disabled state of the component. Implemented as part of ControlValueAccessor.
     * @param isDisabled Whether the component should be disabled.
     */
    InputBoxComponent.prototype.setDisabledState = function (isDisabled) {
        this.disabled = isDisabled;
    };
    /**
     * update form model value and mark for check
     */
    InputBoxComponent.prototype._updateFormModel = function () {
        if (this._onModelChange) {
            this._onModelChange(this.checked);
        }
        if (this._onTouch) {
            this._onTouch(this.checked);
        }
    };
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], InputBoxComponent.prototype, "change", void 0);
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], InputBoxComponent.prototype, "checkedChange", void 0);
    tslib_1.__decorate([
        OnChange(),
        Input(),
        tslib_1.__metadata("design:type", String)
    ], InputBoxComponent.prototype, "type", void 0);
    tslib_1.__decorate([
        OnChange(),
        Input(),
        tslib_1.__metadata("design:type", String)
    ], InputBoxComponent.prototype, "uuid", void 0);
    tslib_1.__decorate([
        OnChange(true),
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], InputBoxComponent.prototype, "disabled", void 0);
    tslib_1.__decorate([
        OnChange(true, true),
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], InputBoxComponent.prototype, "checked", void 0);
    tslib_1.__decorate([
        OnChange(true, true),
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], InputBoxComponent.prototype, "intermediate", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], InputBoxComponent.prototype, "theme", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Object)
    ], InputBoxComponent.prototype, "value", void 0);
    InputBoxComponent = tslib_1.__decorate([
        Component({
            selector: 'nb-checkbox',
            template: "<label class=\"nb-checkbox-label\"><input #checkbox name=\"{{uuid}}\" type=\"{{type}}\" class=\"visually-hidden\" [checked]=\"checked\" [disabled]=\"disabled\" (click)=\"onChange(checkbox.checked, $event)\" (change)=\"onInputChange($event)\"><ng-content></ng-content></label>",
            encapsulation: ViewEncapsulation.None,
            changeDetection: ChangeDetectionStrategy.OnPush,
            preserveWhitespaces: false,
            providers: [BOX_VALUE_ACCESSOR],
            host: {
                'class': 'nb-widget nb-checkbox',
                '[class.nb-checkbox-disabled]': 'disabled',
                '[class.nb-checkbox-checked]': 'checked',
                '[class.nb-checkbox-intermediate]': 'intermediate',
                '[class.nb-checkbox-radio]': 'type == "radio"'
            },
            exportAs: 'nbBox'
        }),
        tslib_1.__param(0, Optional()),
        tslib_1.__metadata("design:paramtypes", [BoxGroupComponent,
            ElementRef,
            ChangeDetectorRef])
    ], InputBoxComponent);
    return InputBoxComponent;
}());
export { InputBoxComponent };
//# sourceMappingURL=box.js.map