/* BdfServer_Html - Copyright (c) 2020 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.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;


/**
 *
 * @author Vincent Calame
 */
public final class Choices {


    public final static HtmlWrapper LIST = WrapperFactory.ul("choices-List");
    public final static HtmlWrapper SPACED_LIST = WrapperFactory.ul("choices-List choices-Spaced");

    private Choices() {

    }

    public static Consumer<HtmlPrinter> checkboxLi(HtmlAttributes inputAttributes, String locKey) {
        return new Choice(HtmlConstants.CHECKBOX_TYPE, inputAttributes, locKey);
    }

    public static Consumer<HtmlPrinter> checkboxLi(HtmlAttributes inputAttributes, Consumer<HtmlPrinter> labelConsumer) {
        return new Choice(HtmlConstants.CHECKBOX_TYPE, inputAttributes, labelConsumer);
    }

    public static Consumer<HtmlPrinter> checkboxLi(HtmlAttributes inputAttributes, Runnable labelRunnable) {
        return new Choice(HtmlConstants.CHECKBOX_TYPE, inputAttributes, labelRunnable);
    }

    public static Consumer<HtmlPrinter> radioLi(HtmlAttributes inputAttributes, String locKey) {
        return new Choice(HtmlConstants.RADIO_TYPE, inputAttributes, locKey);
    }

    public static Consumer<HtmlPrinter> radioLi(HtmlAttributes inputAttributes, Consumer<HtmlPrinter> labelConsumer) {
        return new Choice(HtmlConstants.RADIO_TYPE, inputAttributes, labelConsumer);
    }

    public static Consumer<HtmlPrinter> radioLi(HtmlAttributes inputAttributes, Runnable labelRunnable) {
        return new Choice(HtmlConstants.RADIO_TYPE, inputAttributes, labelRunnable);
    }

    public static Consumer<HtmlPrinter> title(String locKey) {
        return ConsumerFactory.p("choices-Title", locKey);
    }


    private static abstract class LabelFunction {

        protected final Object labelFunction;

        protected LabelFunction(Object contentFunction) {
            this.labelFunction = contentFunction;
        }

        protected void run(HtmlPrinter hp) {
            if (labelFunction instanceof String) {
                hp
                        .__localize((String) labelFunction);
            } else if (labelFunction instanceof Consumer) {
                ((Consumer<HtmlPrinter>) labelFunction).accept(hp);
            } else if (labelFunction instanceof Runnable) {
                ((Runnable) labelFunction).run();
            }
        }

    }


    private static class Choice extends LabelFunction implements Consumer<HtmlPrinter> {

        private final String type;
        private final HtmlAttributes inputAttributes;

        private Choice(String type, HtmlAttributes inputAttributes, Object labelFunction) {
            super(labelFunction);
            this.type = type;
            this.inputAttributes = inputAttributes;
        }

        @Override
        public void accept(HtmlPrinter hp) {
            hp
                    .LI()
                    .SPAN("command-FlexInput")
                    .INPUT(inputAttributes.type(type))
                    .LABEL_for(inputAttributes.id());
            run(hp);
            hp
                    ._LABEL()
                    ._SPAN()
                    ._LI();
        }

    }


    private static class Ul implements Consumer<HtmlPrinter> {

        private final Object contentFunction;

        private Ul(Object contentFunction) {
            this.contentFunction = contentFunction;
        }

        @Override
        public void accept(HtmlPrinter hp) {
            hp
                    .UL("choices-List");
            if (contentFunction != null) {
                if (contentFunction instanceof Consumer) {
                    ((Consumer<HtmlPrinter>) contentFunction).accept(hp);
                } else if (contentFunction instanceof Runnable) {
                    ((Runnable) contentFunction).run();
                }
            }
            hp
                    ._UL();
        }

    }

}
