package usda.weru.gis;

import java.util.LinkedList;
import java.util.List;
import javax.measure.Quantity;
import javax.measure.quantity.Length;
import org.geotools.data.DataStore;
import org.opengis.feature.Feature;
import org.opengis.geometry.DirectPosition;

/**
 * provides several ways to look up things within other GISLookup objects
 * @param <T> 
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class MergedGISLookup<T> implements GISLookup<T> {

    private final Class<T> c_class;
    private final List<GISLookup<T>> c_lookups;

    /**
     * takes one or more GISLookup objects and merges them
     * @param c
     * @param lookups
     */
    @SuppressWarnings("unchecked")
    public MergedGISLookup(Class<T> c, List<GISLookup<T>> lookups) {
        c_class = c;
        c_lookups = lookups;
    }

    @Override
    public void register(String id, DataStore data) {
        // Do Nothing, the proxied lookups will take care of the actual data work
    }

    @Override
    public boolean supports(Class<?> c) {
        return c_class.isAssignableFrom(c);
    }

    @Override
    public List<T> lookup() {
        List<T> result = new LinkedList<T>();

        // single threaded
        for (GISLookup<T> lookup : c_lookups) {
            List<T> temp = lookup.lookup();
            // no test for duplicates
            result.addAll(temp);
        }

        return result;
    }

    @Override
    public List<T> lookup(DirectPosition latlong) {
        List<T> result = new LinkedList<T>();

        // single threaded
        for (GISLookup<T> lookup : c_lookups) {
            List<T> temp = lookup.lookup(latlong);
            // no test for duplicates
            result.addAll(temp);
        }

        return result;
    }

    @Override
    public List<T> lookup(DirectPosition latlong, Quantity<Length> radius) {
        List<T> result = new LinkedList<T>();

        // single threaded
        for (GISLookup<T> lookup : c_lookups) {
            List<T> temp = lookup.lookup(latlong, radius);
            // no test for duplicates
            result.addAll(temp);
        }

        return result;
    }

    @Override
    public List<Feature> lookup(T object) {
        List<Feature> result = new LinkedList<Feature>();

        // single threaded
        if (object != null) {
            for (GISLookup<T> lookup : c_lookups) {
                if (lookup.supports(c_class)) {
                    List<Feature> temp = lookup.lookup(object);
                    // no test for duplicates
                    result.addAll(temp);
                }
            }
        }
        return result;
    }
}
