ingo@136: package de.intevation.flys.artifacts.states;
ingo@136: 
ingo@136: import org.apache.log4j.Logger;
ingo@136: 
ingo@628: import gnu.trove.TDoubleArrayList;
ingo@628: 
ingo@313: import de.intevation.artifacts.Artifact;
ingo@136: 
ingo@136: import de.intevation.artifactdatabase.data.StateData;
ingo@313: 
raimund@3628: import de.intevation.flys.artifacts.FLYSArtifact;
sascha@1055: import de.intevation.flys.artifacts.WINFOArtifact;
sascha@697: 
ingo@136: 
ingo@136: /**
ingo@136:  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
ingo@136:  */
sascha@742: public class LocationDistanceSelect
ingo@921: extends      ComputationRangeState
sascha@721: {
ingo@136: 
felix@1838:     /** The logger used in this class. */
ingo@136:     private static Logger logger = Logger.getLogger(LocationDistanceSelect.class);
ingo@136: 
ingo@627:     /** The name of the 'mode' field. */
ingo@627:     public static final String MODE = "ld_mode";
ingo@627: 
felix@2235:     /** The name of the 'locations' field. */
ingo@627:     public static final String LOCATIONS = "ld_locations";
ingo@627: 
ingo@322: 
ingo@136:     /**
ingo@136:      * The default constructor that initializes an empty State object.
ingo@136:      */
ingo@136:     public LocationDistanceSelect() {
ingo@136:     }
ingo@136: 
ingo@136: 
sascha@660:     @Override
ingo@136:     protected String getUIProvider() {
ingo@136:         return "location_distance_panel";
ingo@136:     }
ingo@313: 
ingo@313: 
felix@3265:     /** Validates the range (or location). */
ingo@322:     @Override
sascha@1050:     public boolean validate(Artifact artifact)
ingo@322:     throws IllegalArgumentException
ingo@322:     {
ingo@322:         logger.debug("LocationDistanceSelect.validate");
ingo@322: 
raimund@3628:         FLYSArtifact flys = (FLYSArtifact)artifact;
raimund@3628:         StateData mode = getData(flys, MODE);
raimund@3628:         String mValue = mode != null ? (String)mode.getValue() : null;
raimund@3628:         if (mValue != null) {
raimund@3628:             if (mValue.equals("distance")) {
raimund@3628:                 return super.validate(flys);
raimund@3628:             }
raimund@3628:             else {
raimund@3628:                 return validateLocations(flys);
raimund@3628:             }
ingo@627:         }
raimund@3628:         return false;
ingo@627:     }
ingo@627: 
ingo@627: 
felix@4043:     /** Validate selected locations. */
raimund@3628:     protected boolean validateLocations(FLYSArtifact flys)
ingo@627:     throws    IllegalArgumentException
ingo@627:     {
ingo@627:         StateData dValues = getData(flys, LOCATIONS);
ingo@627:         String    values  = dValues != null ? (String)dValues.getValue() : null;
ingo@627: 
ingo@627:         if (values == null || values.length() == 0) {
ingo@627:             throw new IllegalArgumentException("error_empty_state");
ingo@627:         }
ingo@627: 
ingo@921:         double[] absMinMax = getMinMax(flys);
ingo@627:         double[] relMinMax = getMinMaxFromString(values);
ingo@627: 
ingo@627:         if (relMinMax[0] < absMinMax[0] || relMinMax[0] > absMinMax[1]) {
ingo@627:             throw new IllegalArgumentException("error_feed_from_out_of_range");
ingo@627:         }
ingo@627: 
ingo@627:         if (relMinMax[1] > absMinMax[1] || relMinMax[1] < absMinMax[0]) {
ingo@627:             throw new IllegalArgumentException("error_feed_to_out_of_range");
ingo@627:         }
ingo@627: 
ingo@627:         return true;
ingo@627:     }
ingo@627: 
ingo@627: 
ingo@627:     /**
ingo@627:      * Extracts the min/max values from String <i>s</i>. An
ingo@627:      * IllegalArgumentException is thrown if there is a value that throws a
ingo@627:      * NumberFormatException.
ingo@627:      *
ingo@627:      * @param s String that contains whitespace separated double values.
ingo@627:      *
ingo@627:      * @return a 2dmin array [min,max].
ingo@627:      */
ingo@627:     public static double[] getMinMaxFromString(String s)
ingo@627:     throws IllegalArgumentException
ingo@627:     {
ingo@627:         String[] values = s.split(" ");
ingo@627: 
ingo@627:         double[] minmax = new double[] {
ingo@627:             Double.MAX_VALUE,
ingo@627:             -Double.MAX_VALUE };
ingo@627: 
ingo@627:         for (String v: values) {
ingo@627:             try {
ingo@627:                 double value = Double.valueOf(v);
ingo@627: 
ingo@627:                 minmax[0] = minmax[0] < value ? minmax[0] : value;
ingo@627:                 minmax[1] = minmax[1] > value ? minmax[1] : value;
ingo@627:             }
ingo@627:             catch (NumberFormatException nfe) {
ingo@627:                 throw new IllegalArgumentException(
ingo@627:                     "error_invalid_double_value");
ingo@627:             }
ingo@627:         }
ingo@627: 
ingo@627:         return minmax;
ingo@627:     }
ingo@628: 
ingo@628: 
sascha@1055:     public static double[] getLocations(WINFOArtifact flys) {
felix@2235:         StateData data  = flys.getData(LOCATIONS);
ingo@628:         String    value = data != null ? (String) data.getValue() : null;
ingo@628: 
ingo@628:         if (value == null || value.length() == 0) {
ingo@628:             logger.warn("No location data given.");
ingo@628:             return null;
ingo@628:         }
ingo@628: 
ingo@628:         String[]         splitted = value.split(" ");
ingo@628:         TDoubleArrayList values   = new TDoubleArrayList();
ingo@628: 
ingo@628:         for (String split: splitted) {
ingo@628:             try {
ingo@628:                 values.add(Double.valueOf(split));
ingo@628:             }
ingo@628:             catch (NumberFormatException nfe) {
ingo@628:                 logger.warn(nfe, nfe);
ingo@628:             }
ingo@628:         }
ingo@628: 
ingo@628:         return values.toNativeArray();
ingo@628:     }
ingo@136: }
ingo@136: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :