/* BdfServer_Html - Copyright (c) 2020-2023 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.html.consumers;

import java.util.function.Consumer;
import net.mapeadores.util.html.ConsumerFactory;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlAttributes;
import net.mapeadores.util.html.HtmlConstants;
import net.mapeadores.util.html.HtmlPrinter;
import net.mapeadores.util.html.HtmlWrapper;
import net.mapeadores.util.html.WrapperFactory;
import net.mapeadores.util.localisation.Litteral;
import net.mapeadores.util.localisation.LocalisationUtils;
import net.mapeadores.util.localisation.Message;


/**
 *
 * @author Vincent Calame
 */
public class Button implements Consumer<HtmlPrinter> {

    public final static HtmlWrapper COMMAND = WrapperFactory.div("command-Submit");
    public final static Consumer<HtmlPrinter> ICON = ConsumerFactory.emptySpan("global-button-Icon");
    public final static String STANDARD_STYLE = "standard";
    public final static String LINK_STYLE = "link";
    public final static String TRANSPARENT_STYLE = "transparent";
    private final static String LINK_TYPE = "link";
    private final String type;
    private String style = STANDARD_STYLE;
    private String href;
    private String target;
    private Object textL10nObject;
    private String text;
    private String tooltipLocKey;
    private String tooltip;
    private Message tooltipMessage;
    private String action;
    private String formId;
    private String buttonId;
    private String shortcutKey;
    private String shortcutTooltip;
    private boolean ficheForm;
    private boolean current;

    private Button(String type) {
        this.type = type;
        if (type.equals(LINK_TYPE)) {
            style = LINK_STYLE;
        }
    }

    public Button action(String action) {
        this.action = action;
        return this;
    }

    public Button current(boolean current) {
        this.current = current;
        return this;
    }

    public Button href(CharSequence href) {
        if (href == null) {
            this.href = null;
        } else {
            this.href = href.toString();
        }
        return this;
    }

    public Button buttonId(String buttonId) {
        this.buttonId = buttonId;
        return this;
    }

    public Button formId(String formId) {
        this.formId = formId;
        return this;
    }

    public Button ficheForm(boolean ficheForm) {
        this.ficheForm = ficheForm;
        return this;
    }

    public Button shortcutKey(String shortcutKey) {
        this.shortcutKey = shortcutKey;
        return this;
    }

    public Button shortcutTooltip(String shortcutTooltip) {
        this.shortcutTooltip = shortcutTooltip;
        return this;
    }

    public Button style(String style) {
        this.style = style;
        return this;
    }

    public Button target(String target) {
        this.target = target;
        return this;
    }

    public Button text(String text) {
        if (text == null) {
            this.textL10nObject = null;
        } else {
            this.textL10nObject = new Litteral(text);
        }
        return this;
    }

    public Button textL10nObject(Object textL10nObject) {
        this.textL10nObject = textL10nObject;
        return this;
    }

    public Button textMessage(String textLocKey, Object... values) {
        this.textL10nObject = LocalisationUtils.toMessage(textLocKey, values);
        return this;
    }

    public Button tooltip(String tooltip) {
        this.tooltip = tooltip;
        this.tooltipLocKey = null;
        this.tooltipMessage = null;
        return this;
    }

    public Button tooltipMessage(String tooltipLocKey) {
        this.tooltip = null;
        this.tooltipLocKey = tooltipLocKey;
        this.tooltipMessage = null;
        return this;
    }

    public Button tooltipMessage(String tooltipLocKey, Object... values) {
        this.tooltip = null;
        this.tooltipLocKey = null;
        this.tooltipMessage = LocalisationUtils.toMessage(tooltipLocKey, values);
        return this;
    }

    public Button tooltipMessage(Message tooltipMessage) {
        this.tooltip = null;
        this.tooltipLocKey = null;
        this.tooltipMessage = tooltipMessage;
        return this;
    }

