import { Directive, Input, Optional, ElementRef, } from '@angular/core';
import { RDialog } from './dialog';
import { _closeDialogVia, RDialogRef } from './dialog-ref';
/** Counter used to generate unique IDs for dialog elements. */
let dialogElementUid = 0;
/**
 * Button that will close the current dialog.
 */
export class RDialogClose {
    constructor(
    // The dialog title directive is always used in combination with a `RDialogRef`.
    // tslint:disable-next-line: lightweight-tokens
    dialogRef, _elementRef, _dialog) {
        this.dialogRef = dialogRef;
        this._elementRef = _elementRef;
        this._dialog = _dialog;
        /** Default to "button" to prevents accidental form submits. */
        this.type = 'button';
    }
    ngOnInit() {
        if (!this.dialogRef) {
            // When this directive is included in a dialog via TemplateRef (rather than being
            // in a Component), the DialogRef isn't available via injection because embedded
            // views cannot be given a custom injector. Instead, we look up the DialogRef by
            // ID. This must occur in `onInit`, as the ID binding for the dialog container won't
            // be resolved at constructor time.
            this.dialogRef = getClosestDialog(this._elementRef, this._dialog.openDialogs);
        }
    }
    ngOnChanges(changes) {
        const proxiedChange = changes['_rDialogClose'] || changes['_rDialogCloseResult'];
        if (proxiedChange) {
            this.dialogResult = proxiedChange.currentValue;
        }
    }
    _onButtonClick(event) {
        // Determinate the focus origin using the click event, because using the FocusMonitor will
        // result in incorrect origins. Most of the time, close buttons will be auto focused in the
        // dialog, and therefore clicking the button won't result in a focus change. This means that
        // the FocusMonitor won't detect any origin change, and will always output `program`.
        _closeDialogVia(this.dialogRef, event.screenX === 0 && event.screenY === 0 ? 'keyboard' : 'mouse', this.dialogResult);
    }
}
RDialogClose.decorators = [
    { type: Directive, args: [{
                selector: '[r-dialog-close], [rDialogClose]',
                exportAs: 'rDialogClose',
                host: {
                    '(click)': '_onButtonClick($event)',
                    '[attr.aria-label]': 'ariaLabel || null',
                    '[attr.type]': 'type',
                }
            },] }
];
RDialogClose.ctorParameters = () => [
    { type: RDialogRef, decorators: [{ type: Optional }] },
    { type: ElementRef },
    { type: RDialog }
];
RDialogClose.propDecorators = {
    ariaLabel: [{ type: Input, args: ['aria-label',] }],
    type: [{ type: Input }],
    dialogResult: [{ type: Input, args: ['r-dialog-close',] }],
    _rDialogClose: [{ type: Input, args: ['rDialogClose',] }]
};
/**
 * Title of a dialog element. Stays fixed to the top of the dialog when scrolling.
 */
export class RDialogTitle {
    constructor(
    // The dialog title directive is always used in combination with a `RDialogRef`.
    // tslint:disable-next-line: lightweight-tokens
    _dialogRef, _elementRef, _dialog) {
        this._dialogRef = _dialogRef;
        this._elementRef = _elementRef;
        this._dialog = _dialog;
        this.id = `r-dialog-title-${dialogElementUid++}`;
    }
    ngOnInit() {
        if (!this._dialogRef) {
            this._dialogRef = getClosestDialog(this._elementRef, this._dialog.openDialogs);
        }
        if (this._dialogRef) {
            Promise.resolve().then(() => {
                const container = this._dialogRef._containerInstance;
                if (container && !container._ariaLabelledBy) {
                    container._ariaLabelledBy = this.id;
                }
            });
        }
    }
}
RDialogTitle.decorators = [
    { type: Directive, args: [{
                selector: '[r-dialog-title], [rDialogTitle]',
                exportAs: 'rDialogTitle',
                host: {
                    'class': 'r-dialog-title',
                    '[id]': 'id',
                },
            },] }
];
RDialogTitle.ctorParameters = () => [
    { type: RDialogRef, decorators: [{ type: Optional }] },
    { type: ElementRef },
    { type: RDialog }
];
RDialogTitle.propDecorators = {
    id: [{ type: Input }]
};
/**
 * Scrollable content container of a dialog.
 */
export class RDialogContent {
}
RDialogContent.decorators = [
    { type: Directive, args: [{
                selector: `[r-dialog-content], r-dialog-content, [rDialogContent]`,
                host: { 'class': 'r-dialog-content' }
            },] }
];
/**
 * Container for the bottom action buttons in a dialog.
 * Stays fixed to the bottom when scrolling.
 */
export class RDialogActions {
}
RDialogActions.decorators = [
    { type: Directive, args: [{
                selector: `[r-dialog-actions], r-dialog-actions, [rDialogActions]`,
                host: { 'class': 'r-dialog-actions' }
            },] }
];
/**
 * Finds the closest RDialogRef to an element by looking at the DOM.
 * @param element Element relative to which to look for a dialog.
 * @param openDialogs References to the currently-open dialogs.
 */
function getClosestDialog(element, openDialogs) {
    let parent = element.nativeElement.parentElement;
    while (parent && !parent.classList.contains('r-dialog-container')) {
        parent = parent.parentElement;
    }
    return parent ? openDialogs.find(dialog => dialog.id === parent.id) : null;
}
//# sourceMappingURL=dialog-content-directives.js.map