package com.revolsys.ui.html.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.HttpServletRequest;
import com.revolsys.record.io.format.html.Aria;
import com.revolsys.record.io.format.html.Data;
import com.revolsys.record.io.format.xml.XmlWriter;
import com.revolsys.ui.html.decorator.Decorator;
import com.revolsys.ui.html.fields.Field;
import com.revolsys.util.HtmlAttr;
import com.revolsys.util.HtmlElem;
public class PanelGroup extends ElementContainer {
private static AtomicInteger ID_GEN = new AtomicInteger();
private final Map<String, ElementContainer> containers = new LinkedHashMap<>();
private String id;
private boolean multipleSelect = true;
private final Map<String, Boolean> states = new HashMap<>();
private final Map<String, String> titles = new HashMap<>();
public PanelGroup() {
this("panel" + ID_GEN.incrementAndGet());
}
public PanelGroup(final String id) {
this.id = id;
}
public void addElement(final String panelId, final Element element) {
final ElementContainer container = getPanel(panelId);
container.add(element);
}
public void addElement(final String panelId, final Element element, final Decorator decorator) {
final ElementContainer container = getPanel(panelId);
container.add(element, decorator);
}
public void addPanel(final String panelId, final String title) {
getPanel(panelId);
this.titles.put(panelId, title);
}
@Override
public List<Element> getElements() {
return new ArrayList<>(this.containers.values());
}
@Override
public Field getField(final String name) {
for (final ElementContainer container : this.containers.values()) {
final Field field = container.getField(name);
if (field != null) {
return field;
}
}
return null;
}
@Override
public List<String> getFieldNames() {
final List<String> allFields = new ArrayList<>();
for (final ElementContainer container : this.containers.values()) {
allFields.addAll(container.getFieldNames());
}
return allFields;
}
@Override
public Map<String, Field> getFields() {
final Map<String, Field> allFields = new HashMap<>();
for (final ElementContainer container : this.containers.values()) {
allFields.putAll(container.getFields());
}
return allFields;
}
public String getId() {
return this.id;
}
private ElementContainer getPanel(final String panelId) {
ElementContainer container = this.containers.get(panelId);
if (container == null) {
container = new ElementContainer();
container.setContainer(this);
this.containers.put(panelId, container);
this.titles.put(panelId, panelId);
this.states.put(panelId, false);
}
return container;
}
@Override
public void initialize(final HttpServletRequest request) {
for (final Element element : this.containers.values()) {
element.initialize(request);
}
}
@Override
public boolean isEmpty() {
return this.containers.size() == 0;
}
public boolean isMultipleSelect() {
return this.multipleSelect;
}
@Override
public void serializeElement(final XmlWriter out) {
if (!this.containers.isEmpty()) {
out.startTag(HtmlElem.DIV);
out.attribute(HtmlAttr.ID, this.id);
out.attribute(HtmlAttr.ROLE, "tablist");
out.attribute("aria-multiselectable", this.multipleSelect);
for (final Entry<String, ElementContainer> entry : this.containers.entrySet()) {
final String panelId = entry.getKey();
final ElementContainer container = entry.getValue();
if (!container.isEmpty()) {
final String title = this.titles.get(panelId);
final boolean open = this.states.get(panelId);
final String fullPanelId = this.id + "_" + panelId;
out.startTag(HtmlElem.DIV);
out.attribute(HtmlAttr.CLASS, "panel panel-default panel-collapsible");
final String headingId = "heading" + fullPanelId;
final String collapseId = "collapse" + fullPanelId;
{
out.startTag(HtmlElem.DIV);
out.attribute(HtmlAttr.CLASS, "panel-heading");
out.attribute(HtmlAttr.ROLE, "tab");
out.attribute(HtmlAttr.ID, headingId);
{
out.startTag(HtmlElem.H4);
out.attribute(HtmlAttr.CLASS, "panel-title");
{
out.startTag(HtmlElem.A);
if (!open) {
out.attribute(HtmlAttr.CLASS, "collapsed");
}
out.attribute(HtmlAttr.ROLE, "button");
Data.toggle(out, "collapse");
Data.parent(out, "#" + this.id);
out.attribute(HtmlAttr.HREF, "#collapse" + fullPanelId);
Aria.expanded(out, open);
Aria.controls(out, collapseId);
out.text(title);
out.endTag(HtmlElem.A);
}
out.endTag(HtmlElem.H4);
}
out.endTag(HtmlElem.DIV);
}
{
out.startTag(HtmlElem.DIV);
out.attribute(HtmlAttr.ID, collapseId);
if (open) {
out.attribute(HtmlAttr.CLASS, "panel-collapse collapse in");
} else {
out.attribute(HtmlAttr.CLASS, "panel-collapse collapse");
}
out.attribute(HtmlAttr.ROLE, "tabpanel");
Aria.labelledby(out, headingId);
{
out.startTag(HtmlElem.DIV);
out.attribute(HtmlAttr.CLASS, "panel-body");
container.serialize(out);
out.endTag(HtmlElem.DIV);
}
out.endTag(HtmlElem.DIV);
}
out.endTag(HtmlElem.DIV);
}
}
out.endTag(HtmlElem.DIV);
}
}
public void setId(final String id) {
this.id = id;
}
public void setMultipleSelect(final boolean multipleSelect) {
this.multipleSelect = multipleSelect;
}
public void setOpen(final String id, final boolean open) {
this.states.put(id, open);
}
@Override
public boolean validate() {
boolean valid = true;
for (final ElementContainer container : this.containers.values()) {
valid &= container.validate();
}
return valid;
}
}