package de.blau.android.filter;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.ViewGroup;
import de.blau.android.App;
import de.blau.android.Logic;
import de.blau.android.osm.Node;
import de.blau.android.osm.OsmElement;
import de.blau.android.osm.Relation;
import de.blau.android.osm.Way;
public abstract class Filter implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6L;
/**
* Filter action for elements
*/
enum Include {
DONT,
INCLUDE,
INCLUDE_WITH_WAYNODES
}
/**
* cache for element filter actions
*/
transient HashMap<Node,Include> cachedNodes = new HashMap<Node,Include>(100);
transient HashMap<Way,Include> cachedWays = new HashMap<Way,Include>(100);
transient HashMap<Relation,Include> cachedRelations = new HashMap<Relation,Include>(100);
private transient Logic logic = App.getLogic();
private Filter savedFilter = null;
Filter() {
logic.setAttachedObjectWarning(true); // set this to true when we create a new filter
}
/**
* This is for any serialisation that might have to happen post deseriaisation
* @param context
*/
public void init(Context context) {
}
/**
* If true include this element
* @param node
* @param selected
* @return
*/
public abstract boolean include(Node node, boolean selected);
/**
* If true include this element
* @param way
* @param selected
* @return
*/
public abstract boolean include(Way way, boolean selected);
/**
* If true include this element
* @param relation
* @param selected
* @return
*/
public abstract boolean include(Relation relation, boolean selected);
/**
* Calls the element specific include methods
* @param e
* @param selected
* @return
*/
public boolean include(OsmElement e, boolean selected) {
if (e instanceof Node) {
return include((Node)e, selected);
} else if (e instanceof Way) {
return include((Way)e, selected);
} else if (e instanceof Relation) {
return include((Relation)e, selected);
}
return false;
}
public void saveFilter(Filter filter) {
savedFilter = filter;
}
public Filter getSavedFilter() {
return savedFilter;
}
public interface Update {
void execute();
}
/**
* Add the controls if any to layout
* @param layout
*/
public void addControls(ViewGroup layout, final Update update) {
}
/**
* Remove the controls from layout
* @param layout
*/
public void removeControls() {
}
/**
* Show the controls if any
*/
public void showControls() {
}
/**
* Show the controls if any
*/
public void hideControls() {
}
/**
* Empty the node, way and relation cache
*/
public void clear() {
cachedNodes.clear();
cachedWays.clear();
cachedRelations.clear();
}
/**
* Get all nodes that are currently visible from the cache
* @return
*/
@NonNull
public List<Node> getVisibleNodes() {
List<Node>result = new ArrayList<Node>();
for (Entry<Node,Include>e:cachedNodes.entrySet()) {
if (e.getValue() != Include.DONT) {
result.add(e.getKey());
}
}
return result;
}
/**
* Get all wayss that are currently visible from the cache
* @return
*/
@NonNull
public List<Way> getVisibleWays() {
List<Way>result = new ArrayList<Way>();
for (Entry<Way,Include>e:cachedWays.entrySet()) {
if (e.getValue() != Include.DONT) {
result.add(e.getKey());
}
}
return result;
}
public void saveState() {
}
/**
* Call this on element change to update/invalidate the cache.
*
* The default implementation simply calls {@link #clear()}
* @param pre the element before the change or null
* @param post the element after the change or null
*/
public void onElementChanged(@Nullable List<OsmElement> pre, @Nullable List<OsmElement> post) {
clear();
}
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
// Normal deserialization will not initialize transient objects, need to do it here
cachedNodes = new HashMap<Node,Include>(100);
cachedWays = new HashMap<Way,Include>(100);
cachedRelations = new HashMap<Relation,Include>(100);
}
}