package eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition;

import eu.eudat.models.data.components.commons.Multiplicity;
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.LinkedList;
import java.util.List;

public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable<FieldSet> {
    private String id;
    private int ordinal;
    private List<Field> fields;
    private String numbering;
    private String title;
    private String description;
    private String extendedDescription;
    private String additionalInformation;
    private Multiplicity multiplicity;
    private boolean hasCommentField;
    private String commentFieldValue;

    public List<Field> getFields() {
        return fields;
    }
    public void setFields(List<Field> fields) {
        this.fields = fields;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public int getOrdinal() {
        return ordinal;
    }
    public void setOrdinal(int ordinal) {
        this.ordinal = ordinal;
    }

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public String getExtendedDescription() {
        return extendedDescription;
    }
    public void setExtendedDescription(String extendedDescription) {
        this.extendedDescription = extendedDescription;
    }

    public Multiplicity getMultiplicity() {
        return multiplicity;
    }
    public void setMultiplicity(Multiplicity multiplicity) {
        this.multiplicity = multiplicity;
    }

    public boolean getHasCommentField() {
        return hasCommentField;
    }
    public void setHasCommentField(boolean hasCommentField) {
        this.hasCommentField = hasCommentField;
    }

    public String getCommentFieldValue() {
        return commentFieldValue;
    }
    public void setCommentFieldValue(String commentFieldValue) {
        this.commentFieldValue = commentFieldValue;
    }

    public String getNumbering() {
        return numbering;
    }
    public void setNumbering(String numbering) {
        this.numbering = numbering;
    }

    public String getAdditionalInformation() {
        return additionalInformation;
    }
    public void setAdditionalInformation(String additionalInformation) {
        this.additionalInformation = additionalInformation;
    }

    @Override
    public Element toXml(Document doc) {
        Element fieldSet = doc.createElement("fieldSet");
        fieldSet.setAttribute("id", this.id);
        fieldSet.setAttribute("ordinal", "" + this.ordinal);
        Element title = doc.createElement("title");
        title.setTextContent(this.title);

        Element description = doc.createElement("description");
        description.setTextContent(this.description);

        Element extendedDescription = doc.createElement("extendedDescription");
        extendedDescription.setTextContent(this.extendedDescription);

        Element additionalInformation = doc.createElement("additionalInformation");
        additionalInformation.setTextContent(this.additionalInformation);

        Element multiplicity = doc.createElement("multiplicity");
        multiplicity.setAttribute("min", "" + this.multiplicity.getMin());
        multiplicity.setAttribute("max", "" + this.multiplicity.getMax());
        multiplicity.setAttribute("placeholder", this.multiplicity.getPlaceholder());

        Element commentField = doc.createElement("commentField");
        commentField.setAttribute("hasCommentField", "" + this.hasCommentField);
        commentField.setAttribute("commentFieldValue", this.commentFieldValue);

        Element numbering = doc.createElement("numbering");
        numbering.setTextContent(this.numbering);

        Element fieldsElement = doc.createElement("fields");
        for (Field field : fields) {
            field.setNumbering(this.numbering + "." + (this.fields.indexOf(field) + 1));
            fieldsElement.appendChild(field.toXml(doc));
        }

        fieldSet.appendChild(numbering);
        fieldSet.appendChild(commentField);
        fieldSet.appendChild(fieldsElement);
        fieldSet.appendChild(multiplicity);
        fieldSet.appendChild(title);
        fieldSet.appendChild(description);
        fieldSet.appendChild(extendedDescription);
        fieldSet.appendChild(additionalInformation);
        return fieldSet;
    }

    @Override
    public FieldSet fromXml(Element element) {
        this.id = element.getAttribute("id");
        this.ordinal = Integer.parseInt(element.getAttribute("ordinal"));
        this.fields = new LinkedList();
        Element title = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "title");
        this.title = title.getTextContent();
        Element description = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "description");
        this.description = description.getTextContent();
        Element extendedDescription = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "extendedDescription");
        this.extendedDescription = extendedDescription.getTextContent();
        Element additionalInformation = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "additionalInformation");
        if (additionalInformation != null)
            this.additionalInformation = additionalInformation.getTextContent();
        Element commentField = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "commentField");
        this.hasCommentField = Boolean.parseBoolean(commentField.getAttribute("hasCommentField"));
        this.commentFieldValue = commentField.getAttribute("commentFieldValue");
        Element fields = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "fields");

        Element numbering = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "numbering");
        if (numbering != null) this.numbering = numbering.getTextContent();

        if (fields != null) {
            NodeList fieldElements = fields.getChildNodes();
            for (int temp = 0; temp < fieldElements.getLength(); temp++) {
                Node fieldElement = fieldElements.item(temp);
                if (fieldElement.getNodeType() == Node.ELEMENT_NODE) {
                    this.fields.add(new Field().fromXml((Element) fieldElement));
                }
            }
        }

        this.multiplicity = new Multiplicity();
        Element multiplicity = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "multiplicity");

        this.multiplicity.setMin(Integer.parseInt(multiplicity.getAttribute("min")));
        this.multiplicity.setMax(Integer.parseInt(multiplicity.getAttribute("max")));
        this.multiplicity.setPlaceholder(multiplicity.getAttribute("placeholder"));

        return this;
    }
}
