/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.ui;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.media.FaceDetector;
import android.os.Handler;
import android.os.Message;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Toast;

import com.android.gallery3d.R;
import com.android.gallery3d.anim.Animation;
import com.android.gallery3d.app.GalleryActivity;
import com.android.gallery3d.common.Utils;

import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL11;

/**
 * The activity can crop specific region of interest from an image.
 */
public class CropView extends GLView {
    private static final String TAG = "CropView";

    private static final int FACE_PIXEL_COUNT = 120000; // around 400x300

    private static final int COLOR_OUTLINE = 0xFF008AFF;
    private static final int COLOR_FACE_OUTLINE = 0xFF000000;

    private static final float OUTLINE_WIDTH = 3f;

    private static final int SIZE_UNKNOWN = -1;
    private static final int TOUCH_TOLERANCE = 30;

    private static final float MIN_SELECTION_LENGTH = 16f;
    public static final float UNSPECIFIED = -1f;

    private static final int MAX_FACE_COUNT = 3;
    private static final float FACE_EYE_RATIO = 2f;

    private static final int ANIMATION_DURATION = 1250;

    private static final int MOVE_LEFT = 1;
    private static final int MOVE_TOP = 2;
    private static final int MOVE_RIGHT = 4;
    private static final int MOVE_BOTTOM = 8;
    private static final int MOVE_BLOCK = 16;

    private static final float MAX_SELECTION_RATIO = 0.8f;
    private static final float MIN_SELECTION_RATIO = 0.4f;
    private static final float SELECTION_RATIO = 0.60f;
    private static final int ANIMATION_TRIGGER = 64;

    private static final int MSG_UPDATE_FACES = 1;

    private float mAspectRatio = UNSPECIFIED;
    private float mSpotlightRatioX = 0;
    private float mSpotlightRatioY = 0;

    private Handler mMainHandler;

    private FaceHighlightView mFaceDetectionView;
    private HighlightRectangle mHighlightRectangle;
    private TileImageView mImageView;
    private AnimationController mAnimation = new AnimationController();

    private int mImageWidth = SIZE_UNKNOWN;
    private int mImageHeight = SIZE_UNKNOWN;

    private GalleryActivity mActivity;

    private GLPaint mPaint = new GLPaint();
    private GLPaint mFacePaint = new GLPaint();

    private int mImageRotation;

    public CropView(GalleryActivity activity) {
        mActivity = activity;
        mImageView = new TileImageView(activity);
        mFaceDetectionView = new FaceHighlightView();
        mHighlightRectangle = new HighlightRectangle();

        addComponent(mImageView);
        addComponent(mFaceDetectionView);
        addComponent(mHighlightRectangle);

        mHighlightRectangle.setVisibility(GLView.INVISIBLE);

        mPaint.setColor(COLOR_OUTLINE);
        mPaint.setLineWidth(OUTLINE_WIDTH);

        mFacePaint.setColor(COLOR_FACE_OUTLINE);
        mFacePaint.setLineWidth(OUTLINE_WIDTH);

        mMainHandler = new SynchronizedHandler(activity.getGLRoot()) {
            @Override
            public void handleMessage(Message message) {
                Utils.assertTrue(message.what == MSG_UPDATE_FACES);
                ((DetectFaceTask) message.obj).updateFaces();
            }
        };
    }

    public void setAspectRatio(float ratio) {
        mAspectRatio = ratio;
    }

    public void setSpotlightRatio(float ratioX, float ratioY) {
        mSpotlightRatioX = ratioX;
        mSpotlightRatioY = ratioY;
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        int width = r - l;
        int height = b - t;

        mFaceDetectionView.layout(0, 0, width, height);
        mHighlightRectangle.layout(0, 0, width, height);
        mImageView.layout(0, 0, width, height);
        if (mImageHeight != SIZE_UNKNOWN) {
            mAnimation.initialize();
            if (mHighlightRectangle.getVisibility() == GLView.VISIBLE) {
                mAnimation.parkNow(
                        mHighlightRectangle.mHighlightRect);
            }
        }
    }

