package org.vfny.geoserver.global;

import java.awt.RenderingHints.Key;
import java.io.IOException;
import java.util.List;
import java.util.Set;

import org.geotools.data.DataAccess;
import org.geotools.data.FeatureListener;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Query;
import org.geotools.data.QueryCapabilities;
import org.geotools.data.ResourceInfo;
import org.geotools.data.Transaction;
import org.geotools.feature.FeatureCollection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.Feature;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.filter.identity.FeatureId;

public class PrefetchingFeatureStore<T extends FeatureType, F extends Feature> implements
        FeatureStore<T, F> {
    FeatureStore<T, F> delegate;

    int queueDepth;

    public PrefetchingFeatureStore(FeatureStore<T, F> delegate, int queueDepth) {
        this.delegate = delegate;
        this.queueDepth = queueDepth;
    }

    public List<FeatureId> addFeatures(FeatureCollection<T, F> collection) throws IOException {
        return delegate.addFeatures(collection);
    }

    public Transaction getTransaction() {
        return delegate.getTransaction();
    }

    public void modifyFeatures(AttributeDescriptor type, Object value, Filter filter)
            throws IOException {
        delegate.modifyFeatures(type, value, filter);
    }

    public void modifyFeatures(AttributeDescriptor[] type, Object[] value, Filter filter)
            throws IOException {
        delegate.modifyFeatures(type, value, filter);
    }

    public void removeFeatures(Filter filter) throws IOException {
        delegate.removeFeatures(filter);
    }

    public void setFeatures(FeatureReader<T, F> reader) throws IOException {
        delegate.setFeatures(reader);
    }

    public void setTransaction(Transaction transaction) {
        delegate.setTransaction(transaction);
    }

    public void addFeatureListener(FeatureListener listener) {
        delegate.addFeatureListener(listener);
    }

    public ReferencedEnvelope getBounds() throws IOException {
        return delegate.getBounds();
    }

    public ReferencedEnvelope getBounds(Query query) throws IOException {
        return delegate.getBounds(query);
    }

    public int getCount(Query query) throws IOException {
        return delegate.getCount(query);
    }

    public DataAccess<T, F> getDataStore() {
        return delegate.getDataStore();
    }

    public FeatureCollection<T, F> getFeatures() throws IOException {
        return new PrefetchingFeatureCollection<T, F>(delegate.getFeatures(), queueDepth);
    }

    public FeatureCollection<T, F> getFeatures(Filter filter) throws IOException {
        return new PrefetchingFeatureCollection<T, F>(delegate.getFeatures(filter), queueDepth);
    }

    public FeatureCollection<T, F> getFeatures(Query query) throws IOException {
        return new PrefetchingFeatureCollection<T, F>(delegate.getFeatures(query), queueDepth);
    }

    public ResourceInfo getInfo() {
        return delegate.getInfo();
    }

    public Name getName() {
        return delegate.getName();
    }

    public QueryCapabilities getQueryCapabilities() {
        return delegate.getQueryCapabilities();
    }

    public T getSchema() {
        return delegate.getSchema();
    }

    public Set<Key> getSupportedHints() {
        return delegate.getSupportedHints();
    }

    public void removeFeatureListener(FeatureListener listener) {
        delegate.removeFeatureListener(listener);
    }

}
