"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UIDialog = exports.UIDialogScrollArea = exports.DIALOG_STYLES = exports.DIALOG_MAX_HEIGHT_OFFSET = void 0;
const react_1 = __importDefault(require("react"));
const react_2 = require("@fluentui/react");
const UIButton_1 = require("../UIButton");
const DeepMerge_1 = require("../../utilities/DeepMerge");
require("../../styles/_shadows.scss");
exports.DIALOG_MAX_HEIGHT_OFFSET = 32;
exports.DIALOG_STYLES = {
    background: 'var(--vscode-editorWidget-background)',
    boxShadow: 'var(--ui-box-shadow-medium)',
    borderColor: 'var(--vscode-editorWidget-border)',
    borderRadius: 4,
    vPadding: 20,
    vPaddingHalf: 10,
    hPadding: 45,
    title: {
        color: 'var(--vscode-panelTitle-activeForeground)'
    },
    contentText: {
        fontSize: 13,
        color: 'var(--vscode-foreground)'
    },
    modalOverlay: {
        background: 'var(--vscode-editor-background)',
        opacity: 0.8
    }
};
var UIDialogScrollArea;
(function (UIDialogScrollArea) {
    // Header and footer freezed and content is scrollable
    UIDialogScrollArea["Content"] = "Content";
    // Whole dialog is scrollable - default FluentUI behaviour, but it is buggy with large content
    UIDialogScrollArea["Dialog"] = "Dialog";
})(UIDialogScrollArea || (exports.UIDialogScrollArea = UIDialogScrollArea = {}));
/**
 * UIDialog component.
 * based on https://developer.microsoft.com/en-us/fluentui#/controls/web/dialog
 * and https://app.abstract.com/projects/42046ab5-889d-4a59-88e6-1089e98cba67/branches/master/commits/f1fcd77447bb2b32aab3498311c1c39517e47e49/files/1455D538-559B-48EF-8D9F-1C2884ED540B/layers/AFDAAFD3-BFA6-4E96-BB6D-057DD13753E5
 *
 * @exports
 * @class UIDialog
 * @extends {React.Component<IDialogProps, {}>}
 */