    private boolean setImageViewPosition(int centerX, int centerY, float scale) {
        int inverseX = mImageWidth - centerX;
        int inverseY = mImageHeight - centerY;
        TileImageView t = mImageView;
        int rotation = mImageRotation;
        switch (rotation) {
            case 0: return t.setPosition(centerX, centerY, scale, 0);
            case 90: return t.setPosition(centerY, inverseX, scale, 90);
            case 180: return t.setPosition(inverseX, inverseY, scale, 180);
            case 270: return t.setPosition(inverseY, centerX, scale, 270);
            default: throw new IllegalArgumentException(String.valueOf(rotation));
        }
    }

    @Override
    public void render(GLCanvas canvas) {
        AnimationController a = mAnimation;
        if (a.calculate(AnimationTime.get())) invalidate();
        setImageViewPosition(a.getCenterX(), a.getCenterY(), a.getScale());
        super.render(canvas);
    }

    @Override
    public void renderBackground(GLCanvas canvas) {
        canvas.clearBuffer();
    }

    public RectF getCropRectangle() {
        if (mHighlightRectangle.getVisibility() == GLView.INVISIBLE) return null;
        RectF rect = mHighlightRectangle.mHighlightRect;
        RectF result = new RectF(rect.left * mImageWidth, rect.top * mImageHeight,
                rect.right * mImageWidth, rect.bottom * mImageHeight);
        return result;
    }

    public int getImageWidth() {
        return mImageWidth;
    }

    public int getImageHeight() {
        return mImageHeight;
    }

    private class FaceHighlightView extends GLView {
        private static final int INDEX_NONE = -1;
        private ArrayList<RectF> mFaces = new ArrayList<RectF>();
        private RectF mRect = new RectF();
        private int mPressedFaceIndex = INDEX_NONE;

        public void addFace(RectF faceRect) {
            mFaces.add(faceRect);
            invalidate();
        }

        private void renderFace(GLCanvas canvas, RectF face, boolean pressed) {
            GL11 gl = canvas.getGLInstance();
            if (pressed) {
                gl.glEnable(GL11.GL_STENCIL_TEST);
                gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
                gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
            }

            RectF r = mAnimation.mapRect(face, mRect);
            canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
            canvas.drawRect(r.left, r.top, r.width(), r.height(), mFacePaint);

            if (pressed) {
                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
            }
        }

        @Override
        protected void renderBackground(GLCanvas canvas) {
            ArrayList<RectF> faces = mFaces;
            for (int i = 0, n = faces.size(); i < n; ++i) {
                renderFace(canvas, faces.get(i), i == mPressedFaceIndex);
            }

            GL11 gl = canvas.getGLInstance();
            if (mPressedFaceIndex != INDEX_NONE) {
                gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
                canvas.fillRect(0, 0, getWidth(), getHeight(), 0x66000000);
                gl.glDisable(GL11.GL_STENCIL_TEST);
            }
        }

        private void setPressedFace(int index) {
            if (mPressedFaceIndex == index) return;
            mPressedFaceIndex = index;
            invalidate();
        }

        private int getFaceIndexByPosition(float x, float y) {
            ArrayList<RectF> faces = mFaces;
            for (int i = 0, n = faces.size(); i < n; ++i) {
                RectF r = mAnimation.mapRect(faces.get(i), mRect);
                if (r.contains(x, y)) return i;
            }
            return INDEX_NONE;
        }