    public static Button button() {
        return new Button(HtmlConstants.BUTTON_TYPE);
    }

    public static Button submit() {
        return new Button(HtmlConstants.SUBMIT_TYPE);
    }

    public static Button submit(String textLocKey) {
        return new Button(HtmlConstants.SUBMIT_TYPE).textL10nObject(textLocKey);
    }

    public static Button submit(String action, String textLocKey) {
        return (new Button(HtmlConstants.SUBMIT_TYPE)).textL10nObject(textLocKey).action(action);
    }

    public static Button link() {
        return new Button(LINK_TYPE);
    }

    public static Button link(String href) {
        return new Button(LINK_TYPE).href(href);
    }

    @Override
    public void accept(HtmlPrinter hp) {
        if (type.equals(LINK_TYPE)) {
            acceptLink(hp);
        } else {
            acceptButton(hp);
        }
    }

    private void acceptButton(HtmlPrinter hp) {
        HtmlAttributes buttonAttributes = HA.type(type).classes(getButtonClass()).addClass((action != null), action);
        checkTooltip(hp, buttonAttributes);
        if (formId != null) {
            buttonAttributes.attr("form", formId);
        }
        if (buttonId != null) {
            buttonAttributes.id(buttonId);
        }
        if (ficheForm) {
            buttonAttributes.attr("data-ficheform-role", "submit-button");
        }
        if (shortcutKey != null) {
            buttonAttributes.attr("data-shortcut-key", shortcutKey);
        }
        if (shortcutTooltip != null) {
            buttonAttributes.attr("data-shortcut-tooltip", shortcutTooltip);
        }
        hp
                .BUTTON(buttonAttributes);
        checkIcon(hp);
        checkText(hp);
        hp
                ._BUTTON();
    }

    private void acceptLink(HtmlPrinter hp) {
        if (current) {
            hp
                    .SPAN(HA.classes(getButtonClass()).addClass("global-button-Current").addClass((action != null), action));
            checkIcon(hp);
            checkText(hp);
            hp
                    ._SPAN();
        } else {
            HtmlAttributes linkAttributes = HA.href(href).target(target).classes(getButtonClass()).addClass((action != null), action);
            checkTooltip(hp, linkAttributes);
            if (shortcutKey != null) {
                linkAttributes.attr("data-shortcut-key", shortcutKey);
            }
            if (shortcutTooltip != null) {
                linkAttributes.attr("data-shortcut-tooltip", shortcutTooltip);
            }
            hp
                    .A(linkAttributes);
            checkIcon(hp);
            checkText(hp);
            hp
                    ._A();
        }
    }

    private void checkTooltip(HtmlPrinter hp, HtmlAttributes htmlAttributes) {
        String tooltipText = getTooltipText(hp);
        if (tooltipText != null) {
            htmlAttributes.title(tooltipText);
        }
    }

    private String getTooltipText(HtmlPrinter hp) {
        if (tooltipLocKey != null) {
            return hp.getLocalization(tooltipLocKey);
        } else if (tooltip != null) {
            return tooltip;
        } else if (tooltipMessage != null) {
            return hp.getLocalization(tooltipMessage);
        } else {
            return null;
        }
    }

    private void checkText(HtmlPrinter hp) {
        if (textL10nObject != null) {
            hp
                    .SPAN("global-button-Text")
                    .__localize(textL10nObject)
                    ._SPAN();
        } else if (text != null) {
            hp
                    .SPAN("global-button-Text")
                    .__escape(text)
                    ._SPAN();
        }
    }

    private void checkIcon(HtmlPrinter hp) {
        if (action != null) {
            hp
                    .__(Button.ICON);
        }
    }

    private String getButtonClass() {
        switch (style) {
            case LINK_STYLE:
                return "global-button-Link";
            case TRANSPARENT_STYLE:
                return "global-button-Transparent";
            default:
                return "global-button-Standard";
        }
    }

}
