"use strict";
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 __());
};
var core_1 = require('@angular/core');
var app_1 = require('../app/app');
var ion_1 = require('../ion');
var config_1 = require('../../config/config');
var keyboard_1 = require('../../util/keyboard');
var dom_1 = require('../../util/dom');
var scroll_view_1 = require('../../util/scroll-view');
var tabs_1 = require('../tabs/tabs');
var view_controller_1 = require('../../navigation/view-controller');
var util_1 = require('../../util/util');
var Content = (function (_super) {
    __extends(Content, _super);
    function Content(config, elementRef, renderer, _app, _keyboard, _zone, viewCtrl, _tabs) {
        _super.call(this, config, elementRef, renderer);
        this._app = _app;
        this._keyboard = _keyboard;
        this._zone = _zone;
        this._tabs = _tabs;
        this._inputPolling = false;
        this._mode = config.get('mode');
        this._setMode('content', this._mode);
        this._sbPadding = config.getBoolean('statusbarPadding', false);
        if (viewCtrl) {
            viewCtrl._setContent(this);
            viewCtrl._setContentRef(elementRef);
        }
    }
    Content.prototype.ngOnInit = function () {
        var _this = this;
        this._scrollEle = this._elementRef.nativeElement.children[0];
        this._zone.runOutsideAngular(function () {
            _this._scroll = new scroll_view_1.ScrollView(_this._scrollEle);
            _this._scLsn = _this.addScrollListener(_this._app.setScrolling);
        });
    };
    Content.prototype.ngOnDestroy = function () {
        this._scLsn && this._scLsn();
        this._scroll && this._scroll.destroy();
        this._scrollEle = this._footerEle = this._scLsn = this._scroll = null;
    };
    Content.prototype.addScrollListener = function (handler) {
        return this._addListener('scroll', handler);
    };
    Content.prototype.addTouchStartListener = function (handler) {
        return this._addListener('touchstart', handler);
    };
    Content.prototype.addTouchMoveListener = function (handler) {
        return this._addListener('touchmove', handler);
    };
    Content.prototype.addTouchEndListener = function (handler) {
        return this._addListener('touchend', handler);
    };
    Content.prototype.addMouseDownListener = function (handler) {
        return this._addListener('mousedown', handler);
    };
    Content.prototype.addMouseUpListener = function (handler) {
        return this._addListener('mouseup', handler);
    };
    Content.prototype.addMouseMoveListener = function (handler) {
        return this._addListener('mousemove', handler);
    };
    Content.prototype._addListener = function (type, handler) {
        var _this = this;
        if (!this._scrollEle) {
            return;
        }
        this._scrollEle.removeEventListener(type, handler);
        this._scrollEle.addEventListener(type, handler);
        return function () {
            if (_this._scrollEle) {
                _this._scrollEle.removeEventListener(type, handler);
            }
        };
    };
    Content.prototype.getScrollElement = function () {
        return this._scrollEle;
    };
    Content.prototype.onScrollEnd = function (callback) {
        var lastScrollTop = null;
        var framesUnchanged = 0;
        var _scrollEle = this._scrollEle;
        function next() {
            var currentScrollTop = _scrollEle.scrollTop;
            if (lastScrollTop !== null) {
                if (Math.round(lastScrollTop) === Math.round(currentScrollTop)) {
                    framesUnchanged++;
                }
                else {
                    framesUnchanged = 0;
                }
                if (framesUnchanged > 9) {
                    return callback();
                }
            }
            lastScrollTop = currentScrollTop;
            dom_1.nativeRaf(function () {
                dom_1.nativeRaf(next);
            });
        }
        dom_1.nativeTimeout(next, 100);
    };
    Content.prototype.onScrollElementTransitionEnd = function (callback) {
        dom_1.transitionEnd(this._scrollEle, callback);
    };
    Content.prototype.scrollTo = function (x, y, duration) {
        if (duration === void 0) { duration = 300; }
        return this._scroll.scrollTo(x, y, duration);
    };
    Content.prototype.scrollToTop = function (duration) {
        if (duration === void 0) { duration = 300; }
        return this._scroll.scrollToTop(duration);
    };
    Content.prototype.getScrollTop = function () {
        return this._scroll.getTop();
    };
    Content.prototype.setScrollTop = function (top) {
        this._scroll.setTop(top);
    };
    Content.prototype.scrollToBottom = function (duration) {
        if (duration === void 0) { duration = 300; }
        return this._scroll.scrollToBottom(duration);
    };
    Content.prototype.jsScroll = function (onScrollCallback) {
        return this._scroll.jsScroll(onScrollCallback);
    };
    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.setScrollElementStyle = function (prop, val) {
        this._scrollEle.style[prop] = val;
    };
    Content.prototype.getContentDimensions = function () {
        var _scrollEle = this._scrollEle;
        var parentElement = _scrollEle.parentElement;
        return {
            contentHeight: parentElement.offsetHeight,
            contentTop: parentElement.offsetTop,
            contentBottom: parentElement.offsetTop + parentElement.offsetHeight,
            contentWidth: parentElement.offsetWidth,
            contentLeft: parentElement.offsetLeft,
            contentRight: parentElement.offsetLeft + parentElement.offsetWidth,
            scrollHeight: _scrollEle.scrollHeight,
            scrollTop: _scrollEle.scrollTop,
            scrollBottom: _scrollEle.scrollTop + _scrollEle.scrollHeight,
            scrollWidth: _scrollEle.scrollWidth,
            scrollLeft: _scrollEle.scrollLeft,
            scrollRight: _scrollEle.scrollLeft + _scrollEle.scrollWidth,
        };
    };
    Content.prototype.addScrollPadding = function (newPadding) {
        if (newPadding > this._scrollPadding) {
            console.debug('content addScrollPadding', newPadding);
            this._scrollPadding = newPadding;
            this._scrollEle.style.paddingBottom = newPadding + 'px';
        }
    };
    Content.prototype.clearScrollPaddingFocusOut = function () {
        var _this = this;
        if (!this._inputPolling) {
            this._inputPolling = true;
            this._keyboard.onClose(function () {
                _this._scrollPadding = 0;
                _this._scrollEle.style.paddingBottom = (_this._paddingBottom > 0 ? _this._paddingBottom + 'px' : '');
                _this._inputPolling = false;
                _this.addScrollPadding(0);
            }, 200, Infinity);
        }
    };
    Content.prototype.resize = function () {
        var _this = this;
        dom_1.nativeRaf(function () {
            _this.readDimensions();
            _this.writeDimensions();
        });
    };
    Content.prototype.readDimensions = function () {
        this._paddingTop = 0;
        this._paddingRight = 0;
        this._paddingBottom = 0;
        this._paddingLeft = 0;
        this._headerHeight = 0;
        this._footerHeight = 0;
        this._tabsPlacement = null;
        var ele = this._elementRef.nativeElement;
        if (!ele)
            return;
        var parentEle = ele.parentElement;
        var computedStyle;
        for (var i = 0; i < parentEle.children.length; i++) {
            ele = parentEle.children[i];
            if (ele.tagName === 'ION-CONTENT') {
                if (this._fullscreen) {
                    computedStyle = getComputedStyle(ele);
                    this._paddingTop = parsePxUnit(computedStyle.paddingTop);
                    this._paddingBottom = parsePxUnit(computedStyle.paddingBottom);
                    this._paddingRight = parsePxUnit(computedStyle.paddingRight);
                    this._paddingLeft = parsePxUnit(computedStyle.paddingLeft);
                }
            }
            else if (ele.tagName === 'ION-HEADER') {
                this._headerHeight = ele.clientHeight;
            }
            else if (ele.tagName === 'ION-FOOTER') {
                this._footerHeight = 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;
        }
    };
    Content.prototype.writeDimensions = function () {
        var newVal;
        var scrollEle = this._scrollEle;
        if (!scrollEle)
            return;
        if (this._fullscreen) {
            newVal = this._headerHeight + this._paddingTop;
            if (this._tabsPlacement === 'top') {
                newVal += this._tabbarHeight;
            }
            if (newVal !== this.contentTop) {
                scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
                this.contentTop = newVal;
            }
            newVal = this._footerHeight + this._paddingBottom;
            if (this._tabsPlacement === 'bottom') {
                newVal += this._tabbarHeight;
                if (newVal > 0 && this._footerEle) {
                    this._footerEle.style.bottom = (newVal - this._footerHeight - this._paddingBottom) + 'px';
                }
            }
            if (newVal !== this.contentBottom) {
                scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : '');
                this.contentBottom = newVal;
            }
        }
        else {
            newVal = this._headerHeight;
            if (this._tabsPlacement === 'top') {
                newVal += this._tabbarHeight;
            }
            if (newVal !== this.contentTop) {
                scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : '');
                this.contentTop = newVal;
            }
            newVal = this._footerHeight;
            if (this._tabsPlacement === 'bottom') {
                newVal += this._tabbarHeight;
            }
            if (newVal !== this.contentBottom) {
                scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : '');
                this.contentBottom = newVal;
                if (newVal > 0 && this._footerEle) {
                    this._footerEle.style.bottom = (newVal - this._footerHeight) + 'px';
                }
            }
        }
        if (this._tabsPlacement !== null && this._tabs) {
            if (this._tabsPlacement === 'top') {
                this._tabs.setTabbarPosition(this._headerHeight, -1);
            }
            else {
                this._tabs.setTabbarPosition(-1, 0);
            }
        }
    };
    Content.decorators = [
        { type: core_1.Component, args: [{
                    selector: 'ion-content',
                    template: '<div class="scroll-content">' +
                        '<ng-content></ng-content>' +
                        '</div>' +
                        '<ng-content select="ion-fixed"></ng-content>' +
                        '<ng-content select="ion-refresher"></ng-content>',
                    host: {
                        '[class.statusbar-padding]': '_sbPadding'
                    },
                    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 },] },
    ];
    Content.propDecorators = {
        'fullscreen': [{ type: core_1.Input },],
    };
    return Content;
}(ion_1.Ion));
exports.Content = Content;
function parsePxUnit(val) {
    return (val.indexOf('px') > 0) ? parseInt(val, 10) : 0;
}
