/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2014 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.web.data.layer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.form.ListMultipleChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.geoserver.catalog.CoverageView;
import org.geoserver.catalog.CoverageView.CompositionType;
import org.geoserver.catalog.CoverageView.CoverageBand;
import org.geoserver.catalog.CoverageView.InputCoverageBand;
/**
*
*/
@SuppressWarnings("serial")
public class CoverageViewEditor extends FormComponentPanel<List<String>> {
IModel<List<String>> coverages;
IModel<List<CoverageBand>> outputBands;
List<String> availableCoverages;
List<CoverageBand> currentOutputBands;
ListMultipleChoice<String> coveragesChoice;
CompositionType compositionType;
ListMultipleChoice<CoverageBand> outputBandsChoice;
TextField<String> definition;
DropDownChoice<CompositionType> compositionChoice;
/**
* Creates a new editor.
*
* @param id
* @param The module should return a non null collection of strings.
*/
public CoverageViewEditor(String id, final IModel<List<String>> inputCoverages, final IModel<List<CoverageBand>> bands,
List<String> availableCoverages) {
super(id, inputCoverages);
this.coverages = inputCoverages;
this.outputBands = bands;
this.availableCoverages = availableCoverages;
coveragesChoice = new ListMultipleChoice<String>("coveragesChoice", new Model<>(),
new ArrayList<String>((List<String>) coverages.getObject()),
new ChoiceRenderer<String>() {
@Override
public Object getDisplayValue(String coverage) {
return coverage;
}
});
coveragesChoice.setOutputMarkupId(true);
add(coveragesChoice);
new ArrayList<CoverageBand>();
outputBandsChoice = new ListMultipleChoice<CoverageBand>("outputBandsChoice", new Model<>(),
new ArrayList<CoverageBand>(outputBands.getObject()),
new ChoiceRenderer<CoverageBand>() {
@Override
public Object getDisplayValue(CoverageBand vcb) {
return vcb.getDefinition();
}
});
outputBandsChoice.setOutputMarkupId(true);
add(outputBandsChoice);
currentOutputBands = new ArrayList<CoverageBand>(outputBandsChoice.getChoices());
add(addBandButton());
definition = new TextField<>("definition", new Model<>());
definition.setOutputMarkupId(true);
// TODO: make this parametric on the CompositionType choice
definition.setEnabled(false);
// TODO Uncomment this row when it can be used
//add(definition);
compositionType = CompositionType.getDefault();
compositionChoice = new DropDownChoice<>("compositionType", new PropertyModel<>(this,
"compositionType"), Arrays.asList(CompositionType.BAND_SELECT), new CompositionTypeRenderer());
compositionChoice.setOutputMarkupId(true);
compositionChoice.add(new AjaxFormComponentUpdatingBehavior("change") {
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
compositionType = compositionChoice.getModelObject();
// TODO Uncomment these rows when they can be used
//definition.setEnabled(compositionType != CompositionType.BAND_SELECT);
//target.add(definition);
}
});
// TODO Uncomment this row when it can be used
//add(compositionChoice);
add(addRemoveAllButton());
add(addRemoveButton());
}
private AjaxButton addBandButton() {
AjaxButton button = new AjaxButton("addBand") {
@Override
public void onSubmit(AjaxRequestTarget target, Form<?> form) {
List<String> selection = (List<String>) coveragesChoice.getModelObject();
compositionType = compositionChoice.getModelObject();
List<CoverageBand> bandsList = new ArrayList<CoverageBand>();
int i = currentOutputBands != null && !currentOutputBands.isEmpty() ? currentOutputBands.size() : 0;
for (Iterator<String> it = selection.iterator(); it.hasNext();) {
String coverage = it.next();
final int bandIndexChar = coverage.indexOf(CoverageView.BAND_SEPARATOR);
String coverageName = coverage;
String bandIndex = null;
if (bandIndexChar != -1) {
coverageName = coverage.substring(0, bandIndexChar);
bandIndex = coverage.substring(bandIndexChar + 1, coverage.length());
}
CoverageBand band = new CoverageBand(
Collections.singletonList(new InputCoverageBand(coverageName, bandIndex)),
coverage, i++, compositionType);
bandsList.add(band);
}
currentOutputBands.addAll(bandsList);
outputBandsChoice.setChoices(currentOutputBands);
outputBandsChoice.modelChanged();
coveragesChoice.setChoices(availableCoverages);
coveragesChoice.modelChanged();
// TODO: Reset choice
target.add(coveragesChoice);
target.add(outputBandsChoice);
}
};
return button;
}
private AjaxButton addRemoveAllButton() {
AjaxButton button = new AjaxButton("removeAllBands") {
@Override
public void onSubmit(AjaxRequestTarget target, Form<?> form) {
List<CoverageBand> outputBands = (List<CoverageBand>) outputBandsChoice
.getModelObject();
outputBands.clear();
currentOutputBands.clear();
outputBandsChoice.setChoices(currentOutputBands);
outputBandsChoice.modelChanged();
// TODO: Reset choice
target.add(outputBandsChoice);
}
};
return button;
}
private AjaxButton addRemoveButton() {
AjaxButton button = new AjaxButton("removeBands") {
@Override
public void onSubmit(AjaxRequestTarget target, Form<?> form) {
List<CoverageBand> removedBands = (List<CoverageBand>) outputBandsChoice
.getModel().getObject();
for (Object band : removedBands) {
currentOutputBands.remove(band);
}
outputBandsChoice.setChoices(currentOutputBands);
outputBandsChoice.modelChanged();
// TODO: Reset choice
target.add(outputBandsChoice);
}
};
return button;
}
private class CompositionTypeRenderer extends ChoiceRenderer<CompositionType> {
public Object getDisplayValue(CompositionType object) {
return object.displayValue();
}
public String getIdValue(CompositionType object, int index) {
return object.toValue();
}
}
}