package com.imyeyu.fx.ui.components;

import com.imyeyu.fx.ui.TimiFXUI;
import com.imyeyu.fx.utils.Nodes;
import com.imyeyu.java.TimiJava;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Skin;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Paint;

import java.util.Objects;

/**
 * 图标按钮，可选图片、SVG 路径或 {@link com.imyeyu.fx.icon.TimiFXIcon} 的字体图标
 *
 * @author 夜雨
 * @since 2021-12-23 17:58
 */
public class IconButton extends Button implements TimiFXUI, TimiFXUI.Colorful {

	private static final String STYLE_CLASS = "icon-button";

	/** 是否自适应尺寸 */
	private final BooleanProperty autoSize;

	private Insets iconPadding, iconTextPadding; // 缓存单独图标内边距和图标文本混合的内边距

	/** 默认构造器 */
	public IconButton() {
		this("", (Node) null);
		setAlignment(Pos.CENTER);
	}

	// ---------- 图片图标 ----------

	/**
	 * 构造图片图标按钮
	 *
	 * @param img 图片
	 */
	public IconButton(Image img) {
		this("", new ImageView(img));
	}

	/**
	 * 构造图片图标按钮
	 *
	 * @param text 按钮文本
	 * @param img  图片
	 */
	public IconButton(String text, Image img) {
		this(text, new ImageView(img));
	}

	// ---------- SVG 图标 ----------

	/**
	 * 构造 SVG 图标按钮
	 *
	 * @param svgPath SVG 路径
	 */
	public IconButton(String svgPath) {
		this(svgPath, ICON);
	}

	/**
	 * 构造 SVG 图标按钮
	 *
	 * @param svgPath SVG 路径
	 * @param fill    填充颜色
	 */
	public IconButton(String svgPath, Paint fill) {
		this("", new SVGIcon(svgPath, fill));
	}

	/**
	 * 构造 SVG 图标按钮
	 *
	 * @param text    按钮文本
	 * @param svgPath SVG 路径
	 * @param fill    填充颜色
	 */
	public IconButton(String text, String svgPath, Paint fill) {
		this(text, new SVGIcon(svgPath, fill));
	}

	// ---------- 默认构造 ----------

	/**
	 * 构造自定义节点按钮
	 *
	 * @param node 节点
	 */
	public IconButton(Node node) {
		this("", node);
	}

	/**
	 * 构造自定义节点按钮
	 *
	 * @param text 文本
	 * @param node 节点
	 */
	public IconButton(String text, Node node) {
		super(text);
		autoSize = new SimpleBooleanProperty(false);

		getStyleClass().setAll(CSS.MINECRAFT, STYLE_CLASS);
		setAlignment(Pos.CENTER);
		setMaxHeight(Double.MAX_VALUE);
		setPickOnBounds(true);

		if (node != null) {
			setGraphic(node);
		}
		Nodes.bindHoverOpacity(this);

		// 自适应尺寸、单独图标、图标文本混合时设置不同的内边距
		paddingProperty().bind(Bindings.createObjectBinding(() -> {
			if (autoSize.get()) {
				return Insets.EMPTY;
			} else {
				if (TimiJava.isEmpty(getText())) {
					return iconPadding == null ? Insets.EMPTY : iconPadding;
				} else {
					return iconTextPadding == null ? Insets.EMPTY : iconTextPadding;
				}
			}
		}, textProperty(), autoSize, skinProperty()));
	}

	/**
	 * 添加按钮背景
	 *
	 * @return 本实例
	 */
	public IconButton withBackground() {
		getStyleClass().add(CSS.BG_BUTTON);
		setBorder(Stroke.DEFAULT);
		opacityProperty().unbind();
		return this;
	}

	/**
	 * 自适应尺寸，不使用内边距填充，图标尺寸决定组件尺寸
	 *
	 * @return 本实例
	 */
	public IconButton autoSize() {
		autoSize.set(true);
		return this;
	}

	/**
	 * 获取当前是否自适应尺寸，true 时图标尺寸决定组件尺寸
	 *
	 * @return true 为自适应尺寸
	 */
	public boolean isAutoSize() {
		return autoSize.get();
	}

	/**
	 * 设置是否自适应尺寸，true 时图标尺寸决定组件尺寸
	 *
	 * @param autoSize true 为自适应尺寸
	 */
	public void setAutoSize(boolean autoSize) {
		this.autoSize.set(autoSize);
	}

	/**
	 * 获取自适应尺寸监听
	 *
	 * @return 自适应尺寸监听
	 */
	public BooleanProperty autoSizeProperty() {
		return autoSize;
	}

	@Override
	protected Skin<?> createDefaultSkin() {
		Skin<?> defaultSkin = super.createDefaultSkin();
		double h = getFont().getSize() * .382;
		double v = h * .8;
		double tv = h * .6;
		iconPadding = new Insets(v);
		iconTextPadding = new Insets(tv, h, tv, h);
		return defaultSkin;
	}

	@Override
	public String getUserAgentStylesheet() {
		return Objects.requireNonNull(IconButton.class.getResource(RESOURCE + "style/components/icon-button.css")).toExternalForm();
	}
}
