package nodebox.node;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableTable;
import nodebox.graphics.*;
import java.util.List;
public class TypeConversions {
private final static ImmutableTable<Class, String, ListConverter> conversionTable;
private final static ImmutableMap<String,Class> typeClassMap;
static {
ImmutableTable.Builder<Class, String, ListConverter> builder = ImmutableTable.builder();
builder.put(Long.class, Port.TYPE_FLOAT, new IntToFloatConverter());
builder.put(Long.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Long.class, Port.TYPE_BOOLEAN, new IntToBooleanConverter());
builder.put(Long.class, Port.TYPE_COLOR, new IntToColorConverter());
builder.put(Long.class, Port.TYPE_POINT, new IntToPointConverter());
builder.put(Long.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Double.class, Port.TYPE_INT, new FloatToIntConverter());
builder.put(Double.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Double.class, Port.TYPE_BOOLEAN, new FloatToBooleanConverter());
builder.put(Double.class, Port.TYPE_COLOR, new FloatToColorConverter());
builder.put(Double.class, Port.TYPE_POINT, new FloatToPointConverter());
builder.put(Double.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(String.class, Port.TYPE_INT, new StringToIntConverter());
builder.put(String.class, Port.TYPE_FLOAT, new StringToFloatConverter());
builder.put(String.class, Port.TYPE_BOOLEAN, new StringToBooleanConverter());
builder.put(String.class, Port.TYPE_COLOR, new StringToColorConverter());
builder.put(String.class, Port.TYPE_POINT, new StringToPointConverter());
builder.put(String.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Boolean.class, Port.TYPE_INT, new BooleanToIntConverter());
builder.put(Boolean.class, Port.TYPE_FLOAT, new BooleanToFloatConverter());
builder.put(Boolean.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Boolean.class, Port.TYPE_COLOR, new BooleanToColorConverter());
builder.put(Boolean.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Color.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Color.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Point.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Point.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Geometry.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Geometry.class, Port.TYPE_POINT, new GeometryToPointsConverter());
builder.put(Geometry.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Path.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Path.class, Port.TYPE_POINT, new GeometryToPointsConverter());
builder.put(Path.class, Port.TYPE_LIST, new NoOpConverter());
builder.put(Contour.class, Port.TYPE_STRING, new ObjectToStringConverter());
builder.put(Contour.class, Port.TYPE_POINT, new GeometryToPointsConverter());
builder.put(Contour.class, Port.TYPE_LIST, new NoOpConverter());
conversionTable = builder.build();
ImmutableMap.Builder<String, Class> b = ImmutableMap.builder();
b.put(Port.TYPE_INT, Long.class);
b.put(Port.TYPE_FLOAT, Double.class);
b.put(Port.TYPE_STRING, String.class);
b.put(Port.TYPE_BOOLEAN, Boolean.class);
b.put(Port.TYPE_POINT, Point.class);
b.put(Port.TYPE_COLOR, Color.class);
b.put(Port.TYPE_GEOMETRY, Geometry.class);
typeClassMap = b.build();
}
public static List<?> convert(Class sourceType, String targetType, List<?> values) {
ListConverter converter = conversionTable.get(sourceType, targetType);
if (converter != null) {
return converter.convert(values);
} else {
return values;
}
}
public static boolean canBeConverted(Class sourceType, String targetType) {
return conversionTable.contains(sourceType, targetType);
}
public static boolean canBeConverted(String sourceType, String targetType) {
Class sourceClass = typeClassMap.get(sourceType);
return sourceClass != null && conversionTable.contains(sourceClass, targetType);
}
private TypeConversions() {}
private static interface ListConverter {
public List<?> convert(List<?> values);
}
private abstract static class ValueConverter implements ListConverter {
public List<?> convert(List<?> values) {
ImmutableList.Builder<Object> b = ImmutableList.builder();
for (Object v : values) {
b.add(convertValue(v));
}
return b.build();
}
public abstract Object convertValue(Object value);
}
private static class NoOpConverter implements ListConverter {
@Override
public List<?> convert(List<?> values) {
return values;
}
}
private static class IntToFloatConverter extends ValueConverter {
public Object convertValue(Object value) {
return ((Long) value).doubleValue();
}
}
private static class ObjectToStringConverter extends ValueConverter {
public Object convertValue(Object value) {
return value.toString();
}
}
private static class IntToBooleanConverter extends ValueConverter {
public Object convertValue(Object value) {
// TODO Which values are true vs false?
return ((Long) value) > 0;
}
}
private static class IntToColorConverter extends ValueConverter {
public Object convertValue(Object value) {
long v = (Long) value;
return new Color(v / 255.0, v / 255.0, v / 255.0);
}
}
private static class IntToPointConverter extends ValueConverter {
public Object convertValue(Object value) {
long v = (Long) value;
return new Point(v, v);
}
}
private static class FloatToIntConverter extends ValueConverter {
public Object convertValue(Object value) {
return Math.round((Double) value);
}
}
private static class FloatToBooleanConverter extends ValueConverter {
public Object convertValue(Object value) {
return ((Double) value) > 0;
}
}
private static class FloatToColorConverter extends ValueConverter {
public Object convertValue(Object value) {
double v = (Double) value;
return new Color(v / 255.0, v / 255.0, v / 255.0);
}
}
private static class FloatToPointConverter extends ValueConverter {
public Object convertValue(Object value) {
double v = (Double) value;
return new Point(v, v);
}
}
private static class StringToIntConverter extends ValueConverter {
public Object convertValue(Object value) {
return Long.parseLong((String) value);
}
}
private static class StringToFloatConverter extends ValueConverter {
public Object convertValue(Object value) {
return Double.parseDouble((String) value);
}
}
private static class StringToBooleanConverter extends ValueConverter {
public Object convertValue(Object value) {
return Boolean.parseBoolean((String) value);
}
}
private static class StringToColorConverter extends ValueConverter {
public Object convertValue(Object value) {
return Color.parseColor((String) value);
}
}
private static class StringToPointConverter extends ValueConverter {
public Object convertValue(Object value) {
return Point.parsePoint((String) value);
}
}
private static class BooleanToIntConverter extends ValueConverter {
public Object convertValue(Object value) {
return ((Boolean) value) ? 1 : 0;
}
}
private static class BooleanToFloatConverter extends ValueConverter {
public Object convertValue(Object value) {
return ((Boolean) value) ? 1.0 : 0.0;
}
}
private static class BooleanToColorConverter extends ValueConverter {
public Object convertValue(Object value) {
return ((Boolean) value) ? Color.WHITE : Color.BLACK;
}
}
private static class GeometryToPointsConverter implements ListConverter {
public List<?> convert(List<?> values) {
ImmutableList.Builder<Object> b = ImmutableList.builder();
for (Object v : values) {
b.addAll(((IGeometry) v).getPoints());
}
return b.build();
}
}
}