package org.blitzortung.android.map;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import com.google.android.maps.MapView;
import com.google.android.maps.Projection;
import org.blitzortung.android.app.R;

import java.util.HashSet;
import java.util.Set;

public class OwnMapView extends MapView {

	private final Set<ZoomListener> zoomListeners = new HashSet<ZoomListener>();

    private View popUp = null;

	public interface ZoomListener {
		void onZoom(int zoomLevel);
	}

    public OwnMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public OwnMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

	public OwnMapView(Context context, String apiKey) {
		super(context, apiKey);
	}

	private float oldPixelSize = -1;

	@Override
	public void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);

		detectAndHandleZoomAction();
	}

    private long firstTapDownTime;
    private int tapCount;

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		boolean result = super.onTouchEvent(event);

        detectAndHandleDoubleTap(event);
        detectAndHandleZoomAction();
		
		return result;
	}

    private void detectAndHandleDoubleTap(MotionEvent event) {
        long currentTime = System.currentTimeMillis();
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (currentTime - firstTapDownTime < 400) {
                tapCount++;
            } else {
                firstTapDownTime = currentTime;
                tapCount = 1;
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (tapCount == 2 && currentTime - firstTapDownTime < 400) {
                removeView(getPopup());

                int x = (int)event.getX(), y = (int)event.getY();;
                Projection p = getProjection();
                getController().animateTo(p.fromPixels(x, y));
                getController().zoomIn();

                firstTapDownTime = 0;
            }
        }
    }

    protected void detectAndHandleZoomAction() {
        if (getProjection() != null) {
            float pixelSize = getProjection().metersToEquatorPixels(1000.0f);

            if (pixelSize != oldPixelSize) {
                notifyZoomListeners();
                oldPixelSize = pixelSize;
            }
        }
	}

	public void addZoomListener(ZoomListener zoomListener) {
		zoomListeners.add(zoomListener);
	}

	public void notifyZoomListeners() {
		for (ZoomListener zoomListener : zoomListeners) {
			zoomListener.onZoom(getZoomLevel());
		}
	}

    public int calculateTargetZoomLevel(float widthInMeters) {
        double equatorLength = 40075004; // in meters
        double widthInPixels = Math.min(getHeight(), getWidth());
        double metersPerPixel = equatorLength / 256;
        int zoomLevel = 1;
        while ((metersPerPixel * widthInPixels) > widthInMeters) {
            metersPerPixel /= 2;
            ++zoomLevel;
        }
        return zoomLevel - 1;
    }

    public synchronized View getPopup() {
        if (popUp == null) {
            popUp = LayoutInflater.from(getContext()).inflate(R.layout.popup, this, false);
        }
        return popUp;
    }
}

@@ -125,24 +125,61 @@
 tributeSet;%0A
+import android.view.GestureDetector;%0A
 import andro
@@ -585,18 +585,71 @@
 = null;%0A
-%0A%09
+    %0A    private GestureDetector gestureDetector;%0A%0A    
 public i
@@ -798,16 +798,32 @@
 attrs);%0A
+        init();%0A
     %7D%0A%0A 
@@ -933,24 +933,40 @@
  defStyle);%0A
+        init();%0A
     %7D%0A%0A%09publ
@@ -1039,21 +1039,568 @@
 piKey);%0A
-%09%7D%0A%0A%09
+        init();%0A    %7D%0A%0A    private void init() %7B%0A        gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() %7B%0A            @Override%0A            public boolean onDoubleTap(MotionEvent event) %7B%0A                removeView(getPopup());%0A%0A                int x = (int)event.getX(), y = (int)event.getY();;%0A                Projection p = getProjection();%0A                getController().animateTo(p.fromPixels(x, y));%0A                getController().zoomIn();%0A                return true;%0A            %7D%0A        %7D);%0A    %7D%0A%0A    
 private 
@@ -1683,39 +1683,8 @@
 ) %7B%0A
-%09%09super.dispatchDraw(canvas);%0A%0A
 %09%09de
@@ -1718,70 +1718,8 @@
 %09%7D%0A%0A
-    private long firstTapDownTime;%0A    private int tapCount;%0A%0A
 %09@Ov
@@ -1834,664 +1834,53 @@
     
-detectAndHandleDoubleTap(event);%0A        detectAndHandleZoomAction();%0A%09%09%0A%09%09return result;%0A%09%7D%0A%0A    private void detectAndHandleDoubleTap(MotionEvent event) %7B%0A        long currentTime = System.currentTimeMillis();%0A        if (event.getAction() == MotionEvent.ACTION_DOWN) %7B%0A            if (currentTime - firstTapDownTime %3C 400) %7B%0A                tapCount++;%0A            %7D else %7B%0A                firstTapDownTime = currentTime;%0A                tapCount = 1;%0A            %7D%0A        %7D else if (event.getAction() == MotionEvent.ACTION_UP) %7B%0A            if (tapCount == 2 && currentTime - firstTapDownTime %3C 400) %7B%0A                removeView(getPopup()
+gestureDetector.onTouchEvent(event
 );%0A
-%0A
         
     
@@ -1879,287 +1879,33 @@
     
-        int x = (int)event.getX(), y = (int)event.getY();;%0A                Projection p = getProjection();%0A                getController().animateTo(p.fromPixels(x, y));%0A                getController().zoomIn();%0A%0A                firstTapDownTime = 0;%0A            %7D%0A        %7D%0A    
+%0A        return result;%0A%09
 %7D%0A%0A 

use default gesture detector