import { Directive, ElementRef, EventEmitter, Host, Input, NgZone, Output } from '@angular/core';
import { Content } from '../content/content';
import { DomController } from '../../util/dom-controller';
export class InfiniteScroll {
    constructor(_content, _zone, _elementRef, _dom) {
        this._content = _content;
        this._zone = _zone;
        this._elementRef = _elementRef;
        this._dom = _dom;
        this._lastCheck = 0;
        this._highestY = 0;
        this._thr = '15%';
        this._thrPx = 0;
        this._thrPc = 0.15;
        this._init = false;
        this.state = STATE_ENABLED;
        this.ionInfinite = new EventEmitter();
        _content.setElementClass('has-infinite-scroll', true);
    }
    get threshold() {
        return this._thr;
    }
    set threshold(val) {
        this._thr = val;
        if (val.indexOf('%') > -1) {
            this._thrPx = 0;
            this._thrPc = (parseFloat(val) / 100);
        }
        else {
            this._thrPx = parseFloat(val);
            this._thrPc = 0;
        }
    }
    set enabled(shouldEnable) {
        this.enable(shouldEnable);
    }
    _onScroll(ev) {
        if (this.state === STATE_LOADING || this.state === STATE_DISABLED) {
            return 1;
        }
        if (this._lastCheck + 32 > ev.timeStamp) {
            return 2;
        }
        this._lastCheck = ev.timeStamp;
        const infiniteHeight = this._elementRef.nativeElement.scrollHeight;
        if (!infiniteHeight) {
            return 3;
        }
        const d = this._content.getContentDimensions();
        let reloadY = d.contentHeight;
        if (this._thrPc) {
            reloadY += (reloadY * this._thrPc);
        }
        else {
            reloadY += this._thrPx;
        }
        const distanceFromInfinite = ((d.scrollHeight - infiniteHeight) - d.scrollTop) - reloadY;
        if (distanceFromInfinite < 0) {
            this._dom.write(() => {
                this._zone.run(() => {
                    if (this.state !== STATE_LOADING && this.state !== STATE_DISABLED) {
                        this.state = STATE_LOADING;
                        this.ionInfinite.emit(this);
                    }
                });
            });
            return 5;
        }
        return 6;
    }
    complete() {
        this.state = STATE_ENABLED;
    }
    enable(shouldEnable) {
        this.state = (shouldEnable ? STATE_ENABLED : STATE_DISABLED);
        this._setListeners(shouldEnable);
    }
    _setListeners(shouldListen) {
        if (this._init) {
            if (shouldListen) {
                if (!this._scLsn) {
                    this._scLsn = this._content.ionScroll.subscribe((ev) => {
                        this._onScroll(ev);
                    });
                }
            }
            else {
                this._scLsn && this._scLsn.unsubscribe();
                this._scLsn = null;
            }
        }
    }
    ngAfterContentInit() {
        this._init = true;
        this._setListeners(this.state !== STATE_DISABLED);
    }
    ngOnDestroy() {
        this._setListeners(false);
    }
}
InfiniteScroll.decorators = [
    { type: Directive, args: [{
                selector: 'ion-infinite-scroll'
            },] },
];
InfiniteScroll.ctorParameters = [
    { type: Content, decorators: [{ type: Host },] },
    { type: NgZone, },
    { type: ElementRef, },
    { type: DomController, },
];
InfiniteScroll.propDecorators = {
    'threshold': [{ type: Input },],
    'enabled': [{ type: Input },],
    'ionInfinite': [{ type: Output },],
};
const STATE_ENABLED = 'enabled';
const STATE_DISABLED = 'disabled';
const STATE_LOADING = 'loading';
//# sourceMappingURL=infinite-scroll.js.map