package fr.openwide.core.wicket.more.markup.repeater.table.builder.toolbar;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Range;
import com.google.common.collect.Sets;
import fr.openwide.core.jpa.more.business.sort.ISort;
import fr.openwide.core.wicket.more.condition.Condition;
import fr.openwide.core.wicket.more.markup.html.factory.IOneParameterComponentFactory;
import fr.openwide.core.wicket.more.markup.repeater.table.CoreDataTable;
import fr.openwide.core.wicket.more.util.model.Detachables;
public class CustomizableToolbarElementBuilder<T, S extends ISort<?>>
implements IOneParameterComponentFactory<Component, CoreDataTable<T, S>> {
private static final long serialVersionUID = 8327298869880437772L;
private final IOneParameterComponentFactory<Component, CoreDataTable<T, S>> factory;
private final int colspanAccumulation;
private Integer colspan = 1;
private final Set<String> cssClasses = Sets.newHashSet();
private Condition condition = Condition.alwaysTrue();
public CustomizableToolbarElementBuilder(int colspanAccumulation, IOneParameterComponentFactory<Component, CoreDataTable<T, S>> factory) {
super();
this.colspanAccumulation = checkNotNull(colspanAccumulation);
this.factory = checkNotNull(factory);
}
@Override
public Component create(String wicketId, final CoreDataTable<T, S> dataTable) {
IModel<Integer> computedColspanModel = new LoadableDetachableModel<Integer>() {
private static final long serialVersionUID = 1L;
@Override
protected Integer load() {
if (colspan == null) {
dataTable.configure(); // Update the displayed columns
return dataTable.getDisplayedColumns().size() - colspanAccumulation;
}
Map<IColumn<T, S>, Condition> columnToConditionMap = dataTable.getColumnToConditionMap();
FluentIterable<Entry<IColumn<T, S>, Condition>> columnEntryIterable =
FluentIterable.from(columnToConditionMap .entrySet())
.skip(colspanAccumulation);
// Make sure we don't span further than the table width
int cappedColspan;
int dataTableColumnsSize = columnToConditionMap.size();
if (colspanAccumulation + colspan > dataTableColumnsSize) {
cappedColspan = dataTableColumnsSize - colspanAccumulation;
} else {
cappedColspan = colspan;
}
// Make sure we don't span further than the column width
columnEntryIterable = columnEntryIterable.limit(cappedColspan);
int colspanWithoutHiddenColumns = cappedColspan;
for (Entry<IColumn<T, S>, Condition> column : columnEntryIterable) {
Condition columnCondition = column.getValue();
if (columnCondition != null && !columnCondition.applies()) {
--colspanWithoutHiddenColumns;
}
}
return Math.max(colspanWithoutHiddenColumns, 0);
}
};
return factory.create(wicketId, dataTable)
.add(
new AttributeModifier("colspan", computedColspanModel),
condition.and(Condition.predicate(computedColspanModel, Range.atLeast(1))).thenShow(),
new AttributeModifier("class", Joiner.on(" ").join(cssClasses))
);
}
public Integer getColspan() {
return colspan;
}
public void colspan(Integer colspan) {
this.colspan = colspan;
}
public void full() {
this.colspan = null;
}
public void when(Condition condition) {
this.condition = condition;
}
public void withClass(String cssClass) {
this.cssClasses.add(cssClass);
}
@Override
public void detach() {
Detachables.detach(factory, condition);
}
}