import { CustomData, Translator } from '../Content';
import { Position } from '../Core';
import { Navigation, NavigationRequest, NavigationRequestMultiDestination, NavigationTrace, NavigationTraceUpdateOptions } from '../Navigation';
import { Category } from './Category';
import { Image } from './Image';
import { ImageCreateOptions } from './ImageCreateOptions';
import { ImageUpdateOptions } from './ImageUpdateOptions';
import { Label } from './Label';
import { LabelCreateOptions } from './LabelCreateOptions';
import { LabelUpdateOptions } from './LabelUpdateOptions';
import { Line } from './Line';
import { LineCreateOptions } from './LineCreateOptions';
import { LineUpdateOptions } from './LineUpdateOptions';
import { Marker } from './Marker';
import { MarkerCreateOptions } from './MarkerCreateOptions';
import { MarkerUpdateOptions } from './MarkerUpdateOptions';
import { POI } from './POI';
import { POICreateOptions } from './POICreateOptions';
import { POIUpdateOptions } from './POIUpdateOptions';
import { Surface } from './Surface';
import { SurfaceUpdateOptions } from './SurfaceUpdateOptions';
import { VenueLayout } from './VenueLayout';

/**
 * This interface represent the venue and provides the ways to interact with it.
 * The venue is loaded using the {@link VisioOne.loadVenue} method.
 */
