"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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var core_1 = require('@angular/core');
var app_1 = require('../app/app');
var config_1 = require('../../config/config');
var tab_button_1 = require('./tab-button');
var tab_highlight_1 = require('./tab-highlight');
var ion_1 = require('../ion');
var platform_1 = require('../../platform/platform');
var nav_controller_1 = require('../nav/nav-controller');
var view_controller_1 = require('../nav/view-controller');
var util_1 = require('../../util/util');
/**
 * @name Tabs
 * @description
 * Tabs make it easy to navigate between different pages or functional
 * aspects of an app. The Tabs component, written as `<ion-tabs>`, is
 * a container of individual [Tab](../Tab/) components.
 *
 * ### Placement
 *
 * The position of the tabs relative to the content varies based on
 * the mode. By default, the tabs are placed at the bottom of the screen
 * for `ios` mode, and at the top for the `md` and `wp` modes. You can
 * configure the position using the `tabbarPlacement` property on the
 * `<ion-tabs>` element, or in your app's [config](../../config/Config/).
 * See the [Input Properties](#input-properties) below for the available
 * values of `tabbarPlacement`.
 *
 * ### Layout
 *
 * The layout for all of the tabs can be defined using the `tabbarLayout`
 * property. If the individual tab has a title and icon, the icons will
 * show on top of the title by default. All tabs can be changed by setting
 * the value of `tabbarLayout` on the `<ion-tabs>` element, or in your
 * app's [config](../../config/Config/). For example, this is useful if
 * you want to show tabs with a title only on Android, but show icons
 * and a title for iOS. See the [Input Properties](#input-properties)
 * below for the available values of `tabbarLayout`.
 *
 * ### Selecting a Tab
 *
 * There are different ways you can select a specific tab from the tabs
 * component. You can use the `selectedIndex` property to set the index
 * on the `<ion-tabs>` element, or you can call `select()` from the `Tabs`
 * instance after creation. See [usage](#usage) below for more information.
 *
 * @usage
 *
 * You can add a basic tabs template to a `@Page` using the following
 * template:
 *
 * ```html
 * <ion-tabs>
 *   <ion-tab [root]="tab1Root"></ion-tab>
 *   <ion-tab [root]="tab2Root"></ion-tab>
 *   <ion-tab [root]="tab3Root"></ion-tab>
 * </ion-tabs>
 * ```
 *
 * Where `tab1Root`, `tab2Root`, and `tab3Root` are each a page:
 *
 *```ts
 * @Page({
 *   templateUrl: 'build/pages/tabs/tabs.html'
 * })
 * export class TabsPage {
 *   // this tells the tabs component which Pages
 *   // should be each tab's root Page
 *   tab1Root = Page1;
 *   tab2Root = Page2;
 *   tab3Root = Page3;
 *
 *   constructor() {
 *
 *   }
 * }
 *```
 *
 * By default, the first tab will be selected upon navigation to the
 * Tabs page. We can change the selected tab by using `selectedIndex`
 * on the `<ion-tabs>` element:
 *
 * ```html
 * <ion-tabs selectedIndex="2">
 *   <ion-tab [root]="tab1Root"></ion-tab>
 *   <ion-tab [root]="tab2Root"></ion-tab>
 *   <ion-tab [root]="tab3Root"></ion-tab>
 * </ion-tabs>
 * ```
 *
 * Since the index starts at `0`, this will select the 3rd tab which has
 * root set to `tab3Root`. If you wanted to change it dynamically from
 * your class, you could use [property binding](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding).
 *
 * Alternatively, you can grab the `Tabs` instance and call the `select()`
 * method. This requires the `<ion-tabs>` element to have an `id`. For
 * example, set the value of `id` to `myTabs`:
 *
 * ```html
 * <ion-tabs #myTabs>
 *   <ion-tab [root]="tab1Root"></ion-tab>
 *   <ion-tab [root]="tab2Root"></ion-tab>
 *   <ion-tab [root]="tab3Root"></ion-tab>
 * </ion-tabs>
 * ```
 *
 * Then in your class you can grab the `Tabs` instance and call `select()`,
 * passing the index of the tab as the argument. Here we're grabbing the tabs
 * by using ViewChild.
 *
 *```ts
 * export class TabsPage {
 *
 * @ViewChild('myTabs') tabRef: Tabs;
 *
 * onPageDidEnter() {
 *   this.tabRef.select(2);
 *  }
 *
 * }
 *```
 *
 * @demo /docs/v2/demos/tabs/
 *
 * @see {@link /docs/v2/components#tabs Tabs Component Docs}
 * @see {@link ../Tab Tab API Docs}
 * @see {@link ../../config/Config Config API Docs}
 *
 */
