package org.mozilla.osmdroid.events;

import android.os.Handler;

import org.mozilla.mozstumbler.service.core.logging.ClientLog;
import org.mozilla.mozstumbler.svclocator.services.log.LoggerUtil;

/*
 * A MapListener that aggregates multiple events called in quick succession.
 * After an event arrives, if another event arrives within <code>delay</code> milliseconds,
 * the original event is discarded.  Otherwise, the event is propagated to the wrapped
 * MapListener.  Note: This class is not thread-safe.
 *
 * @author Theodore Hong
 */
public class DelayedMapListener implements MapListener {

    /**
     * Default listening delay
     */
    protected static final int DEFAULT_DELAY = 100;
    private static final String LOG_TAG = LoggerUtil.makeLogTag(DelayedMapListener.class);
    /**
     * Listening delay, in milliseconds
     */
    protected long delay;
    protected Handler handler;
    protected CallbackTask callback;
    /**
     * The wrapped MapListener
     */
    MapListener wrappedListener;

    /*
     * @param wrappedListener The wrapped MapListener
     *
     * @param delay Listening delay, in milliseconds
     */
    public DelayedMapListener(final MapListener wrappedListener, final long delay) {
        this.wrappedListener = wrappedListener;
        this.delay = delay;
        this.handler = new Handler();
        this.callback = null;
    }

    /*
     * Constructor with default delay.
     *
     * @param wrappedListener The wrapped MapListener
     */
    public DelayedMapListener(final MapListener wrappedListener) {
        this(wrappedListener, DEFAULT_DELAY);
    }

    @Override
    public boolean onScroll(final ScrollEvent event) {
        dispatch(event);
        return true;
    }

    @Override
    public boolean onZoom(final ZoomEvent event) {
        dispatch(event);
        return true;
    }

    /*
     * Process an incoming MapEvent.
     */
    protected void dispatch(final MapEvent event) {
        // cancel any pending callback
        if (callback != null) {
            handler.removeCallbacks(callback);
        }
        callback = new CallbackTask(event);

        // set timer
        handler.postDelayed(callback, delay);
    }

    // Callback tasks
    private class CallbackTask implements Runnable {
        private final MapEvent event;

        public CallbackTask(final MapEvent event) {
            this.event = event;
        }

        @Override
        public void run() {
            // do the callback
            if (event instanceof ScrollEvent) {
                wrappedListener.onScroll((ScrollEvent) event);
            } else if (event instanceof ZoomEvent) {
                wrappedListener.onZoom((ZoomEvent) event);
            } else {
                // unknown event; discard
                ClientLog.d(LOG_TAG, "Unknown event received: " + event);
            }
        }
    }
}

@@ -931,18 +931,65 @@
 callback
+Scroll;%0A    protected CallbackTask callbackZoom
 ;%0A
-
     /**%0A
@@ -1406,24 +1406,64 @@
 his.callback
+Scroll = null;%0A        this.callbackZoom
  = null;%0A   
@@ -1774,38 +1774,71 @@
 ) %7B%0A        
-dispatch(event
+callbackScroll = dispatch(event, callbackScroll
 );%0A        r
@@ -1929,30 +1929,59 @@
         
-dispatch(event
+callbackZoom = dispatch(event, callbackZoom
 );%0A     
@@ -2069,20 +2069,28 @@
 otected 
-void
+CallbackTask
  dispatc
@@ -2103,32 +2103,55 @@
 l MapEvent event
+, CallbackTask callback
 ) %7B%0A        // c
@@ -2332,16 +2332,16 @@
 t timer%0A
-
         
@@ -2378,16 +2378,41 @@
 delay);%0A
+        return callback;%0A
     %7D%0A%0A 

fix zoom