export interface Venue {
    /**
     * The bundle URL that can be used, for instance, to retrieve icons (baseURL + 'icons/')
     */
    readonly baseURL: string;
    /**
     * The structured representation of the venue.
     * @category Venue
     */
    readonly venueLayout: VenueLayout;
    /**
     * The current locale used by this Venue.
     * Labels will be displayed with "text" field corresponding to their POI's LocaleEntry
     * when it exists, otherwise the Label "text" will be empty.
     * When a View exists, each UI items (and the current Navigation) will use this locale to be displayed.
     */
    readonly currentLocale: string;
    /**
     * Modifies the current locale.
     * Available locales can be retrieved from Translator.allLocales
     * @param locale the new current locale.
     */
    setCurrentLocale(locale: string): Promise<void>;
    /**
     * Creates a POI for this venue.
     * When a View exists the POI's related features will be displayed into it.
     * @param options the parameters for POI creation.
     * @return the created POI.
     * @throws {@link POIAlreadyExistsError} when the id used to create the POI is already used in the venue.
     * @category POIs
     */
    createPOI(options: POICreateOptions): POI;
    /**
     * Removes a previously created POI from this venue.
     * Note that if the POI to remove has a visual representation, it will be removed from the view too.
     * @param poi the POI to remove.
     * @category POIs
     */
    removePOI(poi: POI): void;
    /**
     * Create an Image that'll be displayed on the map.
     * @param options All available options for creation.
     * @return the created Image.
     * @category POIs
     */
    createImage(options: ImageCreateOptions): Image;
    /**
     * Create a Label that'll be displayed on the map.
     * @param options All available options for creation.
     * @return the created Image.
     * @category POIs
     */
    createLabel(options: LabelCreateOptions): Label;
    /**
     * Create a Line that'll be displayed on the map.
     * @param options All available options for creation.
     * @return the created Image.
     * @category POIs
     */
    createLine(options: LineCreateOptions): Line;
    /**
     * Create a Marker that'll be displayed on the map.
     * @param options All available options for creation.
     * @return the created Image.
     * @category POIs
     */
    createMarker(options: MarkerCreateOptions): Marker;
    /**
     * Create a Category with provided ID.
     * @param categoryID
     * @return the created Category.
     */
    createCategory(categoryID: string): Category;
    /**
     * Removes a previously created Image from this venue.
     * @param image the Image to remove.
     * @category POIs
     */
    removeImage(image: Image): void;
    /**
     * Removes a previously created Label from this venue.
     * @param label the Label to remove.
     * @category POIs
     */
    removeLabel(label: Label): void;
    /**
     * Removes a previously created Line from this venue.
     * @param line the Line to remove.
     * @category POIs
     */
    removeLine(line: Line): void;
    /**
     * Removes a previously created Marker from this venue.
     * @param marker the Marker to remove.
     * @category POIs
     */
    removeMarker(marker: Marker): void;
    /**
     * Removes a previously created Surface from this venue.
     * @param surface the Surface to remove.
     * @category POIs
     */
    /**
     * Remove given Category from registered categories.
     * Note that it'll also remove that Category from every POIs.
     * @param category
     */
    removeCategory(category: Category): void;
    /**
     * Update provided POI with given options.
     * @param poi poi to be updated.
     * @param options as defined in {@link Venue~POIUpdateOptions | POIUpdateOptions}.
     */
    updatePOI(poi: POI, options: POIUpdateOptions): void;
    /**
     * Update given Image.
     * @param image Image to be updated.
     * @param options All fields to be updated.
     * @category POIs
     */
    updateImage(image: Image, options: ImageUpdateOptions): void;
    /**
     * Update given Label.
     * @param label Label to be updated.
     * @param options All fields to be updated.
     * @category POIs
     */
    updateLabel(label: Label, options: LabelUpdateOptions): void;
    /**
     * Update given Line.
     * @param line Line to be updated.
     * @param options All fields to be updated.
     * @category POIs
     */
    updateLine(line: Line, options: LineUpdateOptions): void;
    /**
     * Update given Surface.
     * @param surface Surface to be updated.
     * @param options All fields to be updated.
     * @category POIs
     */
    updateSurface(surface: Surface, options: SurfaceUpdateOptions): void;
    /**
     * Update given Marker.
     * @param marker Marker to be updated.
     * @param options All fields to be updated.
     * @category POIs
     */
    updateMarker(marker: Marker, options: MarkerUpdateOptions): void;
    /**
     * Create an overlay for this venue.
     *
     * @param parameters the parameters for Overlay creation
     * @return the created Overlay
     * @experimental
     */
    /**
     * Removes a previously created Overlay from this venue.
     * @param overlay the Overlay to remove
     * @experimental
     */
    /**
     * All the modalities for this venue.
     */
    readonly modalities: string[];
    /**
     * All the attributes for this venue.
     */
    readonly attributes: string[];
    /**
     * Compute the navigation instructions based on the specified request.
     * @param request the navigation request must specify the origin, the destination and some parameters helping to compute the navigation
     * instructions.
     * @return the navigation instructions. Note that those instructions are presented in a language independent format.
     * You must translate it to the appropriate locale to make it human readable.
     * @throws {@link Navigation~RouteNotFoundError | RouteNotFoundError}
     * @throws {@link Navigation~SourceOutOfLimitError | SourceOutOfLimitError}
     * @throws {@link Navigation~DestinationOutOfLimitError | DestinationOutOfLimitError}
     * @category Navigation
     */
    computeNavigation(request: NavigationRequest): Navigation;
    /**
     * Compute the navigation instructions with multiple destinations based on the specified request.
     * @param request the navigation request must specify the origin, the destinations and some parameters helping to compute the navigation
     * instructions.
     * @return the navigation instructions. Note that those instructions are presented in a language independent format.
     * You must translate it to the appropriate locale to make it human readable.
     * @throws {@link Navigation~RouteNotFoundError | RouteNotFoundError}
     * @throws {@link Navigation~SourceOutOfLimitError | SourceOutOfLimitError}
     * @throws {@link Navigation~DestinationOutOfLimitError | DestinationOutOfLimitError}
     * @category Navigation
     */
    computeNavigationMultiDestination(request: NavigationRequestMultiDestination): Navigation;
    /**
     * Update given Navigation with given parameters.
     * Most of available options will be applied on every given Navigation's Lines.
     * If you want to apply modifications to specific Line(s) of given Navigation, use updateLine().
     * @param navigationTrace NavigationTrace to update.
     * @param navigationTraceUpdateOptions Options you want to modify.
     */
    updateNavigationTrace(navigationTrace: NavigationTrace, navigationTraceUpdateOptions: NavigationTraceUpdateOptions): void;
    /**
     * Create a NavigationTrace given a navigation.
     * @param navigation the Navigation for which to create the NavigationTrace.
     * @return the created NavigationTrace
     */
    createNavigationTrace(navigation: Navigation): NavigationTrace;
    /**
     * Remove given NavigationTrace.
     * @param navigationTrace NavigationTrace to remove.
     */
    removeNavigationTrace(navigationTrace: NavigationTrace): void;
    /**
     * The list of all the POIs for this venue.
     * @category POIs
     */
    readonly pois: POI[];
    /**
     * The list of all the categories for this venue.
     * @category Content
     */
    readonly categories: Category[];
    /**
     * The translator for this Venue.
     * @category Content
     */
    readonly translator: Translator;
    /**
     * Retrieve a POI CustomData
     * @param poi the POI
     * @returns the POI custom data
     * @category Content
     */
    getPOICustomData(poi: POI): CustomData;
    /**
     * Reload the CustomData from server
     * @category Content
     */
    refreshCustomData(): Promise<void>;
    /**
     * This method should be used when the "authorizationToken" passed in the {@link LoadOptions.authorizationToken | LoadOptions} comes to expire.
     * In this case the subsequent request will fail, because the authorized VisioMapServer will reject the requests.
     * Thus, it is of the integrator's responsibility to provide a new fresh token in time.
     * @param authorizationToken The fresh token to be used in subsequent requests.
     */
    setAuthorizationToken(authorizationToken: string): void;
    /**
     * Compute the distance between a position and a Venue items.
     * This distance is the cartesian shortest distance between the position and the item.
     * When the item is an Image or a Label, the distance is computed between the position and the center of the Image or Label.
     * For a Line or a Surface, the distance is the shortest distance between the position and the Line or the Surface.
     */
    computeDistance(position: Position, item: Position | Image | Label | Line | Surface): number;
}
