"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var dom_util_1 = require("@antv/dom-util");
var react_dom_1 = __importDefault(require("react-dom"));
var util_1 = require("@antv/util");
var insert_css_1 = __importDefault(require("insert-css"));
var base_1 = __importDefault(require("../base"));
typeof document !== 'undefined' &&
    (0, insert_css_1.default)("\n  .g6-component-contextmenu {\n    border: 1px solid #e2e2e2;\n    border-radius: 4px;\n    font-size: 12px;\n    color: #545454;\n    background-color: rgba(255, 255, 255, 0.9);\n    padding: 10px 8px;\n    box-shadow: rgb(174, 174, 174) 0px 0px 10px;\n  }\n  .g6-contextmenu-ul {\n    padding: 0;\n    margin: 0;\n    list-style: none;\n  }\n\n");
var Menu = /** @class */ (function (_super) {
    __extends(Menu, _super);
    function Menu(config) {
        return _super.call(this, config) || this;
    }
    Menu.prototype.getDefaultCfgs = function () {
        return {
            offsetX: 6,
            offsetY: 6,
            handleMenuClick: undefined,
            // 指定菜单内容，function(e) {...}
            customContent: function (e) {
                return "\n          <ul class='g6-contextmenu-ul'>\n            <li>\u83DC\u5355\u98791</li>\n            <li>\u83DC\u5355\u98792</li>\n          </ul>\n        ";
            },
            shouldBegin: function (e) {
                return true;
            },
            // 菜单隐藏事件
            onHide: function () {
                return true;
            },
            itemTypes: ['node', 'edge', 'combo'],
            trigger: 'contextmenu',
        };
    };
    // class-methods-use-this
    Menu.prototype.getEvents = function () {
        if (this.get('trigger') === 'click') {
            return {
                click: 'onMenuShow',
                touchend: 'onMenuShow',
            };
        }
        return {
            contextmenu: 'onMenuShow',
        };
    };
    Menu.prototype.init = function () {
        var className = this.get('className');
        var menu = (0, dom_util_1.createDom)("<div class=".concat(className || 'g6-component-contextmenu', "></div>"));
        (0, dom_util_1.modifyCSS)(menu, { top: '0px', position: 'absolute', visibility: 'hidden' });
        var container = this.get('container');
        if (!container) {
            container = this.get('graph').get('container');
        }
        if ((0, util_1.isString)(container)) {
            container = document.getElementById(container);
        }
        container.appendChild(menu);
        this.set('menu', menu);
    };
    Menu.prototype.onMenuShow = function (e) {
        var self = this;
        e.preventDefault();
        var itemTypes = this.get('itemTypes');
        if (!e.item) {
            if (itemTypes.indexOf('canvas') === -1) {
                self.onMenuHide();
                return;
            }
        }
        else {
            if (e.item && e.item.getType && itemTypes.indexOf(e.item.getType()) === -1) {
                self.onMenuHide();
                return;
            }
        }
        var shouldBegin = this.get('shouldBegin');
        if (!shouldBegin(e))
            return;
        var menuDom = this.get('menu');
        var customContent = this.get('customContent');
        var graph = this.get('graph');
        var menu = customContent(e, graph);
        react_dom_1.default.render(menu, menuDom);
        // 清除之前监听的事件
        this.removeMenuEventListener();
        var handleMenuClick = this.get('handleMenuClick');
        if (handleMenuClick) {
            var handleMenuClickWrapper = function (evt) {
                handleMenuClick(evt.target, e.item, graph);
            };
            this.set('handleMenuClickWrapper', handleMenuClickWrapper);
            menuDom.addEventListener('click', handleMenuClickWrapper);
        }
        var width = graph.get('width');
        var height = graph.get('height');
        var bbox = menuDom.getBoundingClientRect();
        var offsetX = this.get('offsetX') || 0;
        var offsetY = this.get('offsetY') || 0;
        var graphTop = graph.getContainer().offsetTop;
        var graphLeft = graph.getContainer().offsetLeft;
        var x = e.canvasX + graphLeft + offsetX;
        var y = e.canvasY + graphTop + offsetY;
        // when the menu is (part of) out of the canvas
        if (x + bbox.width > width) {
            x = e.canvasX - bbox.width - offsetX + graphLeft;
        }
        if (y + bbox.height > height) {
            y = e.canvasY - bbox.height - offsetY + graphTop;
        }
        (0, dom_util_1.modifyCSS)(menuDom, {
            top: "".concat(y, "px"),
            left: "".concat(x, "px"),
            visibility: 'visible',
        });
        // 左键单击会触发 body 上监听的 click 事件，导致菜单展示出来后又立即被隐藏了，需要过滤掉
        var triggeredByFirstClick = this.get('trigger') === 'click';
        var handler = function (evt) {
            if (triggeredByFirstClick) {
                triggeredByFirstClick = false;
                return;
            }
            self.onMenuHide();
        };
        // 如果在页面中其他任意地方进行click, 隐去菜单
        document.body.addEventListener('click', handler);
        this.set('handler', handler);
    };
    Menu.prototype.removeMenuEventListener = function () {
        var handleMenuClickWrapper = this.get('handleMenuClickWrapper');
        var handler = this.get('handler');
        if (handleMenuClickWrapper) {
            var menuDom = this.get('menu');
            menuDom.removeEventListener('click', handleMenuClickWrapper);
            this.set('handleMenuClickWrapper', null);
        }
        if (handler) {
            document.body.removeEventListener('click', handler);
        }
    };
    Menu.prototype.onMenuHide = function () {
        var menuDom = this.get('menu');
        if (menuDom) {
            (0, dom_util_1.modifyCSS)(menuDom, { visibility: 'hidden' });
        }
        // 隐藏菜单后需要移除事件监听
        this.removeMenuEventListener();
    };
    Menu.prototype.destroy = function () {
        var menu = this.get('menu');
        this.removeMenuEventListener();
        if (menu) {
            var container = this.get('container');
            if (!container) {
                container = this.get('graph').get('container');
            }
            if ((0, util_1.isString)(container)) {
                container = document.getElementById(container);
            }
            container.removeChild(menu);
        }
    };
    return Menu;
}(base_1.default));
exports.default = Menu;
