import { Color, Position } from '../Core';
import { NavigationInstruction, NavigationTrace } from '../Navigation';
import { Building, Floor, POI } from '../Venue';
import { AnimationOptions } from './AnimationOptions';
import { AnimationPromise } from './AnimationPromise';
import { Camera } from './Camera';
import { cameraProjection } from './CameraProjection';
import { DeviceAngles } from './DevicesAngles';
import { NavigationEventCallback, POIEventCallback, TrackingEventCallback, VenueEventCallback } from './Events';
import { ExploreModeEventCallback } from './Events/ExploreModeEventCallback';
import { EventType } from './EventType';
import { ExploreMode } from './ExploreMode';
import { PositionTrackerGraphicOptions } from './PositionTrackerGraphicOptions';
import { PositionTrackerOptions } from './PositionTrackerOptions';
import { ViewpointParameters } from './ViewpointParameters';

export type UIPart = 'navigation' | 'search' | 'floorSelector' | 'poiDetails' | 'userTracking';
/**
 * This interface allows a Venue to be displayed on the screen.
 * The View is created using the {@link VisioOne.createView} method.
 */
export interface View {
    /**
     * This flag is used to show or hide the whole UI.
     */
    showUI: boolean;
    /**
     * Query the visibility state of a part of the UI.
     * @param uiPart The part on which the visibility is queried.
     */
    isUIPartVisible(uiPart: UIPart): boolean;
    /**
     * Allows to show or hide a specific part of the UI.
     * @param uiPart The part you want to change visibility.
     * @param isVisible
     */
    setUIPartVisible(uiPart: UIPart, isVisible: boolean): void;
    /**
     * When true, the view will change surfaces colors when mouse hover them.
     * The color (or behavior) used to replace the color is defined by the surfaceHoverColor value.
     * @defaultValue true
     */
    hoverEnabled: boolean;
    /**
     * The color used when the mouse or a pointing device hover a POI having a surface.
     * When 'highlight' keyword is specified, the resulting color is a highlighted color when original color is dark and a dimmed
     * color when original color is light.
     * When a Surface defines a "hoverColor" then the Surface "hoverColor" is used instead of the View's one.
     * @defaultValue 'highlight'
     */
    surfaceHoverColor: Color | 'highlight';
    /**
     * When true, the surfaces will be selectable and will change their colors when they are clicked.
     * The color (or behavior) used to replace the color is defined by the surfaceSelectionColor value.
     * @defaultValue true
     */
    selectionEnabled: boolean;
    /**
     * The color used when a POI is selected.
     * When a Surface defines a "selectionColor" then the Surface "selectionColor" is used instead of the View's one.
     * @defaultValue '#0094f0'
     */
    surfaceSelectionColor: Color;
    /**
     * The color used as accent color in the UI.
     * @defaultValue '#0094f0'
     */
    accentColor: Color;
    /**
     * The text color used a UI element is using the accent color.
     * @defaultValue '#ffffff'
     */
    textAccentColor: Color;
    /**
     * Indicates to the venue to notify a callback when a given type of event occurs.
     * It uses the same semantic as https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
     * @param type the event's type to listen to.
     * @param listener the callback to invoke when the type of event occurs.
     * @param options this parameters is optional. When a boolean is passed it is interpreted as the "capture" parameter.
     * The AddEventListenerOptions interface accepts the "once" boolean, so that event will only be fired once, the "passive"
     * boolean indicating the "preventDefault()" will never be called by the listener. Finally, this structure can accept a
     * "signal" member. For more information check https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
     */
    addEventListener(type: EventType, listener: POIEventCallback | VenueEventCallback | NavigationEventCallback | TrackingEventCallback | ExploreModeEventCallback, options?: boolean | AddEventListenerOptions): void;
    /**
     * Removes a listener for a specific type of event.
     * It uses the same semantic as https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
     * @param type the event's type to unregister.
     * @param listener the callback to unregister.
     * @param options the options with which the listener was registered.
     */
    removeEventListener(type: EventType, listener: POIEventCallback | VenueEventCallback | NavigationEventCallback | TrackingEventCallback | ExploreModeEventCallback, options?: boolean | EventListenerOptions): void;
    /**
     * The current explore mode.
     */
    currentExploreMode: ExploreMode;
    /**
     * The current building if any.
     * When the camera is exploring the outside the currentBuilding is not defined.
     * Setting the currentBuilding to undefined, will automatically update the exploreState to "global".
     */
    readonly currentBuilding?: Building;
    /**
     * The current floor.
     * When the camera is exploring the outside the currentFloor is the venue's outside floor, otherwise,
     * it is the current floor of the building that is opened.
     */
    readonly currentFloor: Floor;
    /**
     * The POI that is currently selected if any.
     * Those POI's surfaces will be passed in the convenient "selectionColor".
     * The View's "surfaceSelectionColor" will be used when the Surfaces do not define "selectionColor" attribute.
     */
    selectedPOIs: POI[];
    /**
     * Navigation user is currently routing on.
     * While this field is defined, a routing should be visible on the scene.
     */
    readonly currentNavigationTrace?: NavigationTrace;
    /**
     * Indicates which type of projection should be used for this view.
     */
    readonly cameraProjection: cameraProjection;
    /**
     * The View's camera. It can be used to get the current observer position or to indicate how interactions are
     * achieved with it.
     */
    readonly camera: Camera;
    zenithalModeEnabled: boolean;
    /**
     * This method is used to specify the default AnimationOptions
     * @param animationOptions the default animation options.
     */
    setCameraDefaultAnimationOptions(animationOptions: AnimationOptions): void;
    /**
     * Trigger an animation that will move the camera to view the whole venue data.
     * The currentExploreMode will be changed to "global" at the end of this animation.
     * @param animationOptions the animation options (duration and easing) the camera will use.
     * @return the AnimationPromise to track or stop the triggered animation.
     */
    goToGlobal(animationOptions?: AnimationOptions): AnimationPromise;
    /**
     * Trigger an animation that will move the camera to view a specific building.
     * The default Building's floor will be used, once the building is "opened".
     * @param building the building to target.
     * @param animationOptions the animation options (duration and easing) the camera will use.
     * @return the AnimationPromise to track or stop the triggered animation.
     */
    goToBuilding(building: Building, animationOptions?: AnimationOptions): AnimationPromise;
    /**
     * Trigger an animation that will move the camera to view a specific floor.
     * @param floor the floor to target.
     * @param animationOptions the animation options (duration and easing) the camera will use.
     * @return the AnimationPromise to track or stop the triggered animation.
     */
    goToFloor(floor: Floor, animationOptions?: AnimationOptions): AnimationPromise;
    /**
     * Trigger an animation that will move the camera to view a specific POI.
     * Note that the caller is responsible to call goToFloor prior goToPOI,
     * otherwise the currentFloor/Building will remain active.
     * @param poi the poi to target
     * @param animationOptions the animation options (duration and easing) the camera will use.
     * @return the AnimationPromise to track or stop the triggered animation.
     */
    goToPOI(poi: POI, animationOptions?: AnimationOptions): AnimationPromise;
    /**
     * Trigger an animation that will move the camera to match a specific viewpoint.
     * @param viewpointParameters the viewpoint parameters to match
     * @param animationOptions the animation options (duration and easing) the camera will use.
     * @return the AnimationPromise to track or stop the triggered animation.
     */
    goToViewpoint(viewpointParameters: ViewpointParameters, animationOptions?: AnimationOptions): AnimationPromise;
    /**
     * When specified, the Navigation start point will be used as the Navigation starting point.
     * If not specified and the allowTrackPosition flag is true, the latest injected position will be used.
     * In any other case, the used will be asked to enter the starting position.
     */
    navigationStartPoint?: string;
    /**
     * Make a given navigationTrace object current. This will add the objects in the view (the routing representation)
     * and in the UI (the instructions).
     * @param navigationTrace the navigationTrace to make current
     */
    setCurrentNavigationTrace(navigationTrace: NavigationTrace): void;
    /**
     * Remove the representation of the current navigation from the view and hide the UI element that were showing
     * instructions.
     */
    removeCurrentNavigationTrace(): void;
    /**
     * Set the current navigation instruction.
     * @param instruction the navigation instruction to set as the current one.
     */
    setCurrentNavigationInstruction(instruction: NavigationInstruction): void;
    /**
     * If you've previously put a Navigation as current Navigation,
     * it'll will animate its dot to go next instruction and move the camera according to.
     */
    navigateToNextInstruction(): void;
    /**
     * If you've previously put a Navigation as current Navigation,
     * it'll will animate its dot to go previous instruction and move the camera according to.
     */
    navigateToPreviousInstruction(): void;
    /**
     * Allow View to track device orientation and user's position.
     * Setting it to true is mandatory for the features to work.
     * Setting it back to false is also mandatory if you want the camera's manipulator back into a 'classic' state.
     */
    allowTracking: boolean;
    /**
     * Set it to true to bind camera orientation around position icon with device orientation.
     * This won't have any effect if flag 'allowTracking' isn't set to true.
     */
    lockCameraOrientationOnTracking: boolean;
    /**
     * Set it to true to bind camera focus on tracking position.
     * This won't have any effect if flag 'allowTracking' isn't set to true.
     */
    lockCameraPositionOnTracking: boolean;
    /**
     * Track user's position with a visible dot and precision circle.
     * If no animations options are provided, the position tracker's marker won't be animated
     * @param positionTrackerOptions as defined in {@link PositionTrackerOptions}.
     * @param animationOptions as defined in {@link AnimationOptions}.
     */
    injectTrackedPosition(positionTrackerOptions: PositionTrackerOptions, animationOptions?: AnimationOptions): void;
    /**
     * Set parameters for position tracker's marker display like color and animations.
     * @param positionTrackerGraphicOptions as defined in {@link PositionTrackerGraphicOptions}
     */
    updatePositionTrackerGraphicOptions(positionTrackerGraphicOptions: PositionTrackerGraphicOptions): void;
    /**
     * Intent to be used in a callback of a device orientation event.
     * Won't work if state View.allowDeviceTrackingOrientation isn't set to true.
     * @param deviceAngles Expect a specific type of angle.
     * @example
     * function handleDeviceOrientation(deviceOrientationEvent) {
     *   myView.injectDeviceOrientation({
     *     alpha: deviceOrientationEvent.alpha,
     *     beta: deviceOrientationEvent.beta,
     *     gamma: deviceOrientationEvent.gamma,
     *   });
     * }
     * myApp.addEventListener('deviceorientation', handleDeviceOrientation, true);
     */
    injectDeviceOrientation(deviceAngles: DeviceAngles): void;
    /**
     * The latest tracked position if any.
     */
    readonly latestTrackedPosition?: Position;
}
