"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_STYLE = exports.DEFAULT_UNIT_ID = void 0;
const addListener_1 = require("../../../../../client/addListener");
const animation_1 = require("../../../../../client/animation/animation");
const classnames_1 = require("../../../../../client/classnames");
const color_1 = require("../../../../../client/color");
const mergeStyle_1 = require("../../../../../client/component/mergeStyle");
const context_1 = require("../../../../../client/context");
const contextMenu_1 = require("../../../../../client/contextMenu");
const element_1 = require("../../../../../client/element");
const custom_1 = require("../../../../../client/event/custom");
const input_1 = require("../../../../../client/event/input");
const graphComponentFromSpec_1 = require("../../../../../client/graphComponentFromSpec");
const parentElement_1 = require("../../../../../client/platform/web/parentElement");
const theme_1 = require("../../../../../client/theme");
const LINK_DISTANCE_1 = require("../../../../../constant/LINK_DISTANCE");
const _ids_1 = require("../../../../_ids");
const Component_1 = require("../../Div/Component");
const Component_2 = require("../../Frame/Component");
const Component_3 = require("../../Parent/Component");
const Component_4 = require("../../value/Color/Component");
const Component_5 = require("../Cabinet/Component");
const Component_6 = require("../IconButton/Component");
const Component_7 = require("../Minimap/Component");
const Component_8 = require("../ModeSelector/Component");
const Component_9 = require("../Search/Component");
exports.DEFAULT_UNIT_ID = 'unit';
exports.DEFAULT_STYLE = {
    position: 'relative',
    width: '100%',
    height: '100%',
    overflow: 'hidden',
    zIndex: '3',
};
class GUI extends element_1.Element {
    constructor($props, $system) {
        super($props, $system);
        this._hidden = true;
        this._manually_changed_color = false;
        this._get_color = () => {
            const { $theme, $color } = this.$context;
            const { style = {} } = this.$props;
            let { color = $color } = style;
            // let { color = 'currentColor' } = style
            return color;
        };
        this._background_color = () => {
            const { $theme } = this.$context;
            const backgroundColor = (0, color_1.setAlpha)((0, theme_1.themeBackgroundColor)($theme), 0.75);
            return backgroundColor;
        };
        this._refresh_pointer_events = () => {
            const { style = {} } = this.$props;
            const pointerEvents = style.pointerEvents === 'none' ? 'inherit' : 'all';
            (0, mergeStyle_1.default)(this._modes, {
                pointerEvents,
            });
            (0, mergeStyle_1.default)(this._search, {
                pointerEvents,
            });
            (0, mergeStyle_1.default)(this._cabinet, {
                pointerEvents,
            });
        };
        this._refresh_color = () => {
            const color = this._get_color();
            const backgroundColor = this._background_color();
            (0, mergeStyle_1.default)(this._cabinet, {
                backgroundColor,
            });
            (0, mergeStyle_1.default)(this._modes, {
                backgroundColor,
            });
            (0, mergeStyle_1.default)(this._search, {
                backgroundColor,
            });
            (0, mergeStyle_1.default)(this._minimap, {
                color,
            });
        };
        this._init = false;
        this._on_context_theme_changed = () => {
            // console.log('GUI', '_on_context_theme_changed')
            const { api: { document: { setTheme }, }, } = this.$system;
            const { $theme } = this.$context;
            if (this.$context.$parent === null) {
                setTheme($theme);
            }
            if (!this._manually_changed_color) {
                const default_theme_color = (0, theme_1.defaultThemeColor)($theme);
                (0, context_1.setColor)(this.$context, default_theme_color);
                this._color_picker.setProp('value', default_theme_color);
            }
            this._refresh_color();
        };
        this._on_context_color_changed = () => {
            // console.log('GUI', 'colorchanged')
            this._refresh_color();
        };
        this._animate_background = (style, animate) => {
            var _a, _b;
            const duration = animate ? animation_1.ANIMATION_T_MS : 0;
            const fill = 'forwards';
            (_b = (_a = this._background.$element) === null || _a === void 0 ? void 0 : _a.animate) === null || _b === void 0 ? void 0 : _b.call(_a, style, {
                duration,
                fill,
            });
        };
        this._animate_search = (style, animate) => {
            var _a, _b;
            const duration = animate ? animation_1.ANIMATION_T_MS : 0;
            const fill = 'forwards';
            if (this._search_animation) {
                this._search_animation.pause();
                this._search_animation.commitStyles();
            }
            this._search_animation = (_b = (_a = this._search._search.$element) === null || _a === void 0 ? void 0 : _a.animate) === null || _b === void 0 ? void 0 : _b.call(_a, style, {
                duration,
                fill,
            });
        };
        this.hide_background = (animate) => {
            this._animate_background({
                opacity: '0.25',
            }, animate);
        };
        this.hide_search = (animate) => {
            // this._animate_search(
            //   {
            //     transform: 'translate(-50%, 100%)',
            //   },
            //   animate
            // )
            (0, mergeStyle_1.default)(this._search, {
                transform: 'translate(-50%, 100%)',
                transition: (0, animation_1.ifLinearTransition)(animate, 'transform'),
            });
        };
        this._animate_modes = (style, animate) => {
            var _a, _b;
            const duration = animate ? animation_1.ANIMATION_T_MS : 0;
            const fill = 'forwards';
            if (this._modes_animation) {
                this._modes_animation.pause();
                this._modes_animation.commitStyles();
            }
            this._modes_animation = (_b = (_a = this._modes._modes.$element).animate) === null || _b === void 0 ? void 0 : _b.call(_a, [style], {
                duration,
                fill,
            });
        };
        this.hide_modes = (animate = true) => {
            // this._animate_modes(
            //   {
            //     transform: 'translate(-100%, -50%)',
            //   },
            //   animate
            // )
            (0, mergeStyle_1.default)(this._modes, {
                transform: 'translate(-100%, -50%)',
                transition: (0, animation_1.ifLinearTransition)(animate, 'transform'),
            });
        };
        this.hide_cabinet = (animate) => {
            this._cabinet.hide(animate);
        };
        this.show_background = (animate) => {
            this._animate_background({
                opacity: '1',
            }, animate);
        };
        this.show_search = (animate) => {
            // this._animate_search(
            //   {
            //     transform: 'translate(-50%, 0%)',
            //   },
            //   animate
            // )
            (0, mergeStyle_1.default)(this._search, {
                transform: 'translate(-50%, 0%)',
                transition: (0, animation_1.ifLinearTransition)(animate, 'transform'),
            });
        };
        this.show_modes = (animate) => {
            // this._animate_modes(
            //   {
            //     transform: 'translate(0%, -50%)',
            //   },
            //   animate
            // )
            (0, mergeStyle_1.default)(this._modes, {
                transform: 'translate(0%, -50%)',
                transition: (0, animation_1.ifLinearTransition)(animate, 'transform'),
            });
        };
        this.show_cabinet = (animate) => {
            this._cabinet.show(animate);
        };
        this.show_tooltips = () => {
            this._modes.show_tooltips();
            this._cabinet.show_tooltips();
            this._search.showTooltip();
        };
        this.hide_tooltips = () => {
            this._modes.hide_tooltips();
            this._cabinet.hide_tooltips();
            this._search.hideTooltip();
        };
        const { className, style = {} } = this.$props;
        const pointerEvents = style.pointerEvents === 'none' ? 'inherit' : 'all';
        const modes = new Component_8.default({
            className: 'graph-gui-crud',
            style: {
                position: 'absolute',
                top: '50%',
                left: '0px',
                transform: 'translate(0%, -50%)',
                backgroundColor: 'none',
                pointerEvents,
            },
        }, this.$system);
        this._modes = modes;
        const search = new Component_9.default({
            style: {
                position: 'absolute',
                bottom: '0',
                left: '50%',
                transform: 'translate(-50%, 0%)',
                backgroundColor: 'none',
                pointerEvents,
            },
        }, this.$system);
        this._search = search;
        const minimap = new Component_7.default({
            width: Component_7.MINIMAP_WIDTH,
            height: Component_7.MINIMAP_HEIGHT,
            nodes: {},
            links: {},
            style: {
                position: 'absolute',
                width: '100%',
                height: '100%',
                touchAction: 'none',
            },
            padding: 1 * LINK_DISTANCE_1.LINK_DISTANCE,
        }, this.$system);
        this._minimap = minimap;
        const history_tree = new Component_1.default({
            style: {
                position: 'absolute',
                width: `${Component_7.MINIMAP_HEIGHT}px`,
                height: `${Component_7.MINIMAP_HEIGHT * 1.5}`,
                touchAction: 'none',
            },
        }, this.$system);
        this._history = history_tree;
        const { component: color_theme } = (0, graphComponentFromSpec_1.graphComponentFromId)(this.$system, _ids_1.ID_SWITCH, {
            style: {
                height: '26px',
                marginBottom: '3px',
                borderWidth: '1px',
                borderStyle: 'solid',
                borderColor: 'currentColor',
                borderRadius: '3px',
                backgroundColor: theme_1.COLOR_NONE,
                cursor: 'pointer',
            },
            sliderStyle: {
                borderRadius: '1.5px',
                cursor: 'pointer',
                transition: (0, animation_1.ifLinearTransition)(this.$system.animated, 'left', 'background-color'),
            },
        });
        color_theme.addEventListener((0, input_1.makeInputListener)((light) => {
            if (light) {
                (0, context_1.setTheme)(this.$context, 'light');
            }
            else {
                (0, context_1.setTheme)(this.$context, 'dark');
            }
        }));
        const color_picker = new Component_4.default({
            value: '#ffffff',
            style: {
                position: 'relative',
                height: '42px',
                width: '100%',
                borderWidth: '1px',
                borderStyle: 'solid',
                borderColor: 'currentColor',
                borderRadius: '3px',
                boxSizing: 'border-box',
            },
        }, this.$system);
        color_picker.addEventListener((0, input_1.makeInputListener)((data) => {
            this._manually_changed_color = true;
            (0, context_1.setColor)(this.$context, data);
            this._refresh_color();
        }));
        this._color_picker = color_picker;
        const color_pallete = new Component_1.default({
            style: {
                className: 'gui-color-pallete',
                position: 'relative',
                display: 'flex',
                flexDirection: 'column',
            },
        }, this.$system);
        color_pallete.appendChild(color_theme);
        color_pallete.appendChild(color_picker);
        this._color_pallete = color_pallete;
        const folder_button = new Component_6.default({
            icon: 'folder',
            style: {
                width: '21px',
                height: '21px',
                padding: '6px',
            },
        }, this.$system);
        this._folder = folder_button;
        const export_button = new Component_6.default({
            icon: 'upload',
            style: {
                width: '21px',
                height: '21px',
                padding: '6px',
            },
        }, this.$system);
        this._export = export_button;
        const import_button = new Component_6.default({
            icon: 'import',
            style: {
                width: '21px',
                height: '21px',
                padding: '6px',
            },
        }, this.$system);
        this._import = import_button;
        const share = new Component_1.default({
            style: {
                display: 'flex',
                flexDirection: 'column',
                justifyContent: 'center',
                height: 'fit-content',
            },
        }, this.$system);
        share.appendChild(export_button);
        share.appendChild(import_button);
        this._share = share;
        const cabinet = new Component_5.default({
            className: 'graph-gui-cabinet',
            style: {
                backgroundColor: 'none',
                pointerEvents,
            },
            // hidden: true,
        }, this.$system);
        cabinet.addEventListener((0, custom_1.makeCustomListener)('draweractive', ({ drawerId }) => {
            if (drawerId === 'theme') {
                (0, context_1.setTheme)(this.$context, 'light');
            }
        }));
        cabinet.addEventListener((0, custom_1.makeCustomListener)('drawerinactive', ({ drawerId }) => {
            if (drawerId === 'theme') {
                (0, context_1.setTheme)(this.$context, 'dark');
            }
        }));
        this._cabinet = cabinet;
        const background = new Component_1.default({
            className: 'gui-background',
            style: {
                position: 'absolute',
                top: '0px',
                left: '0px',
                width: '100%',
                height: '100%',
            },
        }, this.$system);
        this._background = background;
        const control = new Component_2.default({
            className: 'gui-control',
            style: {
                position: 'absolute',
                top: '0px',
                overflow: 'visible',
                background: 'none',
                pointerEvents: 'none',
            },
        }, this.$system);
        control.registerParentRoot(modes);
        control.registerParentRoot(search);
        control.registerParentRoot(cabinet);
        const main = new Component_3.default({
            className: 'gui-main',
            style: {},
        }, this.$system);
        const foreground = new Component_1.default({
            className: 'gui-foreground',
            style: {
                position: 'absolute',
                top: '0px',
                left: '0px',
                pointerEvents: 'none',
            },
        }, this.$system);
        const gui = new Component_1.default({
            className: (0, classnames_1.default)('gui', className),
            style: {
                position: 'relative',
                width: '100%',
                height: '100%',
                overflow: 'hidden',
            },
        }, this.$system);
        gui.registerParentRoot(background);
        gui.registerParentRoot(main);
        gui.registerParentRoot(control);
        gui.registerParentRoot(foreground);
        this._gui = gui;
        (0, contextMenu_1.preventContextMenu)(gui);
        const container = new Component_1.default({
            className: (0, classnames_1.default)('gui-root', className),
            style: Object.assign(Object.assign({}, exports.DEFAULT_STYLE), style),
        }, this.$system);
        container.registerParentRoot(gui);
        this._container = container;
        this._container.$ref['control'] = this;
        this._container.$ref['cabinet'] = cabinet;
        this._container.$ref['folder'] = folder_button;
        this._container.$ref['export'] = export_button;
        this._container.$ref['import'] = import_button;
        this._container.$ref['minimap'] = minimap;
        this._container.$ref['history'] = history_tree;
        this._container.$ref['modes'] = modes;
        this._container.$ref['search'] = search;
        const $element = (0, parentElement_1.default)($system);
        this.$element = $element;
        this.$slot['default'] = main;
        this.$slot['1'] = background;
        this.$slot['2'] = foreground;
        this.$slotId = {
            default: 'main',
            '1': 'background',
            '2': 'foreground',
        };
        this.$slotTarget = {
            default: 'default',
            '1': 'default',
            '2': 'default',
        };
        this.$unbundled = false;
        this.$primitive = true;
        this.setSubComponents({
            background,
            main,
            gui,
            modes,
            search,
            cabinet,
            control,
            foreground,
            container,
        });
        this.addEventListeners([
            (0, custom_1.makeCustomListener)('dock-move', ({ dy = 0, dx = 0 }) => {
                if (this._hidden) {
                    return;
                }
                (0, mergeStyle_1.default)(control, {
                    left: `${dx}px`,
                    width: `calc(100% - ${dx}px)`,
                    height: `calc(100% - ${dy}px)`,
                    transition: (0, animation_1.linearTransition)('left', 'width', 'height', 'opacity'),
                });
                (0, mergeStyle_1.default)(control, {
                    left: `${dx}px`,
                    width: `calc(100% - ${dx}px)`,
                    height: `calc(100% - ${dy}px)`,
                    transition: (0, animation_1.linearTransition)('left', 'width', 'height', 'opacity'),
                });
                (0, mergeStyle_1.default)(background, {
                    paddingBottom: `${dy}px`,
                    paddingLeft: `${dx}px`,
                    transition: (0, animation_1.linearTransition)('padding-bottom', 'padding-left'),
                });
                if (dy > 0) {
                    (0, mergeStyle_1.default)(search, {
                        borderBottomWidth: '1px',
                        borderBottomStyle: 'solid',
                        borderBottomColor: 'currentColor',
                        borderBottomLeftRadius: '3px',
                        borderBottomRightRadius: '3px',
                        transition: (0, animation_1.linearTransition)('border-bottom-color', 'border-bottom-left-radius', 'border-bottom-right-radius'),
                    });
                }
                if (dx > 0) {
                    (0, mergeStyle_1.default)(modes, {
                        borderLeftWidth: '1px',
                        borderLeftStyle: 'solid',
                        borderLeftColor: 'currentColor',
                        borderTopLeftRadius: '3px',
                        borderBottomLeftRadius: '3px',
                        transition: (0, animation_1.linearTransition)('border-left-color', 'border-left-top-radius', 'border-left-bottom-radius'),
                    });
                }
            }),
            (0, custom_1.makeCustomListener)('dock-leave', () => {
                if (this._hidden) {
                    return;
                }
                (0, mergeStyle_1.default)(control, {
                    left: `${0}px`,
                    width: '100%',
                    height: `100%`,
                });
                (0, mergeStyle_1.default)(search, {
                    borderBottomWidth: '1px',
                    borderBottomStyle: 'solid',
                    borderBottomColor: '#00000000',
                    borderBottomLeftRadius: '0px',
                    borderBottomRightRadius: '0px',
                });
                (0, mergeStyle_1.default)(modes, {
                    borderLeftWidth: '1px',
                    borderLeftStyle: 'solid',
                    borderLeftColor: '#00000000',
                    borderTopLeftRadius: '0px',
                    borderBottomLeftRadius: '0px',
                });
            }),
        ]);
        this.registerRoot(container);
    }
    onPropChanged(prop, current) {
        // console.log('GUI', 'onPropChanged', prop, current)
        if (prop === 'style') {
            this._container.setProp('style', Object.assign(Object.assign({}, exports.DEFAULT_STYLE), current));
            this._refresh_pointer_events();
            this._refresh_color();
        }
    }
    onMount() {
        // console.log('GUI', 'onMount')
        if (!this._init) {
            const { $height } = this.$context;
            const cy = $height / 2;
            this._cabinet.addDrawers({
                minimap: {
                    icon: 'graph',
                    title: 'minimap',
                    component: this._minimap,
                    active: false,
                    width: Component_7.MINIMAP_WIDTH,
                    height: Component_7.MINIMAP_HEIGHT,
                    state: { y: cy - 82.765 },
                    shortcut: 'm',
                },
                color: {
                    icon: 'palette',
                    title: 'color',
                    component: this._color_pallete,
                    active: false,
                    width: 60,
                    height: 72,
                    state: { y: cy - 17.5 },
                },
                file: {
                    icon: 'share-2',
                    title: 'share',
                    component: this._share,
                    active: false,
                    width: 30,
                    height: 68,
                    state: { y: cy + 47.765 },
                },
            });
            this._init = true;
            if (this._hidden) {
                this.hide(false);
            }
        }
        this._context_unlisten = (0, addListener_1.addListeners)(this.$context, [
            (0, custom_1.makeCustomListener)('themechanged', this._on_context_theme_changed),
            (0, custom_1.makeCustomListener)('colorchanged', this._on_context_color_changed),
        ]);
        this._refresh_color();
    }
    onUnmount($context) {
        // console.log('GUI', 'onUnmount')
        this._context_unlisten();
    }
    hide(animate = false) {
        // console.log('GUI', 'hide', animate)
        this._hidden = true;
        this.hide_background(animate);
        this.hide_search(animate);
        this.hide_modes(animate);
        this.hide_cabinet(animate);
    }
    is_hidden() {
        return this._hidden;
    }
    show(animate) {
        // console.log('GUI', 'show', animate)
        this._hidden = false;
        this.show_background(animate);
        this.show_search(animate);
        this.show_modes(animate);
        this.show_cabinet(animate);
    }
}
exports.default = GUI;
//# sourceMappingURL=Component.js.map