/* UtilLib - Copyright (c) 2006-2024 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 net.mapeadores.util.html;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import net.mapeadores.util.exceptions.ShouldNotOccurException;
import net.mapeadores.util.localisation.LocalisationUtils;
import net.mapeadores.util.localisation.Message;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class HtmlAttributes implements Serializable, Cloneable {

    public final static short NONE = 0;
    public final static short STRING = 1;
    public final static short LOCKEY = 2;
    public final static short MESSAGE = 3;
    private String name;
    private String classes;
    private String id;
    private String style;
    private String target;
    private String href;
    private String src;
    private String alt;
    private Object title;
    private short titleType = NONE;
    private String width;
    private String height;
    private String size;
    private String value;
    private String type;
    private String action;
    private String method;
    private String label;
    private String rel;
    private String content;
    private String httpEquiv;
    private String enctype;
    private String forId;
    private String pattern;
    private boolean checked;
    private boolean selected;
    private boolean disabled;
    private boolean readonly;
    private boolean multiple;
    private boolean required;
    private boolean open;
    private int colSpan;
    private int rowSpan;
    private int cols;
    private int rows;
    private Map<String, String> attrMap = null;

    public HtmlAttributes() {
    }

    public HtmlAttributes copy() {
        try {
            return (HtmlAttributes) clone();
        } catch (CloneNotSupportedException e) {
            throw new ShouldNotOccurException(e);
        }
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public String classes() {
        return classes;
    }

    public HtmlAttributes classes(String className) {
        this.classes = className;
        return this;
    }

    public HtmlAttributes addClass(boolean addCondition, String className) {
        if (addCondition) {
            return addClass(className);
        } else {
            return this;
        }
    }

    public HtmlAttributes addClass(String className) {
        if ((className == null) || (className.length() == 0)) {
            return this;
        }
        if ((classes == null) || (classes.length() == 0)) {
            classes = className;
        } else {
            classes = classes + " " + className;
        }
        return this;
    }

    public String id() {
        return id;
    }

    public HtmlAttributes id(String id) {
        this.id = id;
        return this;
    }

    public String forId() {
        return forId;
    }

    public HtmlAttributes forId(String forId) {
        this.forId = forId;
        return this;
    }

    public String name() {
        return name;
    }

    public HtmlAttributes name(String name) {
        this.name = name;
        return this;
    }

    public String style() {
        return style;
    }

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

    public String target() {
        return target;
    }

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

    public String href() {
        return href;
    }

    public HtmlAttributes href(CharSequence href) {
        this.href = href.toString();
        return this;
    }

    public String width() {
        return width;
    }

    public HtmlAttributes width(String width) {
        this.width = width;
        return this;
    }

    public String height() {
        return height;
    }

    public HtmlAttributes height(String height) {
        this.height = height;
        return this;
    }

    /**
     * Instance de String ou Message.
     *
     * @return
     */
    public Object title() {
        return title;
    }

    public short getTitleType() {
        return titleType;
    }

    public HtmlAttributes title(String title) {
        this.title = title;
        if (title != null) {
            titleType = STRING;
        } else {
            titleType = NONE;
        }
        return this;
    }

    public HtmlAttributes titleLocKey(String titleLocKey) {
        this.title = titleLocKey;
        if (title != null) {
            titleType = LOCKEY;
        } else {
            titleType = NONE;
        }
        return this;
    }

    public HtmlAttributes titleMessage(String titleLocKey, Object... values) {
        if (values == null) {
            return HtmlAttributes.this.titleLocKey(titleLocKey);
        }
        titleType = MESSAGE;
        this.title = LocalisationUtils.toMessage(titleLocKey, values);
        return this;
    }

    public HtmlAttributes titleMessage(Message titleMessage) {
        this.title = titleMessage;
        if (title != null) {
            titleType = MESSAGE;
        } else {
            titleType = NONE;
        }
        return this;
    }

    public String src() {
        return src;
    }

    public HtmlAttributes src(CharSequence href) {
        this.src = href.toString();
        return this;
    }

    public String alt() {
        return alt;
    }

    public HtmlAttributes alt(String alt) {
        this.alt = alt;
        return this;
    }

    public String size() {
        return size;
    }

    public HtmlAttributes size(String size) {
        this.size = size;
        return this;
    }

    public HtmlAttributes value(String value) {
        this.value = value;
        return this;
    }

    public HtmlAttributes value(Map<String, String> valueMap) {
        if (name != null) {
            this.value = valueMap.get(name);
        }
        return this;
    }

    public String value() {
        return value;
    }

    public HtmlAttributes type(String type) {
        this.type = type;
        return this;
    }

    public String type() {
        return type;
    }

    public boolean checked() {
        return checked;
    }

    public HtmlAttributes checked(boolean checked) {
        this.checked = checked;
        return this;
    }

    public HtmlAttributes checked(Map<String, String> valueMap) {
        if ((name != null) && (value != null)) {
            String current = valueMap.get(name);
            if (current != null) {
                String[] tokens = StringUtils.getTokens(current, ';', StringUtils.NOTCLEAN);
                boolean checked = false;
                for (String token : tokens) {
                    if (token.equals(value)) {
                        checked = true;
                    }
                }
                this.checked = checked;
            }
        }
        return this;
    }

    public HtmlAttributes checked(String currentValue) {
        if (value != null) {
            if ((currentValue != null) && (value.equals(currentValue))) {
                this.checked = true;
            } else {
                this.checked = false;
            }
        }
        return this;
    }

    public boolean selected() {
        return selected;
    }

    public HtmlAttributes selected(boolean selected) {
        this.selected = selected;
        return this;
    }

    public boolean disabled() {
        return disabled;
    }

    public HtmlAttributes disabled(boolean disabled) {
        this.disabled = disabled;
        return this;
    }

    public boolean open() {
        return open;
    }

    public HtmlAttributes open(boolean open) {
        this.open = open;
        return this;
    }

    public boolean multiple() {
        return multiple;
    }

    public HtmlAttributes multiple(boolean multiple) {
        this.multiple = multiple;
        return this;
    }

    public String action() {
        return action;
    }

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

    public String method() {
        return method;
    }

    public HtmlAttributes method(String method) {
        this.method = method;
        return this;
    }

    public int colspan() {
        return colSpan;
    }

    public HtmlAttributes colspan(int colSpan) {
        this.colSpan = colSpan;
        return this;
    }

    public int rowspan() {
        return rowSpan;
    }

    public HtmlAttributes rowspan(int rowSpan) {
        this.rowSpan = rowSpan;
        return this;
    }

    public String label() {
        return label;
    }

    public HtmlAttributes label(String label) {
        this.label = label;
        return this;
    }

    public int cols() {
        return cols;
    }

    public HtmlAttributes cols(int cols) {
        this.cols = cols;
        return this;
    }

    public int rows() {
        return rows;
    }

    public HtmlAttributes rows(int rows) {
        this.rows = rows;
        return this;
    }

    public boolean readonly() {
        return readonly;
    }

    public HtmlAttributes readonly(boolean readonly) {
        this.readonly = readonly;
        return this;
    }

    public String rel() {
        return rel;
    }

    public HtmlAttributes rel(String rel) {
        this.rel = rel;
        return this;
    }

    public String content() {
        return content;
    }

    public HtmlAttributes content(String content) {
        this.content = content;
        return this;
    }

    public String pattern() {
        return pattern;
    }

    public HtmlAttributes pattern(String pattern) {
        this.pattern = pattern;
        return this;
    }

    public String httpEquiv() {
        return httpEquiv;
    }

    public HtmlAttributes httpEquiv(String httpEquiv) {
        this.httpEquiv = httpEquiv;
        return this;
    }

    public String enctype() {
        return enctype;
    }

    public HtmlAttributes enctype(String enctype) {
        this.enctype = enctype;
        return this;
    }

    public boolean required() {
        return required;
    }

    public HtmlAttributes required(boolean required) {
        this.required = required;
        return this;
    }

    public HtmlAttributes attr(String name, String value) {
        if (value == null) {
            if (attrMap != null) {
                attrMap.remove(name);
            }
        } else {
            if (attrMap == null) {
                attrMap = new HashMap<String, String>();
            }
            attrMap.put(name, value);
        }
        return this;
    }

    public HtmlAttributes attr(boolean addCondition, String name, String value) {
        if (addCondition) {
            return attr(name, value);
        } else {
            return this;
        }
    }

    public String attr(String name) {
        if (attrMap == null) {
            return null;
        }
        return attrMap.get(name);
    }

    public Map<String, String> getAttrMap() {
        return attrMap;
    }

    public HtmlAttributes populate(Consumer<HtmlAttributes> consumer) {
        consumer.accept(this);
        return this;
    }

}
