/*
* Copyright 2012 osmdroid
* Copyright 2013 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
package org.oscim.overlay;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.oscim.core.MapPosition;
import org.oscim.overlay.Overlay.Snappable;
import org.oscim.renderer.overlays.RenderOverlay;
import org.oscim.view.MapView;
import android.graphics.Point;
import android.view.KeyEvent;
import android.view.MotionEvent;
public class OverlayManager extends AbstractList {
private final CopyOnWriteArrayList mOverlayList;
public OverlayManager() {
mOverlayList = new CopyOnWriteArrayList();
}
@Override
public synchronized Overlay get(final int pIndex) {
return mOverlayList.get(pIndex);
}
@Override
public synchronized int size() {
return mOverlayList.size();
}
@Override
public synchronized void add(final int pIndex, final Overlay pElement) {
mOverlayList.add(pIndex, pElement);
mDirtyOverlays = true;
}
@Override
public synchronized Overlay remove(final int pIndex) {
mDirtyOverlays = true;
return mOverlayList.remove(pIndex);
}
@Override
public synchronized Overlay set(final int pIndex, final Overlay pElement) {
mDirtyOverlays = true;
return mOverlayList.set(pIndex, pElement);
}
private boolean mDirtyOverlays;
private List mDrawLayers = new ArrayList();
public List getRenderLayers() {
if (mDirtyOverlays)
updateOverlays();
return mDrawLayers;
}
public void onDetach(final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
o.onDetach(pMapView);
}
Overlay[] mOverlays;
private synchronized void updateOverlays() {
if (!mDirtyOverlays)
return;
mOverlays = new Overlay[mOverlayList.size()];
mDrawLayers.clear();
for (int i = 0, n = mOverlayList.size(); i < n; i++) {
Overlay o = mOverlayList.get(i);
RenderOverlay l = o.getLayer();
if (l != null)
mDrawLayers.add(l);
mOverlays[n - i - 1] = o;
}
mDirtyOverlays = false;
}
public boolean onKeyDown(final int keyCode, final KeyEvent event, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onKeyDown(keyCode, event, pMapView))
return true;
return false;
}
public boolean onKeyUp(final int keyCode, final KeyEvent event, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onKeyUp(keyCode, event, pMapView))
return true;
return false;
}
public boolean onTouchEvent(final MotionEvent event, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onTouchEvent(event, pMapView))
return true;
return false;
}
public boolean onTrackballEvent(final MotionEvent event, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onTrackballEvent(event, pMapView))
return true;
return false;
}
public boolean onSnapToItem(final int x, final int y, final Point snapPoint,
final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o instanceof Snappable)
if (((Snappable) o).onSnapToItem(x, y, snapPoint, pMapView))
return true;
return false;
}
/* GestureDetector.OnDoubleTapListener */
public boolean onDoubleTap(final MotionEvent e, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onDoubleTap(e, pMapView))
return true;
return false;
}
public boolean onDoubleTapEvent(final MotionEvent e, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onDoubleTapEvent(e, pMapView))
return true;
return false;
}
public boolean onSingleTapConfirmed(final MotionEvent e, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onSingleTapConfirmed(e, pMapView))
return true;
return false;
}
/* OnGestureListener */
public boolean onDown(final MotionEvent pEvent, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onDown(pEvent, pMapView))
return true;
return false;
}
public boolean onFling(final MotionEvent pEvent1, final MotionEvent pEvent2,
final float pVelocityX, final float pVelocityY, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onFling(pEvent1, pEvent2, pVelocityX, pVelocityY, pMapView))
return true;
return false;
}
public boolean onLongPress(final MotionEvent pEvent, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onLongPress(pEvent, pMapView))
return true;
return false;
}
public boolean onScroll(final MotionEvent pEvent1, final MotionEvent pEvent2,
final float pDistanceX, final float pDistanceY, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onScroll(pEvent1, pEvent2, pDistanceX, pDistanceY, pMapView))
return true;
return false;
}
public void onShowPress(final MotionEvent pEvent, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
o.onShowPress(pEvent, pMapView);
}
public boolean onSingleTapUp(final MotionEvent pEvent, final MapView pMapView) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
if (o.onSingleTapUp(pEvent, pMapView))
return true;
return false;
}
public void onUpdate(MapPosition mapPosition, boolean changed) {
if (mDirtyOverlays)
updateOverlays();
for (Overlay o : mOverlays)
o.onUpdate(mapPosition, changed);
}
// /**
// * Gets the optional TilesOverlay class.
// *
// * @return the tilesOverlay
// */
// public TilesOverlay getTilesOverlay() {
// return mTilesOverlay;
// }
//
// /**
// * Sets the optional TilesOverlay class. If set, this overlay will be
// drawn before all other
// * overlays and will not be included in the editable list of overlays and
// can't be cleared
// * except by a subsequent call to setTilesOverlay().
// *
// * @param tilesOverlay
// * the tilesOverlay to set
// */
// public void setTilesOverlay(final TilesOverlay tilesOverlay) {
// mTilesOverlay = tilesOverlay;
// }
// public void onDraw(final Canvas c, final MapView pMapView) {
// // if ((mTilesOverlay != null) && mTilesOverlay.isEnabled()) {
// // mTilesOverlay.draw(c, pMapView, true);
// // }
// //
// // if ((mTilesOverlay != null) && mTilesOverlay.isEnabled()) {
// // mTilesOverlay.draw(c, pMapView, false);
// // }
//
// for (final Overlay overlay : mOverlayList) {
// if (overlay.isEnabled()) {
// overlay.draw(c, pMapView, true);
// }
// }
//
// for (final Overlay overlay : mOverlayList) {
// if (overlay.isEnabled()) {
// overlay.draw(c, pMapView, false);
// }
// }
//
// }
// ** Options Menu **//
// public void setOptionsMenusEnabled(final boolean pEnabled) {
// for (final Overlay overlay : mOverlayList) {
// if ((overlay instanceof IOverlayMenuProvider)
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
// ((IOverlayMenuProvider) overlay).setOptionsMenuEnabled(pEnabled);
// }
// }
// }
//
// public boolean onCreateOptionsMenu(final Menu pMenu, final int
// menuIdOffset,
// final MapView mapView) {
// boolean result = true;
// for (final Overlay overlay : this.overlaysReversed()) {
// if ((overlay instanceof IOverlayMenuProvider)
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
// result &= ((IOverlayMenuProvider) overlay).onCreateOptionsMenu(pMenu,
// menuIdOffset,
// mapView);
// }
// }
//
// if ((mTilesOverlay != null) && (mTilesOverlay instanceof
// IOverlayMenuProvider)
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()) {
// result &= mTilesOverlay.onCreateOptionsMenu(pMenu, menuIdOffset,
// mapView);
// }
//
// return result;
// }
//
// public boolean onPrepareOptionsMenu(final Menu pMenu, final int
// menuIdOffset,
// final MapView mapView) {
// for (final Overlay overlay : this.overlaysReversed()) {
// if ((overlay instanceof IOverlayMenuProvider)
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()) {
// ((IOverlayMenuProvider) overlay).onPrepareOptionsMenu(pMenu,
// menuIdOffset, mapView);
// }
// }
//
// if ((mTilesOverlay != null) && (mTilesOverlay instanceof
// IOverlayMenuProvider)
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()) {
// mTilesOverlay.onPrepareOptionsMenu(pMenu, menuIdOffset, mapView);
// }
//
// return true;
// }
//
// public boolean onOptionsItemSelected(final MenuItem item, final int
// menuIdOffset,
// final MapView mapView) {
// for (final Overlay overlay : this.overlaysReversed()) {
// if ((overlay instanceof IOverlayMenuProvider)
// && ((IOverlayMenuProvider) overlay).isOptionsMenuEnabled()
// && ((IOverlayMenuProvider) overlay).onOptionsItemSelected(item,
// menuIdOffset,
// mapView)) {
// return true;
// }
// }
//
// if ((mTilesOverlay != null)
// && (mTilesOverlay instanceof IOverlayMenuProvider)
// && ((IOverlayMenuProvider) mTilesOverlay).isOptionsMenuEnabled()
// && ((IOverlayMenuProvider) mTilesOverlay).onOptionsItemSelected(item,
// menuIdOffset,
// mapView)) {
// return true;
// }
//
// return false;
// }
}