var Tabs = (function (_super) {
    __extends(Tabs, _super);
    function Tabs(parent, viewCtrl, _app, _config, _elementRef, _platform, _renderer) {
        var _this = this;
        _super.call(this, _elementRef);
        this._app = _app;
        this._config = _config;
        this._elementRef = _elementRef;
        this._platform = _platform;
        this._renderer = _renderer;
        this._ids = -1;
        this._preloadTabs = null;
        this._tabs = [];
        this._onReady = null;
        /**
         * @input {any} Expression to evaluate when the tab changes.
         */
        this.change = new core_1.EventEmitter();
        this.parent = parent;
        this.id = ++tabIds;
        this.subPages = _config.getBoolean('tabSubPages');
        this._useHighlight = _config.getBoolean('tabbarHighlight');
        this._sbPadding = _config.getBoolean('statusbarPadding', false);
        if (parent) {
            // this Tabs has a parent Nav
            parent.registerChildNav(this);
        }
        else if (this._app) {
            // this is the root navcontroller for the entire app
            this._app.setRootNav(this);
        }
        // Tabs may also be an actual ViewController which was navigated to
        // if Tabs is static and not navigated to within a NavController
        // then skip this and don't treat it as it's own ViewController
        if (viewCtrl) {
            viewCtrl.setContent(this);
            viewCtrl.setContentRef(_elementRef);
            viewCtrl.onReady = function (done) {
                _this._onReady = done;
            };
        }
    }
    /**
     * @private
     */
    Tabs.prototype.ngAfterViewInit = function () {
        var _this = this;
        this._setConfig('tabbarPlacement', 'bottom');
        this._setConfig('tabbarLayout', 'icon-top');
        if (this._useHighlight) {
            this._platform.onResize(function () {
                _this._highlight.select(_this.getSelected());
            });
        }
        this._btns.toArray().forEach(function (tabButton) {
            tabButton.select.subscribe(function (tab) {
                _this.select(tab);
            });
        });
        var preloadTabs = (util_1.isBlank(this.preloadTabs) ? this._config.getBoolean('preloadTabs') : util_1.isTrueProperty(this.preloadTabs));
        // get the selected index
        var selectedIndex = this.selectedIndex ? parseInt(this.selectedIndex, 10) : 0;
        // ensure the selectedIndex isn't a hidden or disabled tab
        // also find the first available index incase we need it later
        var availableIndex = -1;
        this._tabs.forEach(function (tab, index) {
            if (tab.enabled && tab.show && availableIndex < 0) {
                // we know this tab index is safe to show
                availableIndex = index;
            }
            if (index === selectedIndex && (!tab.enabled || !tab.show)) {
                // the selectedIndex is not safe to show
                selectedIndex = -1;
            }
        });
        if (selectedIndex < 0) {
            // the selected index wasn't safe to show
            // instead use an available index found to be safe to show
            selectedIndex = availableIndex;
        }
        this._tabs.forEach(function (tab, index) {
            if (index === selectedIndex) {
                _this.select(tab);
            }
            else if (preloadTabs) {
                tab.preload(1000 * index);
            }
        });
    };
    /**
     * @private
     */
    Tabs.prototype._setConfig = function (attrKey, fallback) {
        var val = this[attrKey];
        if (util_1.isBlank(val)) {
            val = this._config.get(attrKey, fallback);
        }
        this._renderer.setElementAttribute(this._elementRef.nativeElement, attrKey, val);
    };
    /**
     * @private
     */
    Tabs.prototype.add = function (tab) {
        tab.id = this.id + '-' + (++this._ids);
        this._tabs.push(tab);
    };
    /**
     * @param {number} index Index of the tab you want to select
     */
    Tabs.prototype.select = function (tabOrIndex) {
        var _this = this;
        var selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
        if (!selectedTab) {
            return;
        }
        var deselectedTab = this.getSelected();
        if (selectedTab === deselectedTab) {
            // no change
            return this._touchActive(selectedTab);
        }
        void 0;
        var opts = {
            animate: false
        };
        var deselectedPage;
        if (deselectedTab) {
            deselectedPage = deselectedTab.getActive();
            deselectedPage && deselectedPage.willLeave();
        }
        var selectedPage = selectedTab.getActive();
        selectedPage && selectedPage.willEnter();
        selectedTab.load(opts, function () {
            selectedTab.select.emit(selectedTab);
            _this.change.emit(selectedTab);
            if (selectedTab.root) {
                // only show the selectedTab if it has a root
                // it's possible the tab is only for opening modal's or signing out
                // and doesn't actually have content. In the case there's no content
                // for a tab then do nothing and leave the current view as is
                _this._tabs.forEach(function (tab) {
                    tab.setSelected(tab === selectedTab);
                });
                if (_this._useHighlight) {
                    _this._highlight.select(selectedTab);
                }
            }
            selectedPage && selectedPage.didEnter();
            deselectedPage && deselectedPage.didLeave();
            if (_this._onReady) {
                _this._onReady();
                _this._onReady = null;
            }
        });
    };
    /**
     * @param {number} index Index of the tab you want to get
     * @returns {Tab} Returns the tab who's index matches the one passed
     */
    Tabs.prototype.getByIndex = function (index) {
        if (index < this._tabs.length && index > -1) {
            return this._tabs[index];
        }
        return null;
    };
    /**
     * @return {Tab} Returns the currently selected tab
     */
    Tabs.prototype.getSelected = function () {
        for (var i = 0; i < this._tabs.length; i++) {
            if (this._tabs[i].isSelected) {
                return this._tabs[i];
            }
        }
        return null;
    };
    /**
     * @private
     */
    Tabs.prototype.getActiveChildNav = function () {
        return this.getSelected();
    };
    /**
     * @private
     */
    Tabs.prototype.getIndex = function (tab) {
        return this._tabs.indexOf(tab);
    };
    /**
     * @private
     * "Touch" the active tab, going back to the root view of the tab
     * or optionally letting the tab handle the event
     */
    Tabs.prototype._touchActive = function (tab) {
        var active = tab.getActive();
        if (!active) {
            return Promise.resolve();
        }
        var instance = active.instance;
        // If they have a custom tab selected handler, call it
        if (instance.tabSelected) {
            return instance.tabSelected();
        }
        // If we're a few pages deep, pop to root
        if (tab.length() > 1) {
            // Pop to the root view
            return tab.popToRoot();
        }
        // Otherwise, if the page we're on is not our real root, reset it to our
        // default root type
        if (tab.root !== active.componentType) {
            return tab.setRoot(tab.root);
        }
        // And failing all of that, we do something safe and secure
        return Promise.resolve();
    };
    Object.defineProperty(Tabs.prototype, "rootNav", {
        /**
         * @private
         * Returns the root NavController. Returns `null` if Tabs is not
         * within a NavController.
         * @returns {NavController}
         */
        get: function () {
            var nav = this.parent;
            while (nav.parent) {
                nav = nav.parent;
            }
            return nav;
        },
        enumerable: true,
        configurable: true
    });
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Object)
    ], Tabs.prototype, "selectedIndex", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', Object)
    ], Tabs.prototype, "preloadTabs", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', String)
    ], Tabs.prototype, "tabbarLayout", void 0);
    __decorate([
        core_1.Input(), 
        __metadata('design:type', String)
    ], Tabs.prototype, "tabbarPlacement", void 0);
    __decorate([
        core_1.Output(), 
        __metadata('design:type', core_1.EventEmitter)
    ], Tabs.prototype, "change", void 0);
    __decorate([
        core_1.ViewChild(tab_highlight_1.TabHighlight), 
        __metadata('design:type', tab_highlight_1.TabHighlight)
    ], Tabs.prototype, "_highlight", void 0);
    __decorate([
        core_1.ViewChildren(tab_button_1.TabButton), 
        __metadata('design:type', Object)
    ], Tabs.prototype, "_btns", void 0);
    Tabs = __decorate([
        core_1.Component({
            selector: 'ion-tabs',
            template: '<ion-navbar-section [class.statusbar-padding]="_sbPadding">' +
                '<template navbar-anchor></template>' +
                '</ion-navbar-section>' +
                '<ion-tabbar-section>' +
                '<tabbar role="tablist">' +
                '<a *ngFor="let t of _tabs" [tab]="t" class="tab-button" [class.tab-disabled]="!t.enabled" [class.tab-hidden]="!t.show" role="tab">' +
                '<ion-icon *ngIf="t.tabIcon" [name]="t.tabIcon" [isActive]="t.isSelected" class="tab-button-icon"></ion-icon>' +
                '<span *ngIf="t.tabTitle" class="tab-button-text">{{t.tabTitle}}</span>' +
                '<ion-badge *ngIf="t.tabBadge" class="tab-badge" [ngClass]="\'badge-\' + t.tabBadgeStyle">{{t.tabBadge}}</ion-badge>' +
                '<ion-button-effect></ion-button-effect>' +
                '</a>' +
                '<tab-highlight></tab-highlight>' +
                '</tabbar>' +
                '</ion-tabbar-section>' +
                '<ion-content-section>' +
                '<ng-content></ng-content>' +
                '</ion-content-section>',
            directives: [
                tab_button_1.TabButton,
                tab_highlight_1.TabHighlight,
                core_1.forwardRef(function () { return TabNavBarAnchor; })
            ],
            encapsulation: core_1.ViewEncapsulation.None,
        }),
        __param(0, core_1.Optional()),
        __param(1, core_1.Optional()), 
        __metadata('design:paramtypes', [nav_controller_1.NavController, view_controller_1.ViewController, app_1.IonicApp, config_1.Config, core_1.ElementRef, platform_1.Platform, core_1.Renderer])
    ], Tabs);
    return Tabs;
}(ion_1.Ion));
exports.Tabs = Tabs;
var tabIds = -1;
/**
 * @private
 */
var TabNavBarAnchor = (function () {
    function TabNavBarAnchor(tabs, viewContainerRef) {
        tabs.navbarContainerRef = viewContainerRef;
    }
    TabNavBarAnchor = __decorate([
        core_1.Directive({ selector: 'template[navbar-anchor]' }),
        __param(0, core_1.Host()), 
        __metadata('design:paramtypes', [Tabs, core_1.ViewContainerRef])
    ], TabNavBarAnchor);
    return TabNavBarAnchor;
}());
