/** code from https://github.com/angular/material2 */
import { Component, ElementRef, ContentChildren, ViewEncapsulation, Input, Optional, NgZone, Renderer2, ViewChild, ContentChild, HostBinding } from '@angular/core';
import { Directionality } from '@angular/cdk';
import { NzTabsInkBarDirective } from './nz-tabs-ink-bar.directive';
import { NzTabLabelDirective } from './nz-tab-label.directive';
var EXAGGERATED_OVERSCROLL = 64;
import { auditTime, startWith } from '@angular/cdk';
import { of as observableOf } from 'rxjs/observable/of';
import { merge } from 'rxjs/observable/merge';
import { fromEvent } from 'rxjs/observable/fromEvent';
var NzTabsNavComponent = (function () {
    function NzTabsNavComponent(_elementRef, _ngZone, _renderer, _dir) {
        this._elementRef = _elementRef;
        this._ngZone = _ngZone;
        this._renderer = _renderer;
        this._dir = _dir;
        this._showPaginationControls = false;
        this._disableScrollAfter = true;
        this._disableScrollBefore = true;
        this._scrollDistance = 0;
        this._selectedIndexChanged = false;
        this._realignInkBar = null;
        this._selectedIndex = 0;
        this._tabPositionMode = 'horizontal';
        this.nzAnimated = true;
        this.nzHideBar = false;
        this.nzSize = 'default';
        this._type = 'line';
        this._nzTabsBar = true;
        this.nzShowPagination = true;
    }
    Object.defineProperty(NzTabsNavComponent.prototype, "nzType", {
        get: function () {
            return this._type;
        },
        set: function (value) {
            this._type = value;
            if (this._type !== 'line') {
                this._inkBar.setDisplay('none');
            }
            else {
                this._inkBar.setDisplay('block');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NzTabsNavComponent.prototype, "nzPositionMode", {
        get: function () {
            return this._tabPositionMode;
        },
        set: function (value) {
            this._tabPositionMode = value;
            this._alignInkBarToSelectedTab();
            if (this.nzShowPagination) {
                this._updatePagination();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NzTabsNavComponent.prototype, "selectedIndex", {
        get: function () {
            return this._selectedIndex;
        },
        set: function (value) {
            this._selectedIndexChanged = this._selectedIndex !== value;
            this._selectedIndex = value;
        },
        enumerable: true,
        configurable: true
    });
    NzTabsNavComponent.prototype._onContentChanges = function () {
        if (this.nzShowPagination) {
            this._updatePagination();
        }
        this._alignInkBarToSelectedTab();
    };
    NzTabsNavComponent.prototype._scrollHeader = function (scrollDir) {
        // Move the scroll distance one-third the length of the tab list's viewport.
        this.scrollDistance += (scrollDir === 'before' ? -1 : 1) * this.viewWidthHeightPix / 3;
    };
    NzTabsNavComponent.prototype.ngAfterContentChecked = function () {
        if (this._tabLabelCount !== this._labelWrappers.length) {
            if (this.nzShowPagination) {
                this._updatePagination();
            }
            this._tabLabelCount = this._labelWrappers.length;
        }
        if (this._selectedIndexChanged) {
            this._scrollToLabel(this._selectedIndex);
            if (this.nzShowPagination) {
                this._checkScrollingControls();
            }
            this._alignInkBarToSelectedTab();
            this._selectedIndexChanged = false;
        }
        if (this._scrollDistanceChanged) {
            if (this.nzShowPagination) {
                this._updateTabScrollPosition();
            }
            this._scrollDistanceChanged = false;
        }
    };
    NzTabsNavComponent.prototype.ngAfterContentInit = function () {
        var _this = this;
        this._realignInkBar = this._ngZone.runOutsideAngular(function () {
            var dirChange = _this._dir ? _this._dir.change : observableOf(null);
            var resize = typeof window !== 'undefined' ?
                auditTime.call(fromEvent(window, 'resize'), 10) :
                observableOf(null);
            return startWith.call(merge(dirChange, resize), null).subscribe(function () {
                if (_this.nzShowPagination) {
                    _this._updatePagination();
                }
                _this._alignInkBarToSelectedTab();
            });
        });
    };
    NzTabsNavComponent.prototype._updateTabScrollPosition = function () {
        var scrollDistance = this.scrollDistance;
        if (this.nzPositionMode === 'horizontal') {
            var translateX = this._getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance;
            this._renderer.setStyle(this._tabList.nativeElement, 'transform', "translate3d(" + translateX + "px, 0, 0)");
        }
        else {
            this._renderer.setStyle(this._tabList.nativeElement, 'transform', "translate3d(0," + -scrollDistance + "px, 0)");
        }
    };
    NzTabsNavComponent.prototype._updatePagination = function () {
        this._checkPaginationEnabled();
        this._checkScrollingControls();
        this._updateTabScrollPosition();
    };
    NzTabsNavComponent.prototype._checkPaginationEnabled = function () {
        this._showPaginationControls =
            this.tabListScrollWidthHeightPix > this.elementRefOffSetWidthHeight;
        if (!this._showPaginationControls) {
            this.scrollDistance = 0;
        }
    };
    NzTabsNavComponent.prototype._scrollToLabel = function (labelIndex) {
        var selectedLabel = this._labelWrappers
            ? this._labelWrappers.toArray()[labelIndex]
            : null;
        if (!selectedLabel) {
            return;
        }
        // The view length is the visible width of the tab labels.
        var labelBeforePos, labelAfterPos;
        if (this.nzPositionMode === 'horizontal') {
            if (this._getLayoutDirection() === 'ltr') {
                labelBeforePos = selectedLabel.getOffsetLeft();
                labelAfterPos = labelBeforePos + selectedLabel.getOffsetWidth();
            }
            else {
                labelAfterPos = this._tabList.nativeElement.offsetWidth - selectedLabel.getOffsetLeft();
                labelBeforePos = labelAfterPos - selectedLabel.getOffsetWidth();
            }
        }
        else {
            labelBeforePos = selectedLabel.getOffsetTop();
            labelAfterPos = labelBeforePos + selectedLabel.getOffsetHeight();
        }
        var beforeVisiblePos = this.scrollDistance;
        var afterVisiblePos = this.scrollDistance + this.viewWidthHeightPix;
        if (labelBeforePos < beforeVisiblePos) {
            // Scroll header to move label to the before direction
            this.scrollDistance -= beforeVisiblePos - labelBeforePos + EXAGGERATED_OVERSCROLL;
        }
        else if (labelAfterPos > afterVisiblePos) {
            // Scroll header to move label to the after direction
            this.scrollDistance += labelAfterPos - afterVisiblePos + EXAGGERATED_OVERSCROLL;
        }
    };
    NzTabsNavComponent.prototype._checkScrollingControls = function () {
        // Check if the pagination arrows should be activated.
        this._disableScrollBefore = this.scrollDistance === 0;
        this._disableScrollAfter = this.scrollDistance === this._getMaxScrollDistance();
    };
    /**
     * Determines what is the maximum length in pixels that can be set for the scroll distance. This
     * is equal to the difference in width between the tab list container and tab header container.
     *
     * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
     * should be called sparingly.
     */
    NzTabsNavComponent.prototype._getMaxScrollDistance = function () {
        return (this.tabListScrollWidthHeightPix - this.viewWidthHeightPix) || 0;
    };
    Object.defineProperty(NzTabsNavComponent.prototype, "scrollDistance", {
        get: function () {
            return this._scrollDistance;
        },
        /** Sets the distance in pixels that the tab header should be transformed in the X-axis. */
        set: function (v) {
            this._scrollDistance = Math.max(0, Math.min(this._getMaxScrollDistance(), v));
            // Mark that the scroll distance has changed so that after the view is checked, the CSS
            // transformation can move the header.
            this._scrollDistanceChanged = true;
            this._checkScrollingControls();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NzTabsNavComponent.prototype, "viewWidthHeightPix", {
        get: function () {
            var PAGINATION_PIX = 0;
            if (this._showPaginationControls) {
                PAGINATION_PIX = 64;
            }
            if (this.nzPositionMode === 'horizontal') {
                return this._tabListContainer.nativeElement.offsetWidth - PAGINATION_PIX;
            }
            else {
                return this._tabListContainer.nativeElement.offsetHeight - PAGINATION_PIX;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NzTabsNavComponent.prototype, "tabListScrollWidthHeightPix", {
        get: function () {
            if (this.nzPositionMode === 'horizontal') {
                return this._tabList.nativeElement.scrollWidth;
            }
            else {
                return this._tabList.nativeElement.scrollHeight;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NzTabsNavComponent.prototype, "elementRefOffSetWidthHeight", {
        get: function () {
            if (this.nzPositionMode === 'horizontal') {
                return this._elementRef.nativeElement.offsetWidth;
            }
            else {
                return this._elementRef.nativeElement.offsetHeight;
            }
        },
        enumerable: true,
        configurable: true
    });
    NzTabsNavComponent.prototype._getLayoutDirection = function () {
        return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
    };
    NzTabsNavComponent.prototype._alignInkBarToSelectedTab = function () {
        if (this.nzType === 'line') {
            var selectedLabelWrapper = this._labelWrappers && this._labelWrappers.length
                ? this._labelWrappers.toArray()[this.selectedIndex].elementRef.nativeElement
                : null;
            if (this._inkBar) {
                this._inkBar.alignToElement(selectedLabelWrapper);
            }
        }
    };
    return NzTabsNavComponent;
}());
export { NzTabsNavComponent };
NzTabsNavComponent.decorators = [
    { type: Component, args: [{
                selector: 'nz-tabs-nav',
                encapsulation: ViewEncapsulation.None,
                template: "\n    <div style=\"float:right;\" *ngIf=\"_tabBarExtraContent\">\n      <div class=\"ant-tabs-extra-content\">\n        <ng-template [ngTemplateOutlet]=\"_tabBarExtraContent\">\n        </ng-template>\n      </div>\n    </div>\n    <div class=\"ant-tabs-nav-container\" [class.ant-tabs-nav-container-scrolling]=\"_showPaginationControls\" #tabListContainer>\n      <span class=\"ant-tabs-tab-prev ant-tabs-tab-arrow-show\" (click)=\"_scrollHeader('before')\" [class.ant-tabs-tab-btn-disabled]=\"_disableScrollBefore\" *ngIf=\"_showPaginationControls\">\n        <span class=\"ant-tabs-tab-prev-icon\"></span>\n      </span>\n      <span class=\"ant-tabs-tab-next ant-tabs-tab-arrow-show\" (click)=\"_scrollHeader('after')\" [class.ant-tabs-tab-btn-disabled]=\"_disableScrollAfter\" *ngIf=\"_showPaginationControls\">\n        <span class=\"ant-tabs-tab-next-icon\"></span>\n      </span>\n      <div class=\"ant-tabs-nav-wrap\">\n        <div class=\"ant-tabs-nav-scroll\">\n          <div class=\"ant-tabs-nav\" [class.ant-tabs-nav-animated]=\"nzAnimated\" #tabList (cdkObserveContent)=\"_onContentChanges()\">\n            <div nz-tabs-ink-bar [hidden]=\"nzHideBar\" [nzAnimated]=\"nzAnimated\" [nzPositionMode]=\"nzPositionMode\" style=\"display: block;\"></div>\n            <ng-content></ng-content>\n          </div>\n        </div>\n      </div>\n    </div>"
            },] },
];
/** @nocollapse */
NzTabsNavComponent.ctorParameters = function () { return [
    { type: ElementRef, },
    { type: NgZone, },
    { type: Renderer2, },
    { type: Directionality, decorators: [{ type: Optional },] },
]; };
NzTabsNavComponent.propDecorators = {
    'nzAnimated': [{ type: Input },],
    'nzHideBar': [{ type: Input },],
    'nzSize': [{ type: Input },],
    'nzType': [{ type: Input },],
    '_tabBarExtraContent': [{ type: ContentChild, args: ['tabBarExtraContent',] },],
    '_labelWrappers': [{ type: ContentChildren, args: [NzTabLabelDirective,] },],
    '_inkBar': [{ type: ViewChild, args: [NzTabsInkBarDirective,] },],
    '_tabListContainer': [{ type: ViewChild, args: ['tabListContainer',] },],
    '_tabList': [{ type: ViewChild, args: ['tabList',] },],
    '_nzTabsBar': [{ type: HostBinding, args: ['class.ant-tabs-bar',] },],
    'nzShowPagination': [{ type: Input },],
    'nzPositionMode': [{ type: Input },],
    'selectedIndex': [{ type: Input },],
};
