package jp.gauzau.MikuMikuDroidmod;

import android.graphics.PointF;
import android.util.Log;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;

public class CameraLocrotscaleGestureListener extends SimpleOnGestureListener implements
        OnScaleGestureListener {

    private static final float MIN_START_TRANSLATE_DISTANCE_SQR = 0.07f;

    private static final float MIN_ZOOM_START_FACTOR = 1.1f;

    private static final String TAG = "CameraLocrotGestureListner";

    private boolean mIsOnTranslate;
    private boolean mIsOnZoom;

    private float mZoomRate = 1;
    private float mPreviousZoomRate = 1;
    private final float[] mLocationRate = new float[] { 0, 0, 0 };
    private final float[] mPreviousLocationRate = new float[] { 0, 0, 0 };
    private final float[] mRotationRate = new float[] { 0, 0, 0 };
    private final float[] mPreviousRotationRate = new float[] { 0, 0, 0 };

    private final PointF mPreviousFocus = new PointF();
    private final PointF mFocusDiffRate = new PointF();

    private float mSmallerScreenWidth = 1;

    private final CoreLogic mCoreLogic;
    
    private void applyZoom() {
        mCoreLogic.mCameraZoom = -35 * mZoomRate;
    }
    
    
    public CameraLocrotscaleGestureListener(CoreLogic coreLogic) {
        mCoreLogic = coreLogic;
        applyZoom();
    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        if (!mIsOnTranslate && !mIsOnZoom) {
            float factor = detector.getScaleFactor();
            float changeRate = factor >= 1 ? factor : 1 / factor;
            if (changeRate > MIN_ZOOM_START_FACTOR) {
                Log.d(TAG, "Start zooming");
                mIsOnZoom = true;
            }
            else {
                mFocusDiffRate.set((detector.getFocusX() - mPreviousFocus.x)
                        / mSmallerScreenWidth, (detector.getFocusY() - mPreviousFocus.y)
                        / mSmallerScreenWidth);
                float movedDistanceRateSqr = mFocusDiffRate.x * mFocusDiffRate.x
                        + mFocusDiffRate.y * mFocusDiffRate.y;
                if (movedDistanceRateSqr > MIN_START_TRANSLATE_DISTANCE_SQR) {
                    Log.d(TAG, "Start translating");
                    mIsOnTranslate = true;
                }
            }
        }
        if (mIsOnTranslate) {
            // TODO: 3d
            mLocationRate[0] = mPreviousLocationRate[0]
                    + (detector.getFocusX() - mPreviousFocus.x) / mSmallerScreenWidth;
            mLocationRate[1] = mPreviousLocationRate[1]
                    + (detector.getFocusX() - mPreviousFocus.x) / mSmallerScreenWidth;
        }
        else if (mIsOnZoom) {
            float factor = detector.getScaleFactor();
            mZoomRate = mPreviousZoomRate * factor;
            applyZoom();
        }
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        mPreviousFocus.set(detector.getFocusX(), detector.getFocusY());
        mSmallerScreenWidth = Math.min(mCoreLogic.getScreenWidth(), mCoreLogic
                .getScreenHeight());

        mPreviousZoomRate = mZoomRate;
        System.arraycopy(mLocationRate, 0, mPreviousLocationRate, 0, 3);
        System.arraycopy(mRotationRate, 0, mPreviousRotationRate, 0, 3);
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {
        mIsOnTranslate = mIsOnZoom = false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        // TODO Auto-generated method stub
        return super.onScroll(e1, e2, distanceX, distanceY);
    }
    
    

}

@@ -497,9 +497,11 @@
  0.0
-7
+075
 f;%0D%0A
@@ -559,17 +559,17 @@
 TOR = 1.
-1
+2
 f;%0D%0A%0D%0A  
@@ -761,24 +761,25 @@
  float m
-Previous
+Beginning
 ZoomRate
@@ -880,24 +880,25 @@
 loat%5B%5D m
-Previous
+Beginning
 Location
@@ -1025,24 +1025,25 @@
 loat%5B%5D m
-Previous
+Beginning
 Rotation
@@ -1103,24 +1103,25 @@
 PointF m
-Previous
+Beginning
 Focus = 
@@ -1191,16 +1191,51 @@
 intF();%0D
+%0A    private float mBeginningSpan;%0D
 %0A%0D%0A    p
@@ -1391,17 +1391,17 @@
 m = -35 
-*
+/
  mZoomRa
@@ -1713,37 +1713,54 @@
 detector.get
-ScaleFactor()
+CurrentSpan() / mBeginningSpan
 ;%0D%0A         
@@ -2044,32 +2044,33 @@
 FocusX() - m
-Previous
+Beginning
 Focus.x)%0D%0A  
@@ -2135,32 +2135,33 @@
 FocusY() - m
-Previous
+Beginning
 Focus.y)%0D%0A  
@@ -2353,16 +2353,82 @@
 ate.y;%0D%0A
+                Log.d(TAG, %22dist sqr: %22 + movedDistanceRateSqr);%0D%0A
         
@@ -2726,32 +2726,33 @@
 nRate%5B0%5D = m
-Previous
+Beginning
 LocationRate
@@ -2799,32 +2799,33 @@
 FocusX() - m
-Previous
+Beginning
 Focus.x) / m
@@ -2877,24 +2877,25 @@
 e%5B1%5D = m
-Previous
+Beginning
 Location
@@ -2950,24 +2950,25 @@
 sX() - m
-Previous
+Beginning
 Focus.x)
@@ -3077,21 +3077,38 @@
 .get
-ScaleFactor()
+CurrentSpan() / mBeginningSpan
 ;%0D%0A 
@@ -3131,24 +3131,25 @@
 Rate = m
-Previous
+Beginning
 ZoomRate
@@ -3318,24 +3318,25 @@
        m
-Previous
+Beginning
 Focus.se
@@ -3512,24 +3512,25 @@
        m
-Previous
+Beginning
 ZoomRate
@@ -3540,24 +3540,77 @@
 mZoomRate;%0D%0A
+        mBeginningSpan = detector.getCurrentSpan();%0D%0A
         Syst
@@ -3641,24 +3641,25 @@
 te, 0, m
-Previous
+Beginning
 Location
@@ -3720,16 +3720,17 @@
 0, m
-Previous
+Beginning
 Rota
@@ -3739,32 +3739,68 @@
 onRate, 0, 3);%0D%0A
+        Log.d(TAG, %22Scale bigin%22);%0D%0A
         return t

Fix my misunderstood API uses.