import { ComponentFactory, ComponentFactoryResolver } from '@angular/core';
import { Location } from '@angular/common';
import { App } from '../components/app/app';
import { NavLink, NavSegment } from './nav-util';
import { ModuleLoader } from '../util/module-loader';
import { NavController } from './nav-controller';
import { Tab } from '../components/tabs/tab';
import { Tabs } from '../components/tabs/tabs';
import { UrlSerializer } from './url-serializer';
/**
 * @name DeepLinker
 * @description
 * Deep linker handles registering and displaying specific pages based on URLs. It's used
 * underneath `NavController` so it will never have to be interacted with directly. When a new
 * page is pushed with `NavController`, the URL is updated to match the path to this page.
 *
 * Unlike traditional web apps, URLs don't dictate navigation in Ionic apps.
 * Instead, URLs help us link to specific pieces of content as a breadcrumb.
 * The current URL gets updated as we navigate, but we use the `NavController`
 * push and pop, or `NavPush` and `NavPop` to move around. This makes it much easier
 * to handle complicated nested navigation.
 *
 * We refer to our URL system as a deep link system instead of a router to encourage
 * Ionic developers to think of URLs as a breadcrumb rather than as the source of
 * truth in navigation. This encourages flexible navigation design and happy apps all
 * over the world.
 *
 *
 * @usage
 *
 * The first step to setting up deep links is to add the page that should be
 * a deep link in the `IonicPageModule.forChild` import of the page's module.
 * For our examples, this will be `MyPage`:
 *
 * ```ts
 * @NgModule({
 *   declarations: [
 *     MyPage
 *   ],
 *   imports: [
 *     IonicPageModule.forChild(MyPage)
 *   ],
 *   entryComponents: [
 *     MyPage
 *   ]
 * })
 * export class MyPageModule {}
 * ```
 *
 * Then, add the `@IonicPage` decorator to the component. The most simple usage is adding an
 * empty decorator:
 *
 * ```ts
 * @IonicPage()
 * @Component({
 *   templateUrl: 'main.html'
 * })
 * export class MyPage {}
 * ```
 *
 * This will automatically create a link to the `MyPage` component using the same name as the class,
 * `name`: `'MyPage'`. The page can now be navigated to by using this name. For example:
 *
 * ```ts
 * @Component({
 *   templateUrl: 'another-page.html'
 * })
 * export class AnotherPage {
 *   constructor(public navCtrl: NavController) {}
 *
 *   goToMyPage() {
 *     // go to the MyPage component
 *     this.navCtrl.push('MyPage');
 *   }
 * }
 * ```
 *
 * The `@IonicPage` decorator accepts a `DeepLinkMetadataType` object. This object accepts
 * the following properties: `name`, `segment`, `defaultHistory`, and `priority`. All of them
 * are optional but can be used to create complex navigation links.
 *
 *
 * ### Changing Name
 *
 * As mentioned previously, the `name` property will be set to the class name if it isn't provided.
 * Changing the name of the link is extremely simple. To change the name used to link to the
 * component, simply pass it in the decorator like so:
 *
 * ```ts
 * @IonicPage({
 *   name: 'my-page'
 * })
 * ```
 *
 * This will create a link to the `MyPage` component using the name `'my-page'`. Similar to the previous
 * example, the page can be navigated to by using the name:
 *
 * ```ts
 * goToMyPage() {
 *   // go to the MyPage component
 *   this.navCtrl.push('my-page');
 * }
 * ```
 *
 *
 * ### Setting URL Path
 *
 * The `segment` property is used to set the URL to the page. If this property isn't provided, the
 * `segment` will use the value of `name`. Since components can be loaded anywhere in the app, the
 * `segment` doesn't require a full URL path. When a page becomes the active page, the `segment` is
 * appended to the URL.
 *
 * The `segment` can be changed to anything and doesn't have to match the `name`. For example, passing
 * a value for `name` and `segment`:
 *
 * ```ts
 * @IonicPage({
 *   name: 'my-page',
 *   segment: 'some-path'
 * })
 *
 * When navigating to this page as the first page in the app, the URL will look something like:
 *
 * ```
 * http://localhost:8101/#/some-path
 * ```
 *
 * However, navigating to the page will still use the `name` like the previous examples do.
 *
 *
 * ### Dynamic Links
 *
 * The `segment` property is useful for creating dynamic links. Sometimes the URL isn't known ahead
 * of time, so it can be passed as a variable.
 *
 * Since passing data around is common practice in an app, it can be reflected in the app's URL by
 * using the `:param` syntax. For example, set the `segment` in the `@IonicPage` decorator:
 *
 * ```ts
 * @IonicPage({
 *   name: 'detail-page',
 *   segment: 'detail/:id'
 * })
 * ```
 *
 * In this case, when we `push` to a new instance of `'detail-page'`, the value of `id` will
 * in the `detailInfo` data being passed to `push` will replace `:id` in the URL.
 *
 * Important: The property needs to be something that can be converted into a string, objects
 * are not supported.
 *
 * For example, to push the `'detail-page'` in the `ListPage` component, the following code could
 * be used:
 *
 * ```ts
 * @IonicPage({
 *   name: 'list'
 * })
 * export class ListPage {
 *   constructor(public navCtrl: NavController) {}
 *
 *   pushPage(detailInfo) {
 *     // Push an `id` to the `'detail-page'`
 *     this.navCtrl.push('detail-page', {
 *       'id': detailInfo.id
 *     })
 *   }
 * }
 * ```
 *
 * If the value of `detailInfo.id` is `12`, for example, the URL would end up looking like this:
 *
 * ```
 * http://localhost:8101/#/list/detail/12
 * ```
 *
 * Since this `id` will be used to pull in the data of the specific detail page, it's Important
 * that the `id` is unique.
 *
 * Note: Even though the `name` is `detail-page`, the `segment` uses `detail/:id`, and the URL
 * will use the `segment`.
 *
 *
 * ### Default History
 *
 * Pages can be navigated to using deep links from anywhere in the app, but sometimes the app is
 * launched from a URL and the page needs to have the same history as if it were navigated to from
 * inside of the app.
 *
 * By default, the page would be navigated to as the first page in the stack with no prior history.
 * A good example is the App Store on iOS. Clicking on a URL to an application in the App Store will
 * load the details of the application with no back button, as if it were the first page ever viewed.
 *
 * The default history of any page can be set in the `defaultHistory` property. This history will only
 * be used if the history doesn't already exist, meaning if you navigate to the page the history will
 * be the pages that were navigated from.
 *
 * The `defaultHistory` property takes an array of strings. For example, setting the history of the
 * detail page to the list page where the `name` is `list`:
 *
 * ```ts
 * @IonicPage({
 *   name: 'detail-page',
 *   segment: 'detail/:id',
 *   defaultHistory: ['list']
 * })
 * ```
 *
 * In this example, if the app is launched at `http://localhost:8101/#/detail/my-detail` the displayed page
 * will be the `'detail-page'` with an id of `my-detail` and it will show a back button that goes back to
 * the `'list'` page.
 *
 * An example of an application with a set history stack is the Instagram application. Opening a link
 * to an image on Instagram will show the details for that image with a back button to the user's profile
 * page. There is no "right" way of setting the history for a page, it is up to the application.
 *
 * ### Priority
 *
 * The `priority` property is only used during preloading. By default, preloading is turned off so setting
 * this property would do nothing. Preloading eagerly loads all deep links after the application boots
 * instead of on demand as needed. To enable preloading, set `preloadModules` in the main application module
 * config to `true`:
 *
 * ```ts
 * @NgModule({
 *   declarations: [
 *     MyApp
 *   ],
 *   imports: [
 *     BrowserModule,
 *     IonicModule.forRoot(MyApp, {
 *       preloadModules: true
 *     }),
 *     HttpModule
 *   ],
 *   bootstrap: [IonicApp],
 *   entryComponents: [
 *     MyApp
 *   ]
 * })
 * export class AppModule { }
 * ```
 *
 * If preloading is turned on, it will load the modules based on the value of `priority`. The following
 * values are possible for `priority`: `"high"`, `"low"`, and `"off"`. When there is no `priority`, it
 * will be set to `"low"`.
 *
 * All deep links with their priority set to `"high"` will be loaded first. Upon completion of loading the
 * `"high"` priority modules, all deep links with a priority of `"low"` (or no priority) will be loaded. If
 * the priority is set to `"off"` the link will not be preloaded. Setting the `priority` is as simple as
 * passing it to the `@IonicPage` decorator:
 *
 * ```ts
 * @IonicPage({
 *   name: 'my-page',
 *   priority: 'high'
 * })
 * ```
 *
 * We recommend setting the `priority` to `"high"` on the pages that will be viewed first when launching
 * the application.
 *
 */
