// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import React, { useCallback, useState, useMemo } from 'react';
import { useLocale } from '../localization';
import { ControlBarButton } from './ControlBarButton';
import { _HighContrastAwareIcon } from './HighContrastAwareIcon';
import { ContextualMenuItemType } from '@fluentui/react';
import { generateDefaultDeviceMenuProps } from './DevicesButton';
import { Announcer } from './Announcer';
const defaultLocalVideoViewOptions = {
    scalingMode: 'Crop',
    isMirrored: true
};
/**
 * A button to turn camera on / off.
 *
 * Can be used with {@link ControlBar}.
 *
 * @public
 */
export const CameraButton = (props) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const { localVideoViewOptions, onToggleCamera, onSelectCamera } = props;
    const [waitForCamera, setWaitForCamera] = useState(false);
    const localeStrings = useLocale().strings.cameraButton;
    const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
    const [announcerString, setAnnouncerString] = useState(undefined);
    const [announcerPresent, setAnnouncerPresent] = useState(false);
    const disabled = props.disabled || waitForCamera;
    const onRenderCameraOnIcon = () => React.createElement(_HighContrastAwareIcon, { disabled: disabled, iconName: "ControlButtonCameraOn" });
    const onRenderCameraOffIcon = () => React.createElement(_HighContrastAwareIcon, { disabled: disabled, iconName: "ControlButtonCameraOff" });
    if (waitForCamera && strings.tooltipVideoLoadingContent) {
        strings.tooltipDisabledContent = strings.tooltipVideoLoadingContent;
    }
    const cameraOn = props.checked;
    const cameraTurningOn = waitForCamera && !cameraOn;
    // Ensure Aria-label by default reflects the loading state of the camera
    const ariaLabel = ((_a = props.ariaLabel) !== null && _a !== void 0 ? _a : cameraTurningOn) ? strings.tooltipVideoLoadingContent : undefined;
    const splitButtonAriaString = cameraTurningOn ? strings.tooltipVideoLoadingContent : cameraOn ? strings.onSplitButtonAriaLabel : strings.offSplitButtonAriaLabel;
    const toggleAnnouncerString = useCallback((isCameraOn) => {
        setAnnouncerString(!isCameraOn ? strings.cameraActionTurnedOffAnnouncement : strings.cameraActionTurnedOnAnnouncement);
    }, [strings.cameraActionTurnedOffAnnouncement, strings.cameraActionTurnedOnAnnouncement]);
    const onVideoIsLoadingAnnouncementCallback = useCallback(() => {
        if (!cameraOn) {
            setAnnouncerString(strings.tooltipVideoLoadingContent);
        }
    }, [setAnnouncerString, cameraOn, strings.tooltipVideoLoadingContent]);
    const onToggleClick = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        // Throttle click on camera, need to await onToggleCamera then allow another click
        if (onToggleCamera) {
            setWaitForCamera(true);
            try {
                yield onToggleCamera(localVideoViewOptions !== null && localVideoViewOptions !== void 0 ? localVideoViewOptions : defaultLocalVideoViewOptions);
                // allows for the setting of narrator strings triggering the announcer when camera is turned on or off.
                toggleAnnouncerString(!cameraOn);
            }
            finally {
                setWaitForCamera(false);
            }
        }
    }), [cameraOn, localVideoViewOptions, onToggleCamera, toggleAnnouncerString]);
    const onToggleClickCallback = useCallback(() => {
        onVideoIsLoadingAnnouncementCallback();
        onToggleClick();
    }, [onVideoIsLoadingAnnouncementCallback, onToggleClick]);
    const onChangeCameraClick = useCallback((device) => __awaiter(void 0, void 0, void 0, function* () {
        // Throttle changing camera to prevent too many callbacks
        if (onSelectCamera) {
            setWaitForCamera(true);
            try {
                yield onSelectCamera(device);
            }
            finally {
                setWaitForCamera(false);
            }
        }
    }), [onSelectCamera]);
    const splitButtonMenuItems = [];
    if (props.onClickVideoEffects) {
        splitButtonMenuItems.push({
            key: 'effects',
            'data-ui-id': 'camera-split-button-video-effects',
            text: strings.videoEffectsMenuItemTitle,
            iconProps: {
                iconName: 'ControlButtonVideoEffectsOption',
                styles: {
                    root: {
                        lineHeight: 0
                    }
                }
            },
            onClick: () => {
                if (props.onClickVideoEffects) {
                    props.onClickVideoEffects(true);
                }
            }
        });
    }
    splitButtonMenuItems.push({
        key: 'cameraPrimaryAction',
        text: props.checked ? strings.onSplitButtonPrimaryActionCamera : strings.offSplitButtonPrimaryActionCamera,
        onClick: () => {
            onToggleClick();
        },
        iconProps: {
            iconName: props.checked ? 'SplitButtonPrimaryActionCameraOn' : 'SplitButtonPrimaryActionCameraOff',
            styles: {
                root: {
                    lineHeight: 0
                }
            }
        }
    });
    const splitButtonPrimaryAction = {
        key: 'primaryAction',
        title: 'toggle camera',
        itemType: ContextualMenuItemType.Section,
        sectionProps: {
            topDivider: true,
            items: splitButtonMenuItems
        }
    };
    const splitButtonMenuProps = useMemo(() => (Object.assign(Object.assign({}, props.splitButtonMenuProps), { className: 'camera-split-button' })), [props.splitButtonMenuProps]);
    return React.createElement(React.Fragment, null,
        announcerPresent && React.createElement(Announcer, { announcementString: announcerString, ariaLive: 'polite' }),
        React.createElement(ControlBarButton, Object.assign({}, props, { disabled: disabled, onClick: onToggleCamera ? onToggleClickCallback : props.onClick, onRenderOnIcon: (_b = props.onRenderOnIcon) !== null && _b !== void 0 ? _b : onRenderCameraOnIcon, onRenderOffIcon: (_c = props.onRenderOffIcon) !== null && _c !== void 0 ? _c : onRenderCameraOffIcon, strings: strings, labelKey: (_d = props.labelKey) !== null && _d !== void 0 ? _d : 'cameraButtonLabel', menuProps: (_e = props.menuProps) !== null && _e !== void 0 ? _e : (props.enableDeviceSelectionMenu ? generateDefaultDeviceMenuProps(Object.assign(Object.assign({}, props), { onSelectCamera: onChangeCameraClick, styles: (_f = props.styles) === null || _f === void 0 ? void 0 : _f.menuStyles }), strings, splitButtonPrimaryAction) : undefined), menuIconProps: ((_g = props.menuIconProps) !== null && _g !== void 0 ? _g : !props.enableDeviceSelectionMenu) ? {
                hidden: true
            } : undefined, split: (_h = props.split) !== null && _h !== void 0 ? _h : props.enableDeviceSelectionMenu, "aria-description": strings.cameraButtonAriaDescription, "aria-roledescription": props.enableDeviceSelectionMenu ? strings.cameraButtonSplitRoleDescription : undefined, ariaLabel: ariaLabel, splitButtonAriaLabel: props.enableDeviceSelectionMenu ? splitButtonAriaString : undefined, splitButtonMenuProps: splitButtonMenuProps, onFocus: () => setAnnouncerPresent(true), onBlur: () => setAnnouncerPresent(false) })));
};
//# sourceMappingURL=CameraButton.js.map