import { Component, ViewEncapsulation, Input, EventEmitter, Output, Renderer2, ViewChild, ElementRef } from '@angular/core';
// import { Observable } from 'rxjs/Observable';
import { RxChain } from '@angular/cdk';
import { fromEvent } from 'rxjs/observable/fromEvent';
import { throttleTime } from 'rxjs/operator/throttleTime';
import { distinctUntilChanged } from 'rxjs/operator/distinctUntilChanged';
import { NzScrollService } from "../core/scroll/nz-scroll.service";
var NzAffixComponent = (function () {
    function NzAffixComponent(scrollSrv, _el, _renderer) {
        this.scrollSrv = scrollSrv;
        this._el = _el;
        this._renderer = _renderer;
        this.scroll$ = null;
        this.scrollWinInTarget$ = null;
        this.target = null;
        // 缓存固定状态
        this.fixed = false;
        this.nzOffsetTop = 0;
        this.nzOffsetBottom = 0;
        this.nzChange = new EventEmitter();
    }
    Object.defineProperty(NzAffixComponent.prototype, "nzTarget", {
        set: function (el) {
            this.target = el;
            this.registerScrollEvent();
        },
        enumerable: true,
        configurable: true
    });
    NzAffixComponent.prototype.ngOnInit = function () {
        if (!this.scroll$)
            this.registerScrollEvent();
    };
    NzAffixComponent.prototype.getTarget = function () {
        return this.target || window;
    };
    NzAffixComponent.prototype.reCalculate = function () {
        var elOffset = this.scrollSrv.getOffset(this._el.nativeElement);
        this.orgOffset = {
            top: elOffset.top + this.scrollSrv.getScroll(this.getTarget()),
            left: elOffset.left + this.scrollSrv.getScroll(this.getTarget(), false)
        };
        return this;
    };
    NzAffixComponent.prototype.process = function () {
        if (!this.orgOffset)
            this.reCalculate();
        var containerScrollTop = this.scrollSrv.getScroll(this.getTarget());
        var fixTop = this.getTarget() === window ? 0 : this.scrollSrv.getOffset(this.getTarget()).top;
        var hasFixed = this.orgOffset.top - fixTop - containerScrollTop - this.nzOffsetTop <= 0;
        if (this.fixed === hasFixed)
            return;
        var wrapEl = this.wrap.nativeElement;
        wrapEl.classList[hasFixed ? 'add' : 'remove']('ant-affix');
        if (hasFixed) {
            wrapEl.style.cssText = "top:" + (this.nzOffsetTop + fixTop) + "px;left:" + this.orgOffset.left + "px";
        }
        else {
            wrapEl.style.cssText = "";
        }
        this.fixed = hasFixed;
        this.nzChange.emit(hasFixed);
    };
    NzAffixComponent.prototype.removeListen = function () {
        if (this.scroll$)
            this.scroll$.unsubscribe();
        if (this.scrollWinInTarget$)
            this.scrollWinInTarget$.unsubscribe();
    };
    NzAffixComponent.prototype.registerScrollEvent = function () {
        var _this = this;
        this.removeListen();
        this.reCalculate().process();
        this.scroll$ = RxChain.from(fromEvent(this.getTarget(), 'scroll'))
            .call(throttleTime, 50)
            .call(distinctUntilChanged)
            .subscribe(function (e) {
            _this.process();
        });
        if (this.getTarget() !== window) {
            // 当 window 滚动位发生变动时，需要重新计算滚动容器
            this.scrollWinInTarget$ = RxChain.from(fromEvent(window, 'scroll'))
                .call(throttleTime, 50)
                .call(distinctUntilChanged)
                .subscribe(function (e) {
                _this.orgOffset = null;
                _this.fixed = false;
            });
        }
    };
    NzAffixComponent.prototype.ngOnDestroy = function () {
        this.removeListen();
    };
    return NzAffixComponent;
}());
export { NzAffixComponent };
NzAffixComponent.decorators = [
    { type: Component, args: [{
                selector: 'nz-affix',
                encapsulation: ViewEncapsulation.None,
                template: "<div #wrap><ng-content></ng-content></div>",
                styles: [
                    "/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */\n/* stylelint-disable declaration-bang-space-before */\n/* stylelint-disable declaration-bang-space-before */\n.ant-affix {\n  position: fixed;\n  z-index: 10;\n}\n",
                    "nz-affix {\n  display: block;\n}\n"
                ]
            },] },
];
/** @nocollapse */
NzAffixComponent.ctorParameters = function () { return [
    { type: NzScrollService, },
    { type: ElementRef, },
    { type: Renderer2, },
]; };
NzAffixComponent.propDecorators = {
    'wrap': [{ type: ViewChild, args: ['wrap',] },],
    'nzTarget': [{ type: Input },],
    'nzOffsetTop': [{ type: Input },],
    'nzOffsetBottom': [{ type: Input },],
    'nzChange': [{ type: Output },],
};
