package org.esa.snap.rcp.statistics;
import com.bc.ceres.binding.Property;
import com.bc.ceres.binding.ValidationException;
import com.bc.ceres.binding.ValueSet;
import com.bc.ceres.core.Assert;
import com.bc.ceres.swing.binding.BindingContext;
import org.esa.snap.core.datamodel.Product;
import org.esa.snap.core.datamodel.ProductNodeGroup;
import org.esa.snap.core.datamodel.VectorDataNode;
import org.geotools.feature.NameImpl;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.Name;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Norman Fomferra
*/
class CorrelativeFieldSelector {
final JLabel pointDataSourceLabel;
final JComboBox pointDataSourceList;
final JLabel dataFieldLabel;
final JComboBox dataFieldList;
final Property pointDataSourceProperty;
final Property dataFieldProperty;
final static String NULL_NAME = " ";
CorrelativeFieldSelector(BindingContext bindingContext) {
Assert.argument(bindingContext.getPropertySet().getProperty("pointDataSource") != null, "bindingContext");
Assert.argument(bindingContext.getPropertySet().getProperty("dataField") != null, "bindingContext");
Assert.argument(bindingContext.getPropertySet().getProperty("pointDataSource").getType().equals(VectorDataNode.class), "bindingContext");
Assert.argument(bindingContext.getPropertySet().getProperty("dataField").getType().equals(AttributeDescriptor.class), "bindingContext");
pointDataSourceLabel = new JLabel("Point data source:");
pointDataSourceList = new JComboBox();
dataFieldLabel = new JLabel("Data field:");
dataFieldList = new JComboBox();
pointDataSourceList.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
this.setText(((VectorDataNode) value).getName());
}
return this;
}
});
dataFieldList.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
this.setText(((AttributeDescriptor) value).getName().getLocalPart());
}
return this;
}
});
bindingContext.bind("pointDataSource", pointDataSourceList);
pointDataSourceProperty = bindingContext.getPropertySet().getProperty("pointDataSource");
dataFieldProperty = bindingContext.getPropertySet().getProperty("dataField");
pointDataSourceProperty.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
updateDataField();
}
});
bindingContext.getBinding("pointDataSource").addComponent(pointDataSourceLabel);
bindingContext.bind("dataField", dataFieldList);
bindingContext.getBinding("dataField").addComponent(dataFieldLabel);
}
public void updatePointDataSource(Product product) {
if (product != null) {
final Class pointClass = com.vividsolutions.jts.geom.Point.class;
final ProductNodeGroup<VectorDataNode> vectorDataGroup = product.getVectorDataGroup();
final List<VectorDataNode> vectorDataNodes = new ArrayList<VectorDataNode>();
for (VectorDataNode vectorDataNode : vectorDataGroup.toArray(new VectorDataNode[vectorDataGroup.getNodeCount()])) {
final GeometryDescriptor geometryDescriptor = vectorDataNode.getFeatureType().getGeometryDescriptor();
if (geometryDescriptor != null &&
pointClass.isAssignableFrom(geometryDescriptor.getType().getBinding())) {
vectorDataNodes.add(vectorDataNode);
}
}
final ValueSet valueSet = new ValueSet(vectorDataNodes.toArray());
pointDataSourceProperty.getDescriptor().setValueSet(valueSet);
} else {
pointDataSourceProperty.getDescriptor().setValueSet(null);
dataFieldProperty.getDescriptor().setValueSet(null);
try {
pointDataSourceProperty.setValue(null);
dataFieldProperty.setValue(null);
} catch (ValidationException ignore) {
}
}
}
public void updateDataField() {
if (pointDataSourceProperty.getValue() != null) {
final List<AttributeDescriptor> attributeDescriptors = ((VectorDataNode) pointDataSourceProperty.getValue()).getFeatureType().getAttributeDescriptors();
final List<AttributeDescriptor> result = new ArrayList<AttributeDescriptor>();
result.add(new NullAttributeDescriptor());
for (AttributeDescriptor attributeDescriptor : attributeDescriptors) {
if (Number.class.isAssignableFrom(attributeDescriptor.getType().getBinding())) {
result.add(attributeDescriptor);
}
}
dataFieldProperty.getDescriptor().setValueSet(new ValueSet(result.toArray()));
} else {
dataFieldProperty.getDescriptor().setValueSet(null);
try {
dataFieldProperty.setValue(null);
} catch (ValidationException ignore) {
}
}
}
public void tryToSelectPointDataSource(VectorDataNode pointDataSource) {
pointDataSourceList.setSelectedItem(pointDataSource);
}
public void tryToSelectDataField(AttributeDescriptor dataField) {
dataFieldList.setSelectedItem(dataField);
}
private class NullAttributeDescriptor implements AttributeDescriptor {
@Override
public AttributeType getType() {
return null;
}
@Override
public String getLocalName() {
return NULL_NAME;
}
@Override
public Object getDefaultValue() {
return null;
}
@Override
public Name getName() {
return new NameImpl(NULL_NAME);
}
@Override
public int getMinOccurs() {
return 0;
}
@Override
public int getMaxOccurs() {
return 0;
}
@Override
public boolean isNillable() {
return true;
}
@Override
public Map<Object, Object> getUserData() {
return null;
}
}
}