package com.imyeyu.fx.ui.components;

import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;

import java.util.List;

/**
 * 支持最小尺寸的菜单，默认 90
 *
 * @author 夜雨
 * @since 2023-03-10 11:14
 */
public class ContextMenu extends javafx.scene.control.ContextMenu {

	/** 当菜单项 {@link Menu#getProperties()} 携带此标记时，该菜单不继承最小宽度属性 */
	public static final String NOT_EXTENDS_FLAG = "NOT_EXTENDS_FLAG";

	private static final String STYLE_TEMPLATE = "-fx-min-width: %s; -fx-pref-width: %s";

	/**
	 * 标准构造
	 *
	 * @param items   菜单项
	 */
	public ContextMenu(MenuItem... items) {
		super(items);

		getItems().addListener((ListChangeListener<MenuItem>) c -> {
			while (c.next()) {
				if (c.wasAdded()) {
					updateMinWidth(getItems());
				}
			}
		});
		minWidthProperty().addListener((obs, o, n) -> updateMinWidth(getItems()));
		setMinWidth(90);
	}

	private void updateMinWidth(List<MenuItem> items) {
		for (MenuItem item : items) {
			if (item instanceof Menu menu) {
				if (!menu.getProperties().containsKey(NOT_EXTENDS_FLAG)) {
					boolean isItemsMenu = false; // 为 true 时表示子菜单是一般菜单项，继续应用最小宽度
					ObservableList<MenuItem> subItems = menu.getItems();
					for (MenuItem subItem : subItems) {
						if (subItem.getClass().equals(MenuItem.class)) {
							isItemsMenu = true;
							break;
						}
					}
					if (isItemsMenu) {
						updateMinWidth(menu.getItems());
					}
				}
			} else {
				item.setStyle(STYLE_TEMPLATE.formatted(getMinWidth(), getMinWidth()));
			}
		}
	}
}
