var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
(function (factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === 'function' && define.amd) {
        define(["require", "exports", '@angular/core', '../app/app', '../../config/config', '../../util/dom-controller', '../ion', '../../util/util', '../../util/keyboard', '../../util/scroll-view', '../tabs/tabs', '../../util/dom', '../../navigation/view-controller', '../../util/scroll-view'], factory);
    }
})(function (require, exports) {
    "use strict";
    var core_1 = require('@angular/core');
    var app_1 = require('../app/app');
    var config_1 = require('../../config/config');
    var dom_controller_1 = require('../../util/dom-controller');
    var ion_1 = require('../ion');
    var util_1 = require('../../util/util');
    var keyboard_1 = require('../../util/keyboard');
    var scroll_view_1 = require('../../util/scroll-view');
    var tabs_1 = require('../tabs/tabs');
    var dom_1 = require('../../util/dom');
    var view_controller_1 = require('../../navigation/view-controller');
    var scroll_view_2 = require('../../util/scroll-view');
    exports.ScrollDirection = scroll_view_2.ScrollDirection;
    var Content = (function (_super) {
        __extends(Content, _super);
        function Content(config, elementRef, renderer, _app, _keyboard, _zone, viewCtrl, _tabs, _dom) {
            _super.call(this, config, elementRef, renderer, 'content');
            this._app = _app;
            this._keyboard = _keyboard;
            this._zone = _zone;
            this._tabs = _tabs;
            this._dom = _dom;
            this._scrollPadding = 0;
            this._inputPolling = false;
            this._imgs = [];
            this.scrollHeight = 0;
            this.scrollWidth = 0;
            this.ionScrollStart = new core_1.EventEmitter();
            this.ionScroll = new core_1.EventEmitter();
            this.ionScrollEnd = new core_1.EventEmitter();
            this.readReady = new core_1.EventEmitter();
            this.writeReady = new core_1.EventEmitter();
            this.statusbarPadding = config.getBoolean('statusbarPadding', false);
            if (viewCtrl) {
                viewCtrl._setIONContent(this);
                viewCtrl._setIONContentRef(elementRef);
            }
            this._scroll = new scroll_view_1.ScrollView(_dom);
        }
        Object.defineProperty(Content.prototype, "scrollTop", {
            get: function () {
                return this._scroll.getTop();
            },
            set: function (top) {
                this._scroll.setTop(top);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "scrollLeft", {
            get: function () {
                return this._scroll.getLeft();
            },
            set: function (top) {
                this._scroll.setLeft(top);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "isScrolling", {
            get: function () {
                return this._scroll.isScrolling;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "velocityY", {
            get: function () {
                return this._scroll.ev.velocityY || 0;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "velocityX", {
            get: function () {
                return this._scroll.ev.velocityX || 0;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "directionY", {
            get: function () {
                return this._scroll.ev.directionY;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Content.prototype, "directionX", {
            get: function () {
                return this._scroll.ev.directionX;
            },
            enumerable: true,
            configurable: true
        });
        Content.prototype.ngOnInit = function () {
            var _this = this;
            if (this._scrollEle)
                return;
            var children = this._elementRef.nativeElement.children;
            (void 0);
            this._fixedEle = children[0];
            this._scrollEle = children[1];
            this._scroll.scrollStart.subscribe(function (ev) {
                _this.ionScrollStart.emit(ev);
            });
            this._scroll.scroll.subscribe(function (ev) {
                _this._app.setScrolling(ev.timeStamp);
                _this.ionScroll.emit(ev);
                _this.imgsUpdate();
            });
            this._scroll.scrollEnd.subscribe(function (ev) {
                _this.ionScrollEnd.emit(ev);
                _this.imgsUpdate();
            });
        };
        Content.prototype.ngOnDestroy = function () {
            this._scLsn && this._scLsn();
            this._scroll && this._scroll.destroy();
            this._scrollEle = this._fixedEle = this._footerEle = this._scLsn = this._scroll = null;
        };
        Content.prototype.getScrollElement = function () {
            return this._scrollEle;
        };
        Content.prototype.onScrollElementTransitionEnd = function (callback) {
            dom_1.transitionEnd(this._scrollEle, callback);
        };
        Content.prototype.scrollTo = function (x, y, duration, done) {
            if (duration === void 0) { duration = 300; }
            (void 0);
            return this._scroll.scrollTo(x, y, duration, done);
        };
        Content.prototype.scrollToTop = function (duration) {
            if (duration === void 0) { duration = 300; }
            (void 0);
            return this._scroll.scrollToTop(duration);
        };
        Content.prototype.scrollToBottom = function (duration) {
            if (duration === void 0) { duration = 300; }
            (void 0);
            return this._scroll.scrollToBottom(duration);
        };
        Content.prototype.enableJsScroll = function () {
            this._scroll.enableJsScroll(this.contentTop, this.contentBottom);
        };
        Object.defineProperty(Content.prototype, "fullscreen", {
            get: function () {
                return !!this._fullscreen;
            },
            set: function (val) {
                this._fullscreen = util_1.isTrueProperty(val);
            },
            enumerable: true,
            configurable: true
        });
        Content.prototype.addImg = function (img) {
            this._imgs.push(img);
        };
        Content.prototype.removeImg = function (img) {
            util_1.removeArrayItem(this._imgs, img);
        };
        Content.prototype.setScrollElementStyle = function (prop, val) {
            var _this = this;
            this._dom.write(function () {
                _this._scrollEle.style[prop] = val;
            });
        };
        Content.prototype.getContentDimensions = function () {
            var scrollEle = this._scrollEle;
            var parentElement = scrollEle.parentElement;
            return {
                contentHeight: parentElement.offsetHeight - this.contentTop - this.contentBottom,
                contentTop: this.contentTop,
                contentBottom: this.contentBottom,
                contentWidth: parentElement.offsetWidth,
                contentLeft: parentElement.offsetLeft,
                scrollHeight: scrollEle.scrollHeight,
                scrollTop: scrollEle.scrollTop,
                scrollWidth: scrollEle.scrollWidth,
                scrollLeft: scrollEle.scrollLeft,
            };
        };
        Content.prototype.addScrollPadding = function (newPadding) {
            var _this = this;
            (void 0);
            if (newPadding > this._scrollPadding) {
                (void 0);
                this._scrollPadding = newPadding;
                if (this._scrollEle) {
                    this._dom.write(function () {
                        if (_this._scrollEle) {
                            _this._scrollEle.style.paddingBottom = (newPadding > 0) ? newPadding + 'px' : '';
                        }
                    });
                }
            }
        };
        Content.prototype.clearScrollPaddingFocusOut = function () {
            var _this = this;
            if (!this._inputPolling) {
                (void 0);
                this._inputPolling = true;
                this._keyboard.onClose(function () {
                    (void 0);
                    _this._inputPolling = false;
                    _this._scrollPadding = -1;
                    _this.addScrollPadding(0);
                }, 200, 3000);
            }
        };
        Content.prototype.resize = function () {
            this._dom.read(this.readDimensions, this);
            this._dom.write(this.writeDimensions, this);
        };
        Content.prototype.readDimensions = function () {
            var cachePaddingTop = this._pTop;
            var cachePaddingRight = this._pRight;
            var cachePaddingBottom = this._pBottom;
            var cachePaddingLeft = this._pLeft;
            var cacheHeaderHeight = this._hdrHeight;
            var cacheFooterHeight = this._ftrHeight;
            var cacheTabsPlacement = this._tabsPlacement;
            var tabsTop = 0;
            this.scrollWidth = 0;
            this.scrollHeight = 0;
            this._pTop = 0;
            this._pRight = 0;
            this._pBottom = 0;
            this._pLeft = 0;
            this._hdrHeight = 0;
            this._ftrHeight = 0;
            this._tabsPlacement = null;
            this._tTop = 0;
            this._fTop = 0;
            this._fBottom = 0;
            var ele = this._elementRef.nativeElement;
            if (!ele) {
                (void 0);
                return;
            }
            var computedStyle;
            var tagName;
            var parentEle = ele.parentElement;
            var children = parentEle.children;
            for (var i = children.length - 1; i >= 0; i--) {
                ele = children[i];
                tagName = ele.tagName;
                if (tagName === 'ION-CONTENT') {
                    this.scrollWidth = ele.scrollWidth;
                    this.scrollHeight = ele.scrollHeight;
                    if (this._fullscreen) {
                        computedStyle = getComputedStyle(ele);
                        this._pTop = parsePxUnit(computedStyle.paddingTop);
                        this._pBottom = parsePxUnit(computedStyle.paddingBottom);
                        this._pRight = parsePxUnit(computedStyle.paddingRight);
                        this._pLeft = parsePxUnit(computedStyle.paddingLeft);
                    }
                }
                else if (tagName === 'ION-HEADER') {
                    this._hdrHeight = ele.clientHeight;
                }
                else if (tagName === 'ION-FOOTER') {
                    this._ftrHeight = ele.clientHeight;
                    this._footerEle = ele;
                }
            }
            ele = parentEle;
            var tabbarEle;
            while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
                if (ele.tagName === 'ION-TABS') {
                    tabbarEle = ele.firstElementChild;
                    this._tabbarHeight = tabbarEle.clientHeight;
                    if (this._tabsPlacement === null) {
                        this._tabsPlacement = ele.getAttribute('tabsplacement');
                    }
                }
                ele = ele.parentElement;
            }
            if (this._tabs && this._tabsPlacement === 'top') {
                this._tTop = this._hdrHeight;
                tabsTop = this._tabs._top;
            }
            this._cTop = this._hdrHeight;
            this._cBottom = this._ftrHeight;
            if (this._tabsPlacement === 'top') {
                this._cTop += this._tabbarHeight;
            }
            else if (this._tabsPlacement === 'bottom') {
                this._cBottom += this._tabbarHeight;
            }
            this._fTop = this._cTop;
            this._fBottom = this._cBottom;
            if (this._fullscreen) {
                this._cTop += this._pTop;
                this._cBottom += this._pBottom;
            }
            this._dirty = (cachePaddingTop !== this._pTop ||
                cachePaddingBottom !== this._pBottom ||
                cachePaddingLeft !== this._pLeft ||
                cachePaddingRight !== this._pRight ||
                cacheHeaderHeight !== this._hdrHeight ||
                cacheFooterHeight !== this._ftrHeight ||
                cacheTabsPlacement !== this._tabsPlacement ||
                tabsTop !== this._tTop ||
                this._cTop !== this.contentTop ||
                this._cBottom !== this.contentBottom);
            this._scroll.init(this._scrollEle, this._cTop, this._cBottom);
            this.imgsUpdate();
            this.readReady.emit();
        };
        Content.prototype.writeDimensions = function () {
            if (!this._dirty) {
                (void 0);
                return;
            }
            var scrollEle = this._scrollEle;
            if (!scrollEle) {
                (void 0);
                return;
            }
            var fixedEle = this._fixedEle;
            if (!fixedEle) {
                (void 0);
                return;
            }
            if (this._tabsPlacement === 'bottom' && this._cBottom > 0 && this._footerEle) {
                var footerPos = this._cBottom - this._ftrHeight;
                (void 0);
                this._footerEle.style.bottom = cssFormat(footerPos);
            }
            var topProperty = 'marginTop';
            var bottomProperty = 'marginBottom';
            var fixedTop = this._fTop;
            var fixedBottom = this._fBottom;
            if (this._fullscreen) {
                (void 0);
                (void 0);
                topProperty = 'paddingTop';
                bottomProperty = 'paddingBottom';
            }
            if (this._cTop !== this.contentTop) {
                (void 0);
                (void 0);
                scrollEle.style[topProperty] = cssFormat(this._cTop);
                fixedEle.style.marginTop = cssFormat(fixedTop);
                this.contentTop = this._cTop;
            }
            if (this._cBottom !== this.contentBottom) {
                (void 0);
                (void 0);
                scrollEle.style[bottomProperty] = cssFormat(this._cBottom);
                fixedEle.style.marginBottom = cssFormat(fixedBottom);
                this.contentBottom = this._cBottom;
            }
            if (this._tabsPlacement !== null && this._tabs) {
                if (this._tabsPlacement === 'top') {
                    this._tabs.setTabbarPosition(this._tTop, -1);
                }
                else {
                    (void 0);
                    this._tabs.setTabbarPosition(-1, 0);
                }
            }
            this.writeReady.emit();
        };
        Content.prototype.imgsUpdate = function () {
            if (this._imgs.length && this.isImgsUpdatable()) {
                updateImgs(this._imgs, this.scrollTop, this.scrollHeight, this.directionY, IMG_REQUESTABLE_BUFFER, IMG_RENDERABLE_BUFFER);
            }
        };
        Content.prototype.isImgsUpdatable = function () {
            return Math.abs(this.velocityY) < 3;
        };
        Content.decorators = [
            { type: core_1.Component, args: [{
                        selector: 'ion-content',
                        template: '<div class="fixed-content">' +
                            '<ng-content select="[ion-fixed],ion-fab"></ng-content>' +
                            '</div>' +
                            '<div class="scroll-content">' +
                            '<ng-content></ng-content>' +
                            '</div>' +
                            '<ng-content select="ion-refresher"></ng-content>',
                        host: {
                            '[class.statusbar-padding]': 'statusbarPadding'
                        },
                        changeDetection: core_1.ChangeDetectionStrategy.OnPush,
                        encapsulation: core_1.ViewEncapsulation.None
                    },] },
        ];
        Content.ctorParameters = [
            { type: config_1.Config, },
            { type: core_1.ElementRef, },
            { type: core_1.Renderer, },
            { type: app_1.App, },
            { type: keyboard_1.Keyboard, },
            { type: core_1.NgZone, },
            { type: view_controller_1.ViewController, decorators: [{ type: core_1.Optional },] },
            { type: tabs_1.Tabs, decorators: [{ type: core_1.Optional },] },
            { type: dom_controller_1.DomController, },
        ];
        Content.propDecorators = {
            'ionScrollStart': [{ type: core_1.Output },],
            'ionScroll': [{ type: core_1.Output },],
            'ionScrollEnd': [{ type: core_1.Output },],
            'readReady': [{ type: core_1.Output },],
            'writeReady': [{ type: core_1.Output },],
            'fullscreen': [{ type: core_1.Input },],
        };
        return Content;
    }(ion_1.Ion));
    exports.Content = Content;
    function updateImgs(imgs, scrollTop, scrollHeight, scrollDirectionY, requestableBuffer, renderableBuffer) {
        var scrollBottom = (scrollTop + scrollHeight);
        var priority1 = [];
        var priority2 = [];
        var img;
        for (var i = 0, ilen = imgs.length; i < ilen; i++) {
            img = imgs[i];
            if (scrollDirectionY === scroll_view_1.ScrollDirection.Up) {
                if (img.top < scrollBottom && img.bottom > scrollTop - renderableBuffer) {
                    img.canRequest = img.canRender = true;
                    priority1.push(img);
                    continue;
                }
                if (img.bottom <= scrollTop && img.bottom > scrollTop - requestableBuffer) {
                    img.canRequest = true;
                    img.canRender = false;
                    priority2.push(img);
                    continue;
                }
                if (img.top >= scrollBottom && img.top < scrollBottom + renderableBuffer) {
                    img.canRequest = img.canRender = false;
                    continue;
                }
            }
            else {
                if (img.bottom > scrollTop && img.top < scrollBottom + renderableBuffer) {
                    img.canRequest = img.canRender = true;
                    priority1.push(img);
                    continue;
                }
                if (img.top >= scrollBottom && img.top < scrollBottom + requestableBuffer) {
                    img.canRequest = true;
                    img.canRender = false;
                    priority2.push(img);
                    continue;
                }
                if (img.bottom <= scrollTop && img.bottom > scrollTop - renderableBuffer) {
                    img.canRequest = img.canRender = false;
                    continue;
                }
            }
            img.canRequest = img.canRender = false;
            img.reset();
        }
        priority1.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
        if (scrollDirectionY === scroll_view_1.ScrollDirection.Up) {
            priority2.sort(sortTopToBottom).reverse().forEach(function (i) { return i.update(); });
        }
        else {
            priority2.sort(sortTopToBottom).forEach(function (i) { return i.update(); });
        }
    }
    exports.updateImgs = updateImgs;
    var IMG_REQUESTABLE_BUFFER = 1200;
    var IMG_RENDERABLE_BUFFER = 300;
    function sortTopToBottom(a, b) {
        if (a.top < b.top) {
            return -1;
        }
        if (a.top > b.top) {
            return 1;
        }
        return 0;
    }
    function parsePxUnit(val) {
        return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
    }
    function cssFormat(val) {
        return (val > 0 ? val + 'px' : '');
    }
});
//# sourceMappingURL=content.js.map