import CancelIcon from 'mdi-react/CancelIcon';
import CloseIcon from 'mdi-react/CloseIcon';
import * as React from 'react';
import { ReplaySubject, Subject, Subscription } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { Resizable } from '../components/Resizable';
import { Spacer, TabsWithURLViewStatePersistence } from '../components/Tabs';
import { eventLogger } from '../tracking/eventLogger';
import { parseHash } from '../util/url';
// TODO: Panel should be mounted whenever the blob page is shown.
// There's no reason to not have it rendered. We can just hide it. This will make the logic here a lot safer.
/**
 * The panel, which is a tabbed component with contextual information. Components rendering the panel should
 * generally use ResizablePanel, not Panel.
 *
 * Other components can contribute panel items to the panel.
 */
export class Panel extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.subscriptions = new Subscription();
        this.state = { items: [] };
        this.onSelectTab = (tab) => eventLogger.log('PanelTabActivated', { tab });
        this.onDismiss = () => this.props.history.push(TabsWithURLViewStatePersistence.urlForTabID(this.props.location, null));
    }
    /**
     * Set the panel title. Do not call directly; use PanelTitlePortal instead.
     * @param fragment to set as the panel title
     */
    static setTitle(fragment) {
        Panel.newTitles.next(fragment);
        return {
            unsubscribe: () => {
                Panel.titlesToRemove.next(fragment);
            },
        };
    }
    /**
     * Add an item to the panel. Do not call directly; use PanelItemPortal instead.
     * @param item to add to the header
     */
    static addItem(item) {
        Panel.newItems.next(item);
        return {
            unsubscribe: () => {
                Panel.itemsToRemove.next(item);
            },
        };
    }
    /**
     * Forces an update of items in the panel. Do not call directly; use PanelItemPortal instead.
     */
    static forceUpdate() {
        this.forceUpdates.next();
    }
    componentDidMount() {
        this.subscriptions.add(Panel.forceUpdates.subscribe(() => this.forceUpdate()));
        this.subscriptions.add(Panel.newItems.pipe(distinctUntilChanged()).subscribe(item => {
            this.setState(state => ({
                items: state.items.concat(item).sort(byPriority),
            }));
        }));
        this.subscriptions.add(Panel.itemsToRemove.subscribe(item => {
            this.setState(state => ({
                items: state.items.filter(i => i !== item),
            }));
        }));
        this.subscriptions.add(Panel.newTitles.pipe(distinctUntilChanged()).subscribe(title => {
            this.setState({
                title,
            });
        }));
        this.subscriptions.add(Panel.titlesToRemove.subscribe(title => {
            if (this.state.title === title) {
                this.setState({ title: undefined });
            }
        }));
    }
    componentWillUnmount() {
        this.subscriptions.unsubscribe();
    }
    render() {
        const closeButton = (React.createElement("button", { onClick: this.onDismiss, className: "btn btn-icon panel__header-icon tab_bar__close-button tab-bar__end-fragment-other-element", "data-tooltip": "Close" },
            React.createElement(CloseIcon, { className: "icon-inline" })));
        const hasTabs = this.state.items.length > 0;
        return (React.createElement("div", { className: "panel" },
            (!hasTabs || this.state.title) && (React.createElement("header", { className: "panel__header" },
                React.createElement("div", { className: "panel__header-title" }, this.state.title),
                closeButton)),
            hasTabs ? (React.createElement(TabsWithURLViewStatePersistence, { tabs: this.state.items || [], tabBarEndFragment: React.createElement(React.Fragment, null,
                    React.createElement(Spacer, null),
                    !this.state.title && closeButton), className: "panel__tabs", tabClassName: "tab-bar__tab--h5like", onSelectTab: this.onSelectTab, location: this.props.location }, this.state.items &&
                this.state.items.map(({ id, element }) => React.cloneElement(element, { key: id })))) : (React.createElement("div", { className: "panel__empty" },
                React.createElement(CancelIcon, { className: "icon-inline" }),
                " Nothing to show here"))));
    }
}
Panel.forceUpdates = new Subject();
// We'll use ReplaySubject so everything will get emitted even if the panel isn't mounted
Panel.newItems = new ReplaySubject();
Panel.newTitles = new ReplaySubject();
Panel.itemsToRemove = new ReplaySubject();
Panel.titlesToRemove = new ReplaySubject();
function byPriority(a, b) {
    return b.priority - a.priority;
}
/** A wrapper around Panel that makes it resizable. */
export const ResizablePanel = props => !!parseHash(props.location.hash).viewState ? (React.createElement(Resizable, { className: "panel--resizable", handlePosition: "top", defaultSize: 350, storageKey: "panel-size", element: React.createElement(Panel, Object.assign({}, props)) })) : null;
//# sourceMappingURL=Panel.js.map