        @Override
        protected boolean onTouch(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE: {
                    setPressedFace(getFaceIndexByPosition(x, y));
                    break;
                }
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP: {
                    int index = mPressedFaceIndex;
                    setPressedFace(INDEX_NONE);
                    if (index != INDEX_NONE) {
                        mHighlightRectangle.setRectangle(mFaces.get(index));
                        mHighlightRectangle.setVisibility(GLView.VISIBLE);
                        setVisibility(GLView.INVISIBLE);
                    }
                }
            }
            return true;
        }
    }

    private class AnimationController extends Animation {
        private int mCurrentX;
        private int mCurrentY;
        private float mCurrentScale;
        private int mStartX;
        private int mStartY;
        private float mStartScale;
        private int mTargetX;
        private int mTargetY;
        private float mTargetScale;

        public AnimationController() {
            setDuration(ANIMATION_DURATION);
            setInterpolator(new DecelerateInterpolator(4));
        }

        public void initialize() {
            mCurrentX = mImageWidth / 2;
            mCurrentY = mImageHeight / 2;
            mCurrentScale = Math.min(2, Math.min(
                    (float) getWidth() / mImageWidth,
                    (float) getHeight() / mImageHeight));
        }

        public void startParkingAnimation(RectF highlight) {
            RectF r = mAnimation.mapRect(highlight, new RectF());
            int width = getWidth();
            int height = getHeight();

            float wr = r.width() / width;
            float hr = r.height() / height;
            final int d = ANIMATION_TRIGGER;
            if (wr >= MIN_SELECTION_RATIO && wr < MAX_SELECTION_RATIO
                    && hr >= MIN_SELECTION_RATIO && hr < MAX_SELECTION_RATIO
                    && r.left >= d && r.right < width - d
                    && r.top >= d && r.bottom < height - d) return;

            mStartX = mCurrentX;
            mStartY = mCurrentY;
            mStartScale = mCurrentScale;
            calculateTarget(highlight);
            start();
        }

        public void parkNow(RectF highlight) {
            calculateTarget(highlight);
            forceStop();
            mStartX = mCurrentX = mTargetX;
            mStartY = mCurrentY = mTargetY;
            mStartScale = mCurrentScale = mTargetScale;
        }

        public void inverseMapPoint(PointF point) {
            float s = mCurrentScale;
            point.x = Utils.clamp(((point.x - getWidth() * 0.5f) / s
                    + mCurrentX) / mImageWidth, 0, 1);
            point.y = Utils.clamp(((point.y - getHeight() * 0.5f) / s
                    + mCurrentY) / mImageHeight, 0, 1);
        }

        public RectF mapRect(RectF input, RectF output) {
            float offsetX = getWidth() * 0.5f;
            float offsetY = getHeight() * 0.5f;
            int x = mCurrentX;
            int y = mCurrentY;
            float s = mCurrentScale;
            output.set(
                    offsetX + (input.left * mImageWidth - x) * s,
                    offsetY + (input.top * mImageHeight - y) * s,
                    offsetX + (input.right * mImageWidth - x) * s,
                    offsetY + (input.bottom * mImageHeight - y) * s);
            return output;
        }

        @Override
        protected void onCalculate(float progress) {
            mCurrentX = Math.round(mStartX + (mTargetX - mStartX) * progress);
            mCurrentY = Math.round(mStartY + (mTargetY - mStartY) * progress);
            mCurrentScale = mStartScale + (mTargetScale - mStartScale) * progress;

            if (mCurrentX == mTargetX && mCurrentY == mTargetY
                    && mCurrentScale == mTargetScale) forceStop();
        }

        public int getCenterX() {
            return mCurrentX;
        }

        public int getCenterY() {
            return mCurrentY;
        }

        public float getScale() {
            return mCurrentScale;
        }

        private void calculateTarget(RectF highlight) {
            float width = getWidth();
            float height = getHeight();

            if (mImageWidth != SIZE_UNKNOWN) {
                float minScale = Math.min(width / mImageWidth, height / mImageHeight);
                float scale = Utils.clamp(SELECTION_RATIO * Math.min(
                        width / (highlight.width() * mImageWidth),
                        height / (highlight.height() * mImageHeight)), minScale, 2f);
                int centerX = Math.round(
                        mImageWidth * (highlight.left + highlight.right) * 0.5f);
                int centerY = Math.round(
                        mImageHeight * (highlight.top + highlight.bottom) * 0.5f);

                if (Math.round(mImageWidth * scale) > width) {
                    int limitX = Math.round(width * 0.5f / scale);
                    centerX = Math.round(
                            (highlight.left + highlight.right) * mImageWidth / 2);
                    centerX = Utils.clamp(centerX, limitX, mImageWidth - limitX);
                } else {
                    centerX = mImageWidth / 2;
                }
                if (Math.round(mImageHeight * scale) > height) {
                    int limitY = Math.round(height * 0.5f / scale);
                    centerY = Math.round(
                            (highlight.top + highlight.bottom) * mImageHeight / 2);
                    centerY = Utils.clamp(centerY, limitY, mImageHeight - limitY);
                } else {
                    centerY = mImageHeight / 2;
                }
                mTargetX = centerX;
                mTargetY = centerY;
                mTargetScale = scale;
            }
        }

    }

    private class HighlightRectangle extends GLView {
        private RectF mHighlightRect = new RectF(0.25f, 0.25f, 0.75f, 0.75f);
        private RectF mTempRect = new RectF();
        private PointF mTempPoint = new PointF();

        private ResourceTexture mArrow;

        private int mMovingEdges = 0;
        private float mReferenceX;
        private float mReferenceY;

        public HighlightRectangle() {
            mArrow = new ResourceTexture(mActivity.getAndroidContext(),
                    R.drawable.camera_crop_holo);
        }

        public void setInitRectangle() {
            float targetRatio = mAspectRatio == UNSPECIFIED
                    ? 1f
                    : mAspectRatio * mImageHeight / mImageWidth;
            float w = SELECTION_RATIO / 2f;
            float h = SELECTION_RATIO / 2f;
            if (targetRatio > 1) {
                h = w / targetRatio;
            } else {
                w = h * targetRatio;
            }
            mHighlightRect.set(0.5f - w, 0.5f - h, 0.5f + w, 0.5f + h);
        }

        public void setRectangle(RectF faceRect) {
            mHighlightRect.set(faceRect);
            mAnimation.startParkingAnimation(faceRect);
            invalidate();
        }

        private void moveEdges(MotionEvent event) {
            float scale = mAnimation.getScale();
            float dx = (event.getX() - mReferenceX) / scale / mImageWidth;
            float dy = (event.getY() - mReferenceY) / scale / mImageHeight;
            mReferenceX = event.getX();
            mReferenceY = event.getY();
            RectF r = mHighlightRect;

            if ((mMovingEdges & MOVE_BLOCK) != 0) {
                dx = Utils.clamp(dx, -r.left,  1 - r.right);
                dy = Utils.clamp(dy, -r.top , 1 - r.bottom);
                r.top += dy;
                r.bottom += dy;
                r.left += dx;
                r.right += dx;
            } else {
                PointF point = mTempPoint;
                point.set(mReferenceX, mReferenceY);
                mAnimation.inverseMapPoint(point);
                float left = r.left + MIN_SELECTION_LENGTH / mImageWidth;
                float right = r.right - MIN_SELECTION_LENGTH / mImageWidth;
                float top = r.top + MIN_SELECTION_LENGTH / mImageHeight;
                float bottom = r.bottom - MIN_SELECTION_LENGTH / mImageHeight;
                if ((mMovingEdges & MOVE_RIGHT) != 0) {
                    r.right = Utils.clamp(point.x, left, 1f);
                }
                if ((mMovingEdges & MOVE_LEFT) != 0) {
                    r.left = Utils.clamp(point.x, 0, right);
                }
                if ((mMovingEdges & MOVE_TOP) != 0) {
                    r.top = Utils.clamp(point.y, 0, bottom);
                }
                if ((mMovingEdges & MOVE_BOTTOM) != 0) {
                    r.bottom = Utils.clamp(point.y, top, 1f);
                }
                if (mAspectRatio != UNSPECIFIED) {
                    float targetRatio = mAspectRatio * mImageHeight / mImageWidth;
                    if (r.width() / r.height() > targetRatio) {
                        float height = r.width() / targetRatio;
                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
                            r.bottom = Utils.clamp(r.top + height, top, 1f);
                        } else {
                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
                        }
                    } else {
                        float width = r.height() * targetRatio;
                        if ((mMovingEdges & MOVE_LEFT) != 0) {
                            r.left = Utils.clamp(r.right - width, 0, right);
                        } else {
                            r.right = Utils.clamp(r.left + width, left, 1f);
                        }
                    }
                    if (r.width() / r.height() > targetRatio) {
                        float width = r.height() * targetRatio;
                        if ((mMovingEdges & MOVE_LEFT) != 0) {
                            r.left = Utils.clamp(r.right - width, 0, right);
                        } else {
                            r.right = Utils.clamp(r.left + width, left, 1f);
                        }
                    } else {
                        float height = r.width() / targetRatio;
                        if ((mMovingEdges & MOVE_BOTTOM) != 0) {
                            r.bottom = Utils.clamp(r.top + height, top, 1f);
                        } else {
                            r.top = Utils.clamp(r.bottom - height, 0, bottom);
                        }
                    }
                }
            }
            invalidate();
        }

        private void setMovingEdges(MotionEvent event) {
            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
            float x = event.getX();
            float y = event.getY();

            if (x > r.left + TOUCH_TOLERANCE && x < r.right - TOUCH_TOLERANCE
                    && y > r.top + TOUCH_TOLERANCE && y < r.bottom - TOUCH_TOLERANCE) {
                mMovingEdges = MOVE_BLOCK;
                return;
            }

            boolean inVerticalRange = (r.top - TOUCH_TOLERANCE) <= y
                    && y <= (r.bottom + TOUCH_TOLERANCE);
            boolean inHorizontalRange = (r.left - TOUCH_TOLERANCE) <= x
                    && x <= (r.right + TOUCH_TOLERANCE);

            if (inVerticalRange) {
                boolean left = Math.abs(x - r.left) <= TOUCH_TOLERANCE;
                boolean right = Math.abs(x - r.right) <= TOUCH_TOLERANCE;
                if (left && right) {
                    left = Math.abs(x - r.left) < Math.abs(x - r.right);
                    right = !left;
                }
                if (left) mMovingEdges |= MOVE_LEFT;
                if (right) mMovingEdges |= MOVE_RIGHT;
                if (mAspectRatio != UNSPECIFIED && inHorizontalRange) {
                    mMovingEdges |= (y >
                            (r.top + r.bottom) / 2) ? MOVE_BOTTOM : MOVE_TOP;
                }
            }
            if (inHorizontalRange) {
                boolean top = Math.abs(y - r.top) <= TOUCH_TOLERANCE;
                boolean bottom = Math.abs(y - r.bottom) <= TOUCH_TOLERANCE;
                if (top && bottom) {
                    top = Math.abs(y - r.top) < Math.abs(y - r.bottom);
                    bottom = !top;
                }
                if (top) mMovingEdges |= MOVE_TOP;
                if (bottom) mMovingEdges |= MOVE_BOTTOM;
                if (mAspectRatio != UNSPECIFIED && inVerticalRange) {
                    mMovingEdges |= (x >
                            (r.left + r.right) / 2) ? MOVE_RIGHT : MOVE_LEFT;
                }
            }
        }

        @Override
        protected boolean onTouch(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    mReferenceX = event.getX();
                    mReferenceY = event.getY();
                    setMovingEdges(event);
                    invalidate();
                    return true;
                }
                case MotionEvent.ACTION_MOVE:
                    moveEdges(event);
                    break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP: {
                    mMovingEdges = 0;
                    mAnimation.startParkingAnimation(mHighlightRect);
                    invalidate();
                    return true;
                }
            }
            return true;
        }

        @Override
        protected void renderBackground(GLCanvas canvas) {
            RectF r = mAnimation.mapRect(mHighlightRect, mTempRect);
            drawHighlightRectangle(canvas, r);

            float centerY = (r.top + r.bottom) / 2;
            float centerX = (r.left + r.right) / 2;
            boolean notMoving = mMovingEdges == 0;
            if ((mMovingEdges & MOVE_RIGHT) != 0 || notMoving) {
                mArrow.draw(canvas,
                        Math.round(r.right - mArrow.getWidth() / 2),
                        Math.round(centerY - mArrow.getHeight() / 2));
            }
            if ((mMovingEdges & MOVE_LEFT) != 0 || notMoving) {
                mArrow.draw(canvas,
                        Math.round(r.left - mArrow.getWidth() / 2),
                        Math.round(centerY - mArrow.getHeight() / 2));
            }
            if ((mMovingEdges & MOVE_TOP) != 0 || notMoving) {
                mArrow.draw(canvas,
                        Math.round(centerX - mArrow.getWidth() / 2),
                        Math.round(r.top - mArrow.getHeight() / 2));
            }
            if ((mMovingEdges & MOVE_BOTTOM) != 0 || notMoving) {
                mArrow.draw(canvas,
                        Math.round(centerX - mArrow.getWidth() / 2),
                        Math.round(r.bottom - mArrow.getHeight() / 2));
            }
        }

        private void drawHighlightRectangle(GLCanvas canvas, RectF r) {
            GL11 gl = canvas.getGLInstance();
            gl.glLineWidth(3.0f);
            gl.glEnable(GL11.GL_LINE_SMOOTH);

            gl.glEnable(GL11.GL_STENCIL_TEST);
            gl.glClear(GL11.GL_STENCIL_BUFFER_BIT);
            gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
            gl.glStencilFunc(GL11.GL_ALWAYS, 1, 1);

            if (mSpotlightRatioX == 0 || mSpotlightRatioY == 0) {
                canvas.fillRect(r.left, r.top, r.width(), r.height(), Color.TRANSPARENT);
                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);
            } else {
                float sx = r.width() * mSpotlightRatioX;
                float sy = r.height() * mSpotlightRatioY;
                float cx = r.centerX();
                float cy = r.centerY();

                canvas.fillRect(cx - sx / 2, cy - sy / 2, sx, sy, Color.TRANSPARENT);
                canvas.drawRect(cx - sx / 2, cy - sy / 2, sx, sy, mPaint);
                canvas.drawRect(r.left, r.top, r.width(), r.height(), mPaint);

                gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
                gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);

                canvas.drawRect(cx - sy / 2, cy - sx / 2, sy, sx, mPaint);
                canvas.fillRect(cx - sy / 2, cy - sx / 2, sy, sx, Color.TRANSPARENT);
                canvas.fillRect(r.left, r.top, r.width(), r.height(), 0x80000000);
            }

            gl.glStencilFunc(GL11.GL_NOTEQUAL, 1, 1);
            gl.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);

            canvas.fillRect(0, 0, getWidth(), getHeight(), 0xA0000000);

            gl.glDisable(GL11.GL_STENCIL_TEST);
        }
    }

    private class DetectFaceTask extends Thread {
        private final FaceDetector.Face[] mFaces = new FaceDetector.Face[MAX_FACE_COUNT];
        private final Bitmap mFaceBitmap;
        private int mFaceCount;

        public DetectFaceTask(Bitmap bitmap) {
            mFaceBitmap = bitmap;
            setName("face-detect");
        }

        @Override
        public void run() {
            Bitmap bitmap = mFaceBitmap;
            FaceDetector detector = new FaceDetector(
                    bitmap.getWidth(), bitmap.getHeight(), MAX_FACE_COUNT);
            mFaceCount = detector.findFaces(bitmap, mFaces);
            mMainHandler.sendMessage(
                    mMainHandler.obtainMessage(MSG_UPDATE_FACES, this));
        }

        private RectF getFaceRect(FaceDetector.Face face) {
            PointF point = new PointF();
            face.getMidPoint(point);

            int width = mFaceBitmap.getWidth();
            int height = mFaceBitmap.getHeight();
            float rx = face.eyesDistance() * FACE_EYE_RATIO;
            float ry = rx;
            float aspect = mAspectRatio;
            if (aspect != UNSPECIFIED) {
                if (aspect > 1) {
                    rx = ry * aspect;
                } else {
                    ry = rx / aspect;
                }
            }

            RectF r = new RectF(
                    point.x - rx, point.y - ry, point.x + rx, point.y + ry);
            r.intersect(0, 0, width, height);

            if (aspect != UNSPECIFIED) {
                if (r.width() / r.height() > aspect) {
                    float w = r.height() * aspect;
                    r.left = (r.left + r.right - w) * 0.5f;
                    r.right = r.left + w;
                } else {
                    float h = r.width() / aspect;
                    r.top =  (r.top + r.bottom - h) * 0.5f;
                    r.bottom = r.top + h;
                }
            }

            r.left /= width;
            r.right /= width;
            r.top /= height;
            r.bottom /= height;
            return r;
        }

        public void updateFaces() {
            if (mFaceCount > 1) {
                for (int i = 0, n = mFaceCount; i < n; ++i) {
                    mFaceDetectionView.addFace(getFaceRect(mFaces[i]));
                }
                mFaceDetectionView.setVisibility(GLView.VISIBLE);
                Toast.makeText(mActivity.getAndroidContext(),
                        R.string.multiface_crop_help, Toast.LENGTH_SHORT).show();
            } else if (mFaceCount == 1) {
                mFaceDetectionView.setVisibility(GLView.INVISIBLE);
                mHighlightRectangle.setRectangle(getFaceRect(mFaces[0]));
                mHighlightRectangle.setVisibility(GLView.VISIBLE);
            } else /*mFaceCount == 0*/ {
                mHighlightRectangle.setInitRectangle();
                mHighlightRectangle.setVisibility(GLView.VISIBLE);
            }
        }
    }

    public void setDataModel(TileImageView.Model dataModel, int rotation) {
        if (((rotation / 90) & 0x01) != 0) {
            mImageWidth = dataModel.getImageHeight();
            mImageHeight = dataModel.getImageWidth();
        } else {
            mImageWidth = dataModel.getImageWidth();
            mImageHeight = dataModel.getImageHeight();
        }

        mImageRotation = rotation;

        mImageView.setModel(dataModel);
        mAnimation.initialize();
    }

    public void detectFaces(Bitmap bitmap) {
        int rotation = mImageRotation;
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scale = FloatMath.sqrt((float) FACE_PIXEL_COUNT / (width * height));

        // faceBitmap is a correctly rotated bitmap, as viewed by a user.
        Bitmap faceBitmap;
        if (((rotation / 90) & 1) == 0) {
            int w = (Math.round(width * scale) & ~1); // must be even
            int h = Math.round(height * scale);
            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
            Canvas canvas = new Canvas(faceBitmap);
            canvas.rotate(rotation, w / 2, h / 2);
            canvas.scale((float) w / width, (float) h / height);
            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
        } else {
            int w = (Math.round(height * scale) & ~1); // must be even
            int h = Math.round(width * scale);
            faceBitmap = Bitmap.createBitmap(w, h, Config.RGB_565);
            Canvas canvas = new Canvas(faceBitmap);
            canvas.translate(w / 2, h / 2);
            canvas.rotate(rotation);
            canvas.translate(-h / 2, -w / 2);
            canvas.scale((float) w / height, (float) h / width);
            canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
        }
        new DetectFaceTask(faceBitmap).start();
    }

    public void initializeHighlightRectangle() {
        mHighlightRectangle.setInitRectangle();
        mHighlightRectangle.setVisibility(GLView.VISIBLE);
    }

    public void resume() {
        mImageView.prepareTextures();
    }

    public void pause() {
        mImageView.freeTextures();
    }
}