export declare class DeepLinker {
    _app: App;
    _serializer: UrlSerializer;
    _location: Location;
    _moduleLoader: ModuleLoader;
    _baseCfr: ComponentFactoryResolver;
    /** @internal */
    _segments: NavSegment[];
    /** @internal */
    _history: string[];
    /** @internal */
    _indexAliasUrl: string;
    constructor(_app: App, _serializer: UrlSerializer, _location: Location, _moduleLoader: ModuleLoader, _baseCfr: ComponentFactoryResolver);
    /**
     * @internal
     */
    init(): void;
    /**
     * The browser's location has been updated somehow.
     * @internal
     */
    _urlChange(browserUrl: string): void;
    /**
     * Update the deep linker using the NavController's current active view.
     * @internal
     */
    navChange(direction: string): void;
    /**
     * @internal
     */
    _updateLocation(browserUrl: string, direction: string): void;
    getComponentFromName(componentName: string): Promise<any>;
    getNavLinkComponent(link: NavLink): Promise<any>;
    /**
     * @internal
     */
    resolveComponent(component: any): ComponentFactory<any>;
    /**
     * @internal
     */
    createUrl(nav: any, nameOrComponent: any, data: any, prepareExternalUrl?: boolean): string;
    /**
     * Build a browser URL out of this NavController. Climbs up the tree
     * of NavController's to create a string representation of all the
     * NavControllers state.
     *
     * @internal
     */
    _pathFromNavs(nav: NavController, component?: any, data?: any): NavSegment[];
    /**
     * @internal
     */
    _getTabSelector(tab: Tab): string;
    /**
     * @internal
     */
    getSelectedTabIndex(tabsNav: Tabs, pathName: string, fallbackIndex?: number): number;
    /**
     * Each NavController will call this method when it initializes for
     * the first time. This allows each NavController to figure out
     * where it lives in the path and load up the correct component.
     * @internal
     */
    initNav(nav: any): NavSegment;
    /**
     * @internal
     */
    initViews(segment: NavSegment): Promise<any>;
    /**
     * Using the known Path of Segments, walk down all descendents
     * from the root NavController and load each NavController according
     * to each Segment. This is usually called after a browser URL and
     * Path changes and needs to update all NavControllers to match
     * the new browser URL. Because the URL is already known, it will
     * not update the browser's URL when transitions have completed.
     *
     * @internal
     */
    _loadNavFromPath(nav: NavController, done?: Function): void;
    /**
     * @internal
     */
    _loadViewFromSegment(navInstance: any, done: Function): void;
    /**
     * @internal
     */
    _isBackUrl(browserUrl: string): boolean;
    /**
     * @internal
     */
    _isCurrentUrl(browserUrl: string): boolean;
    /**
     * @internal
     */
    _historyPush(browserUrl: string): void;
    /**
     * @internal
     */
    _historyPop(): void;
}
export declare function setupDeepLinker(app: App, serializer: UrlSerializer, location: Location, moduleLoader: ModuleLoader, cfr: ComponentFactoryResolver): DeepLinker;
export declare function normalizeUrl(browserUrl: string): string;