class UIDialog extends react_1.default.Component {
    /**
     * Initializes component properties.
     *
     * @param {DialogProps} props
     */
    constructor(props) {
        super(props);
        this.onResize = this.onResize.bind(this);
        this.onModalLayerMount = this.onModalLayerMount.bind(this);
        this.onModalLayerUnmount = this.onModalLayerUnmount.bind(this);
        this.attachResize = this.attachResize.bind(this);
        this.detachResize = this.detachResize.bind(this);
        this.onHeaderMouseDown = this.onHeaderMouseDown.bind(this);
        this.state = {
            resizeMaxHeight: this.getResizeMaxHeight(),
            isMounted: false
        };
    }
    /**
     * Called when component is rerendered.
     *
     * @param {Readonly<DialogProps>} prevProps
     */
    componentDidUpdate(prevProps) {
        const { scrollArea } = this.props;
        if (prevProps.scrollArea !== scrollArea) {
            if (scrollArea === UIDialogScrollArea.Content) {
                this.attachResize();
            }
            else {
                this.detachResize();
            }
        }
    }
    /**
     * Method handles modal dialog mount event.
     */
    onModalLayerMount() {
        this.attachResize();
        this.setState({
            isMounted: true
        });
    }
    /**
     * Method handles modal dialog unmount event.
     */
    onModalLayerUnmount() {
        this.detachResize();
        this.setState({
            isMounted: false
        });
    }
    /**
     * Method attaches to window resize event.
     */
    attachResize() {
        // Window resize handled
        window.addEventListener('resize', this.onResize);
        this.onResize();
    }
    /**
     * Method detaches from window resize event.
     */
    detachResize() {
        window.removeEventListener('resize', this.onResize);
    }
    /**
     * Method handles window resizer event to update calculation for content scrollarea size.
     */
    onResize() {
        this.setState({
            resizeMaxHeight: this.getResizeMaxHeight()
        });
    }
    /**
     * Method returns maximal height for dialog content "scrollArea=Content" mode.
     *
     * @returns {number} Max size of dialog.
     */
    getResizeMaxHeight() {
        return window.innerHeight - exports.DIALOG_MAX_HEIGHT_OFFSET;
    }
    /**
     * Method returns footer element depending in component props.
     * Three states.
     * 1. Accept/Decline buttons.
     * 2. Custom content of footer.
     * 3. No footer.
     *
     * @returns {JSX.Element | null} Footer element to render.
     */
    getFooter() {
        let element;
        const { acceptButtonText, cancelButtonText, onAccept, onCancel, acceptButtonId, cancelButtonId, footer } = this.props;
        const dialogFooterProps = {
            styles: {
                actionsRight: {
                    width: '100%',
                    textAlign: 'center',
                    justifyContent: 'center',
                    margin: '0px'
                },
                actions: {
                    margin: `${exports.DIALOG_STYLES.vPaddingHalf}px 0 ${exports.DIALOG_STYLES.vPadding}px`,
                    lineHeight: 'auto'
                },
                action: {
                    margin: '0px 5px'
                }
            }
        };
        if (footer) {
            element = react_1.default.createElement(react_2.DialogFooter, { ...dialogFooterProps }, footer);
        }
        else if (onAccept || onCancel) {
            element = (react_1.default.createElement(react_2.DialogFooter, { ...dialogFooterProps },
                onAccept ? (react_1.default.createElement(UIButton_1.UIDefaultButton, { onClick: onAccept, primary: true, style: { height: '26px' }, id: acceptButtonId }, acceptButtonText)) : (''),
                onCancel ? (react_1.default.createElement(UIButton_1.UIDefaultButton, { onClick: onCancel, style: { height: '26px' }, id: cancelButtonId }, cancelButtonText)) : ('')));
        }
        return element;
    }
    /**
     * Method handles mousedown event for dialog header area.
     * Method added to handle scenario when we open dropdown menu and move dialog.
     * Code in method sets focus to focuszone's placeholder - it triggers close for opened dropdown menu.
     *
     * @param {React.MouseEvent} event Mousedown event
     */
    onHeaderMouseDown(event) {
        if (!this.props.modalProps?.dragOptions) {
            // No need to handle non draggable
            return;
        }
        const dialogFocusZone = event.target.closest('.ms-Dialog-main');
        if (dialogFocusZone?.firstChild) {
            const focusPlaceholder = dialogFocusZone.firstChild;
            focusPlaceholder.focus();
        }
    }
    /**
     * @returns {JSX.Element}
     */
    render() {
        const { acceptButtonText, cancelButtonText, onAccept, onCancel, acceptButtonId, cancelButtonId, footer, closeButtonVisible, multiLineTitle, scrollArea = UIDialogScrollArea.Content, children, ...rest } = this.props;
        const dialogProps = {
            minWidth: '460px',
            modalProps: {
                layerProps: {
                    onLayerDidMount: this.onModalLayerMount,
                    onLayerWillUnmount: this.onModalLayerUnmount
                },
                overlay: {
                    styles: {
                        root: {
                            background: exports.DIALOG_STYLES.modalOverlay.background,
                            opacity: exports.DIALOG_STYLES.modalOverlay.opacity
                        }
                    }
                }
            },
            styles: {
                root: {
                    opacity: !this.props.isOpenAnimated || this.state.isMounted ? undefined : 0
                },
                main: {
                    backgroundColor: exports.DIALOG_STYLES.background,
                    border: `1px solid ${exports.DIALOG_STYLES.borderColor}`,
                    boxShadow: exports.DIALOG_STYLES.boxShadow,
                    borderRadius: exports.DIALOG_STYLES.borderRadius,
                    minHeight: 100,
                    ...(scrollArea === UIDialogScrollArea.Content && {
                        overflow: 'hidden',
                        '.ms-Modal-scrollableContent': {
                            overflow: 'hidden',
                            height: '100%'
                        }
                    })
                }
            },
            dialogContentProps: {
                title: this.props.title,
                titleProps: {
                    className: 'ui-medium-header',
                    style: {
                        padding: `${exports.DIALOG_STYLES.vPadding}px 0  5px`,
                        textAlign: 'center',
                        color: exports.DIALOG_STYLES.title.color,
                        ...(!multiLineTitle && {
                            whiteSpace: 'nowrap',
                            overflow: 'hidden',
                            textOverflow: 'ellipsis',
                            padding: `${exports.DIALOG_STYLES.vPadding}px ${exports.DIALOG_STYLES.hPadding}px 5px`
                        })
                    },
                    onMouseDown: this.onHeaderMouseDown
                },
                styles: {
                    button: {
                        display: !closeButtonVisible ? 'none' : undefined
                    },
                    inner: {
                        padding: '0',
                        ...(scrollArea === UIDialogScrollArea.Content && {
                            height: '100%',
                            overflow: 'hidden',
                            display: 'flex',
                            flexDirection: 'column'
                        })
                    },
                    subText: {
                        margin: '0',
                        lineHeight: 18,
                        ...exports.DIALOG_STYLES.contentText
                    },
                    content: {
                        ...exports.DIALOG_STYLES.contentText,
                        ...(scrollArea === UIDialogScrollArea.Content && {
                            height: '100%',
                            display: 'flex',
                            flexDirection: 'column',
                            maxHeight: this.state.resizeMaxHeight
                        })
                    },
                    innerContent: {
                        padding: `${exports.DIALOG_STYLES.vPaddingHalf}px ${exports.DIALOG_STYLES.hPadding}px`,
                        boxSizing: 'border-box',
                        ...(scrollArea === UIDialogScrollArea.Content && {
                            height: '100%',
                            overflow: 'auto',
                            boxSizing: 'border-box'
                        })
                    }
                }
            }
        };
        const props = (0, DeepMerge_1.deepMerge)(dialogProps, rest);
        return (react_1.default.createElement(react_2.Dialog, { ...props },
            children,
            this.getFooter()));
    }
}
exports.UIDialog = UIDialog;
// Default values for public component properties
UIDialog.defaultProps = { isOpenAnimated: true };
//# sourceMappingURL=UIDialog.js.map