/* 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 android.widget;

import java.lang.ref.WeakReference;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.TableMaskFilter;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.LinearInterpolator;
import android.widget.RemoteViews.RemoteView;

@RemoteView
/**
 * A view that displays its children in a stack and allows users to discretely swipe
 * through the children.
 */
public class StackView extends AdapterViewAnimator {
    private final String TAG = "StackView";

    /**
     * Default animation parameters
     */
    private static final int DEFAULT_ANIMATION_DURATION = 400;
    private static final int MINIMUM_ANIMATION_DURATION = 50;
    private static final int STACK_RELAYOUT_DURATION = 100;

    /**
     * Parameters effecting the perspective visuals
     */
    private static final float PERSPECTIVE_SHIFT_FACTOR_Y = 0.1f;
    private static final float PERSPECTIVE_SHIFT_FACTOR_X = 0.1f;

    private float mPerspectiveShiftX;
    private float mPerspectiveShiftY;
    private float mNewPerspectiveShiftX;
    private float mNewPerspectiveShiftY;

    @SuppressWarnings({"FieldCanBeLocal"})
    private static final float PERSPECTIVE_SCALE_FACTOR = 0f;

    /**
     * Represent the two possible stack modes, one where items slide up, and the other
     * where items slide down. The perspective is also inverted between these two modes.
     */
    private static final int ITEMS_SLIDE_UP = 0;
    private static final int ITEMS_SLIDE_DOWN = 1;

    /**
     * These specify the different gesture states
     */
    private static final int GESTURE_NONE = 0;
    private static final int GESTURE_SLIDE_UP = 1;
    private static final int GESTURE_SLIDE_DOWN = 2;

    /**
     * Specifies how far you need to swipe (up or down) before it
     * will be consider a completed gesture when you lift your finger
     */
    private static final float SWIPE_THRESHOLD_RATIO = 0.2f;

    /**
     * Specifies the total distance, relative to the size of the stack,
     * that views will be slid, either up or down
     */
    private static final float SLIDE_UP_RATIO = 0.7f;

    /**
     * Sentinel value for no current active pointer.
     * Used by {@link #mActivePointerId}.
     */
    private static final int INVALID_POINTER = -1;

    /**
     * Number of active views in the stack. One fewer view is actually visible, as one is hidden.
     */
    private static final int NUM_ACTIVE_VIEWS = 5;

    private static final int FRAME_PADDING = 4;

    private final Rect mTouchRect = new Rect();

    private static final int MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE = 5000;

    private static final long MIN_TIME_BETWEEN_SCROLLS = 100;

    /**
     * These variables are all related to the current state of touch interaction
     * with the stack
     */
    private float mInitialY;
    private float mInitialX;
    private int mActivePointerId;
    private int mYVelocity = 0;
    private int mSwipeGestureType = GESTURE_NONE;
    private int mSlideAmount;
    private int mSwipeThreshold;
    private int mTouchSlop;
    private int mMaximumVelocity;
    private VelocityTracker mVelocityTracker;
    private boolean mTransitionIsSetup = false;
    private int mResOutColor;
    private int mClickColor;

    private static HolographicHelper sHolographicHelper;
    private ImageView mHighlight;
    private ImageView mClickFeedback;
    private boolean mClickFeedbackIsValid = false;
    private StackSlider mStackSlider;
    private boolean mFirstLayoutHappened = false;
    private long mLastInteractionTime = 0;
    private long mLastScrollTime;
    private int mStackMode;
    private int mFramePadding;
    private final Rect stackInvalidateRect = new Rect();

    /**
     * {@inheritDoc}
     */
    public StackView(Context context) {
        this(context, null);
    }

    /**
     * {@inheritDoc}
     */
    public StackView(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.stackViewStyle);
    }

    /**
     * {@inheritDoc}
     */
    public StackView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.StackView, defStyleAttr, 0);

        mResOutColor = a.getColor(
                com.android.internal.R.styleable.StackView_resOutColor, 0);
        mClickColor = a.getColor(
                com.android.internal.R.styleable.StackView_clickColor, 0);

        a.recycle();
        initStackView();
    }

    private void initStackView() {
        configureViewAnimator(NUM_ACTIVE_VIEWS, 1);
        setStaticTransformationsEnabled(true);
        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
        mTouchSlop = configuration.getScaledTouchSlop();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
        mActivePointerId = INVALID_POINTER;

        mHighlight = new ImageView(getContext());
        mHighlight.setLayoutParams(new LayoutParams(mHighlight));
        addViewInLayout(mHighlight, -1, new LayoutParams(mHighlight));

        mClickFeedback = new ImageView(getContext());
        mClickFeedback.setLayoutParams(new LayoutParams(mClickFeedback));
        addViewInLayout(mClickFeedback, -1, new LayoutParams(mClickFeedback));
        mClickFeedback.setVisibility(INVISIBLE);

        mStackSlider = new StackSlider();

        if (sHolographicHelper == null) {
            sHolographicHelper = new HolographicHelper(mContext);
        }
        setClipChildren(false);
        setClipToPadding(false);

        // This sets the form of the StackView, which is currently to have the perspective-shifted
        // views above the active view, and have items slide down when sliding out. The opposite is
        // available by using ITEMS_SLIDE_UP.
        mStackMode = ITEMS_SLIDE_DOWN;

        // This is a flag to indicate the the stack is loading for the first time
        mWhichChild = -1;

        // Adjust the frame padding based on the density, since the highlight changes based
        // on the density
        final float density = mContext.getResources().getDisplayMetrics().density;
        mFramePadding = (int) Math.ceil(density * FRAME_PADDING);
    }

    /**
     * Animate the views between different relative indexes within the {@link AdapterViewAnimator}
     */
    void transformViewForTransition(int fromIndex, int toIndex, final View view, boolean animate) {
        if (!animate) {
            ((StackFrame) view).cancelSliderAnimator();
            view.setRotationX(0f);
            LayoutParams lp = (LayoutParams) view.getLayoutParams();
            lp.setVerticalOffset(0);
            lp.setHorizontalOffset(0);
        }

        if (fromIndex == -1 && toIndex == getNumActiveViews() -1) {
            transformViewAtIndex(toIndex, view, false);
            view.setVisibility(VISIBLE);
            view.setAlpha(1.0f);
        } else if (fromIndex == 0 && toIndex == 1) {
            // Slide item in
            ((StackFrame) view).cancelSliderAnimator();
            view.setVisibility(VISIBLE);

            int duration = Math.round(mStackSlider.getDurationForNeutralPosition(mYVelocity));
            StackSlider animationSlider = new StackSlider(mStackSlider);
            animationSlider.setView(view);

            if (animate) {
                PropertyValuesHolder slideInY = PropertyValuesHolder.ofFloat("YProgress", 0.0f);
                PropertyValuesHolder slideInX = PropertyValuesHolder.ofFloat("XProgress", 0.0f);
                ObjectAnimator slideIn = ObjectAnimator.ofPropertyValuesHolder(animationSlider,
                        slideInX, slideInY);
                slideIn.setDuration(duration);
                slideIn.setInterpolator(new LinearInterpolator());
                ((StackFrame) view).setSliderAnimator(slideIn);
                slideIn.start();
            } else {
                animationSlider.setYProgress(0f);
                animationSlider.setXProgress(0f);
            }
        } else if (fromIndex == 1 && toIndex == 0) {
            // Slide item out
            ((StackFrame) view).cancelSliderAnimator();
            int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity));

            StackSlider animationSlider = new StackSlider(mStackSlider);
            animationSlider.setView(view);
            if (animate) {
                PropertyValuesHolder slideOutY = PropertyValuesHolder.ofFloat("YProgress", 1.0f);
                PropertyValuesHolder slideOutX = PropertyValuesHolder.ofFloat("XProgress", 0.0f);
                ObjectAnimator slideOut = ObjectAnimator.ofPropertyValuesHolder(animationSlider,
                        slideOutX, slideOutY);
                slideOut.setDuration(duration);
                slideOut.setInterpolator(new LinearInterpolator());
                ((StackFrame) view).setSliderAnimator(slideOut);
                slideOut.start();
            } else {
                animationSlider.setYProgress(1.0f);
                animationSlider.setXProgress(0f);
            }
        } else if (toIndex == 0) {
            // Make sure this view that is "waiting in the wings" is invisible
            view.setAlpha(0.0f);
            view.setVisibility(INVISIBLE);
        } else if ((fromIndex == 0 || fromIndex == 1) && toIndex > 1) {
            view.setVisibility(VISIBLE);
            view.setAlpha(1.0f);
            view.setRotationX(0f);
            LayoutParams lp = (LayoutParams) view.getLayoutParams();
            lp.setVerticalOffset(0);
            lp.setHorizontalOffset(0);
        } else if (fromIndex == -1) {
            view.setAlpha(1.0f);
            view.setVisibility(VISIBLE);
        } else if (toIndex == -1) {
            if (animate) {
                postDelayed(new Runnable() {
                    public void run() {
                        view.setAlpha(0);
                    }
                }, STACK_RELAYOUT_DURATION);
            } else {
                view.setAlpha(0f);
            }
        }

        // Implement the faked perspective
        if (toIndex != -1) {
            transformViewAtIndex(toIndex, view, animate);
        }
    }

    private void transformViewAtIndex(int index, final View view, boolean animate) {
        final float maxPerspectiveShiftY = mPerspectiveShiftY;
        final float maxPerspectiveShiftX = mPerspectiveShiftX;

        if (mStackMode == ITEMS_SLIDE_DOWN) {
            index = mMaxNumActiveViews - index - 1;
            if (index == mMaxNumActiveViews - 1) index--;
        } else {
            index--;
            if (index < 0) index++;
        }

        float r = (index * 1.0f) / (mMaxNumActiveViews - 2);

        final float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r);

        float perspectiveTranslationY = r * maxPerspectiveShiftY;
        float scaleShiftCorrectionY = (scale - 1) *
                (getMeasuredHeight() * (1 - PERSPECTIVE_SHIFT_FACTOR_Y) / 2.0f);
        final float transY = perspectiveTranslationY + scaleShiftCorrectionY;

        float perspectiveTranslationX = (1 - r) * maxPerspectiveShiftX;
        float scaleShiftCorrectionX =  (1 - scale) *
                (getMeasuredWidth() * (1 - PERSPECTIVE_SHIFT_FACTOR_X) / 2.0f);
        final float transX = perspectiveTranslationX + scaleShiftCorrectionX;

        // If this view is currently being animated for a certain position, we need to cancel
        // this animation so as not to interfere with the new transformation.
        if (view instanceof StackFrame) {
            ((StackFrame) view).cancelTransformAnimator();
        }

        if (animate) {
            PropertyValuesHolder translationX = PropertyValuesHolder.ofFloat("translationX", transX);
            PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", transY);
            PropertyValuesHolder scalePropX = PropertyValuesHolder.ofFloat("scaleX", scale);
            PropertyValuesHolder scalePropY = PropertyValuesHolder.ofFloat("scaleY", scale);

            ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(view, scalePropX, scalePropY,
                    translationY, translationX);
            oa.setDuration(STACK_RELAYOUT_DURATION);
            if (view instanceof StackFrame) {
                ((StackFrame) view).setTransformAnimator(oa);
            }
            oa.start();
        } else {
            view.setTranslationX(transX);
            view.setTranslationY(transY);
            view.setScaleX(scale);
            view.setScaleY(scale);
        }
    }

    private void setupStackSlider(View v, int mode) {
        mStackSlider.setMode(mode);
        if (v != null) {
            mHighlight.setImageBitmap(sHolographicHelper.createResOutline(v, mResOutColor));
            mHighlight.setRotation(v.getRotation());
            mHighlight.setTranslationY(v.getTranslationY());
            mHighlight.setTranslationX(v.getTranslationX());
            mHighlight.bringToFront();
            v.bringToFront();
            mStackSlider.setView(v);

            v.setVisibility(VISIBLE);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @android.view.RemotableViewMethod
    public void showNext() {
        if (mSwipeGestureType != GESTURE_NONE) return;
        if (!mTransitionIsSetup) {
            View v = getViewAtRelativeIndex(1);
            if (v != null) {
                setupStackSlider(v, StackSlider.NORMAL_MODE);
                mStackSlider.setYProgress(0);
                mStackSlider.setXProgress(0);
            }
        }
        super.showNext();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @android.view.RemotableViewMethod
    public void showPrevious() {
        if (mSwipeGestureType != GESTURE_NONE) return;
        if (!mTransitionIsSetup) {
            View v = getViewAtRelativeIndex(0);
            if (v != null) {
                setupStackSlider(v, StackSlider.NORMAL_MODE);
                mStackSlider.setYProgress(1);
                mStackSlider.setXProgress(0);
            }
        }
        super.showPrevious();
    }

    @Override
    void showOnly(int childIndex, boolean animate) {
        super.showOnly(childIndex, animate);

        // Here we need to make sure that the z-order of the children is correct
        for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
            int index = modulo(i, getWindowSize());
            ViewAndMetaData vm = mViewsMap.get(index);
            if (vm != null) {
                View v = mViewsMap.get(index).view;
                if (v != null) v.bringToFront();
            }
        }
        if (mHighlight != null) {
            mHighlight.bringToFront();
        }
        mTransitionIsSetup = false;
        mClickFeedbackIsValid = false;
    }

    void updateClickFeedback() {
        if (!mClickFeedbackIsValid) {
            View v = getViewAtRelativeIndex(1);
            if (v != null) {
                mClickFeedback.setImageBitmap(
                        sHolographicHelper.createClickOutline(v, mClickColor));
                mClickFeedback.setTranslationX(v.getTranslationX());
                mClickFeedback.setTranslationY(v.getTranslationY());
            }
            mClickFeedbackIsValid = true;
        }
    }

    @Override
    void showTapFeedback(View v) {
        updateClickFeedback();
        mClickFeedback.setVisibility(VISIBLE);
        mClickFeedback.bringToFront();
        invalidate();
    }

    @Override
    void hideTapFeedback(View v) {
        mClickFeedback.setVisibility(INVISIBLE);
        invalidate();
    }

    private void updateChildTransforms() {
        for (int i = 0; i < getNumActiveViews(); i++) {
            View v = getViewAtRelativeIndex(i);
            if (v != null) {
                transformViewAtIndex(i, v, false);
            }
        }
    }

    private static class StackFrame extends FrameLayout {
        WeakReference<ObjectAnimator> transformAnimator;
        WeakReference<ObjectAnimator> sliderAnimator;

        public StackFrame(Context context) {
            super(context);
        }

        void setTransformAnimator(ObjectAnimator oa) {
            transformAnimator = new WeakReference<ObjectAnimator>(oa);
        }

        void setSliderAnimator(ObjectAnimator oa) {
            sliderAnimator = new WeakReference<ObjectAnimator>(oa);
        }

        boolean cancelTransformAnimator() {
            if (transformAnimator != null) {
                ObjectAnimator oa = transformAnimator.get();
                if (oa != null) {
                    oa.cancel();
                    return true;
                }
            }
            return false;
        }

        boolean cancelSliderAnimator() {
            if (sliderAnimator != null) {
                ObjectAnimator oa = sliderAnimator.get();
                if (oa != null) {
                    oa.cancel();
                    return true;
                }
            }
            return false;
        }
    }

    @Override
    FrameLayout getFrameForChild() {
        StackFrame fl = new StackFrame(mContext);
        fl.setPadding(mFramePadding, mFramePadding, mFramePadding, mFramePadding);
        return fl;
    }

    /**
     * Apply any necessary tranforms for the child that is being added.
     */
    void applyTransformForChildAtIndex(View child, int relativeIndex) {
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        boolean expandClipRegion = false;

        canvas.getClipBounds(stackInvalidateRect);
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child =  getChildAt(i);
            LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if ((lp.horizontalOffset == 0 && lp.verticalOffset == 0) ||
                    child.getAlpha() == 0f || child.getVisibility() != VISIBLE) {
                lp.resetInvalidateRect();
            }
            Rect childInvalidateRect = lp.getInvalidateRect();
            if (!childInvalidateRect.isEmpty()) {
                expandClipRegion = true;
                stackInvalidateRect.union(childInvalidateRect);
            }
        }

        // We only expand the clip bounds if necessary.
        if (expandClipRegion) {
            canvas.save(Canvas.CLIP_SAVE_FLAG);
            canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
            super.dispatchDraw(canvas);
            canvas.restore();
        } else {
            super.dispatchDraw(canvas);
        }
    }

    private void onLayout() {
        if (!mFirstLayoutHappened) {
            mFirstLayoutHappened = true;
            updateChildTransforms();
        }

        final int newSlideAmount = Math.round(SLIDE_UP_RATIO * getMeasuredHeight());
        if (mSlideAmount != newSlideAmount) {
            mSlideAmount = newSlideAmount;
            mSwipeThreshold = Math.round(SWIPE_THRESHOLD_RATIO * newSlideAmount);
        }

        if (Float.compare(mPerspectiveShiftY, mNewPerspectiveShiftY) != 0 ||
                Float.compare(mPerspectiveShiftX, mNewPerspectiveShiftX) != 0) {

            mPerspectiveShiftY = mNewPerspectiveShiftY;
            mPerspectiveShiftX = mNewPerspectiveShiftX;
            updateChildTransforms();
        }
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_SCROLL: {
                    final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
                    if (vscroll < 0) {
                        pacedScroll(false);
                        return true;
                    } else if (vscroll > 0) {
                        pacedScroll(true);
                        return true;
                    }
                }
            }
        }
        return super.onGenericMotionEvent(event);
    }

    // This ensures that the frequency of stack flips caused by scrolls is capped
    private void pacedScroll(boolean up) {
        long timeSinceLastScroll = System.currentTimeMillis() - mLastScrollTime;
        if (timeSinceLastScroll > MIN_TIME_BETWEEN_SCROLLS) {
            if (up) {
                showPrevious();
            } else {
                showNext();
            }
            mLastScrollTime = System.currentTimeMillis();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch(action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                if (mActivePointerId == INVALID_POINTER) {
                    mInitialX = ev.getX();
                    mInitialY = ev.getY();
                    mActivePointerId = ev.getPointerId(0);
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                int pointerIndex = ev.findPointerIndex(mActivePointerId);
                if (pointerIndex == INVALID_POINTER) {
                    // no data for our primary pointer, this shouldn't happen, log it
                    Log.d(TAG, "Error: No data for our primary pointer.");
                    return false;
                }
                float newY = ev.getY(pointerIndex);
                float deltaY = newY - mInitialY;

                beginGestureIfNeeded(deltaY);
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {
                onSecondaryPointerUp(ev);
                break;
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                mActivePointerId = INVALID_POINTER;
                mSwipeGestureType = GESTURE_NONE;
            }
        }

        return mSwipeGestureType != GESTURE_NONE;
    }

    private void beginGestureIfNeeded(float deltaY) {
        if ((int) Math.abs(deltaY) > mTouchSlop && mSwipeGestureType == GESTURE_NONE) {
            final int swipeGestureType = deltaY < 0 ? GESTURE_SLIDE_UP : GESTURE_SLIDE_DOWN;
            cancelLongPress();
            requestDisallowInterceptTouchEvent(true);

            if (mAdapter == null) return;
            final int adapterCount = getCount();

            int activeIndex;
            if (mStackMode == ITEMS_SLIDE_UP) {
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1;
            } else {
                activeIndex = (swipeGestureType == GESTURE_SLIDE_DOWN) ? 1 : 0;
            }

            boolean endOfStack = mLoopViews && adapterCount == 1 && 
                ((mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_UP) ||
                 (mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_DOWN));
            boolean beginningOfStack = mLoopViews && adapterCount == 1 && 
                ((mStackMode == ITEMS_SLIDE_DOWN && swipeGestureType == GESTURE_SLIDE_UP) ||
                 (mStackMode == ITEMS_SLIDE_UP && swipeGestureType == GESTURE_SLIDE_DOWN));

            int stackMode;
            if (mLoopViews && !beginningOfStack && !endOfStack) {
                stackMode = StackSlider.NORMAL_MODE;
            } else if (mCurrentWindowStartUnbounded + activeIndex == -1 || beginningOfStack) {
                activeIndex++;
                stackMode = StackSlider.BEGINNING_OF_STACK_MODE;
            } else if (mCurrentWindowStartUnbounded + activeIndex == adapterCount - 1 || endOfStack) {
                stackMode = StackSlider.END_OF_STACK_MODE;
            } else {
                stackMode = StackSlider.NORMAL_MODE;
            }

            mTransitionIsSetup = stackMode == StackSlider.NORMAL_MODE;

            View v = getViewAtRelativeIndex(activeIndex);
            if (v == null) return;

            setupStackSlider(v, stackMode);

            // We only register this gesture if we've made it this far without a problem
            mSwipeGestureType = swipeGestureType;
            cancelHandleClick();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        super.onTouchEvent(ev);

        int action = ev.getAction();
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex == INVALID_POINTER) {
            // no data for our primary pointer, this shouldn't happen, log it
            Log.d(TAG, "Error: No data for our primary pointer.");
            return false;
        }

        float newY = ev.getY(pointerIndex);
        float newX = ev.getX(pointerIndex);
        float deltaY = newY - mInitialY;
        float deltaX = newX - mInitialX;
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_MOVE: {
                beginGestureIfNeeded(deltaY);

                float rx = deltaX / (mSlideAmount * 1.0f);
                if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
                    float r = (deltaY - mTouchSlop * 1.0f) / mSlideAmount * 1.0f;
                    if (mStackMode == ITEMS_SLIDE_DOWN) r = 1 - r;
                    mStackSlider.setYProgress(1 - r);
                    mStackSlider.setXProgress(rx);
                    return true;
                } else if (mSwipeGestureType == GESTURE_SLIDE_UP) {
                    float r = -(deltaY + mTouchSlop * 1.0f) / mSlideAmount * 1.0f;
                    if (mStackMode == ITEMS_SLIDE_DOWN) r = 1 - r;
                    mStackSlider.setYProgress(r);
                    mStackSlider.setXProgress(rx);
                    return true;
                }
                break;
            }
            case MotionEvent.ACTION_UP: {
                handlePointerUp(ev);
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {
                onSecondaryPointerUp(ev);
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                mActivePointerId = INVALID_POINTER;
                mSwipeGestureType = GESTURE_NONE;
                break;
            }
        }
        return true;
    }

    private void onSecondaryPointerUp(MotionEvent ev) {
        final int activePointerIndex = ev.getActionIndex();
        final int pointerId = ev.getPointerId(activePointerIndex);
        if (pointerId == mActivePointerId) {

            int activeViewIndex = (mSwipeGestureType == GESTURE_SLIDE_DOWN) ? 0 : 1;

            View v = getViewAtRelativeIndex(activeViewIndex);
            if (v == null) return;

            // Our primary pointer has gone up -- let's see if we can find
            // another pointer on the view. If so, then we should replace
            // our primary pointer with this new pointer and adjust things
            // so that the view doesn't jump
            for (int index = 0; index < ev.getPointerCount(); index++) {
                if (index != activePointerIndex) {

                    float x = ev.getX(index);
                    float y = ev.getY(index);

                    mTouchRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
                    if (mTouchRect.contains(Math.round(x), Math.round(y))) {
                        float oldX = ev.getX(activePointerIndex);
                        float oldY = ev.getY(activePointerIndex);

                        // adjust our frame of reference to avoid a jump
                        mInitialY += (y - oldY);
                        mInitialX += (x - oldX);

                        mActivePointerId = ev.getPointerId(index);
                        if (mVelocityTracker != null) {
                            mVelocityTracker.clear();
                        }
                        // ok, we're good, we found a new pointer which is touching the active view
                        return;
                    }
                }
            }
            // if we made it this far, it means we didn't find a satisfactory new pointer :(,
            // so end the gesture
            handlePointerUp(ev);
        }
    }

    private void handlePointerUp(MotionEvent ev) {
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        float newY = ev.getY(pointerIndex);
        int deltaY = (int) (newY - mInitialY);
        mLastInteractionTime = System.currentTimeMillis();

        if (mVelocityTracker != null) {
            mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            mYVelocity = (int) mVelocityTracker.getYVelocity(mActivePointerId);
        }

        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }

        if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
            // We reset the gesture variable, because otherwise we will ignore showPrevious() /
            // showNext();
            mSwipeGestureType = GESTURE_NONE;

            // Swipe threshold exceeded, swipe down
            if (mStackMode == ITEMS_SLIDE_UP) {
                showPrevious();
            } else {
                showNext();
            }
            mHighlight.bringToFront();
        } else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
                && mStackSlider.mMode == StackSlider.NORMAL_MODE) {
            // We reset the gesture variable, because otherwise we will ignore showPrevious() /
            // showNext();
            mSwipeGestureType = GESTURE_NONE;

            // Swipe threshold exceeded, swipe up
            if (mStackMode == ITEMS_SLIDE_UP) {
                showNext();
            } else {
                showPrevious();
            }

            mHighlight.bringToFront();
        } else if (mSwipeGestureType == GESTURE_SLIDE_UP ) {
            // Didn't swipe up far enough, snap back down
            int duration;
            float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 1 : 0;
            if (mStackMode == ITEMS_SLIDE_UP || mStackSlider.mMode != StackSlider.NORMAL_MODE) {
                duration = Math.round(mStackSlider.getDurationForNeutralPosition());
            } else {
                duration = Math.round(mStackSlider.getDurationForOffscreenPosition());
            }

            StackSlider animationSlider = new StackSlider(mStackSlider);
            PropertyValuesHolder snapBackY = PropertyValuesHolder.ofFloat("YProgress", finalYProgress);
            PropertyValuesHolder snapBackX = PropertyValuesHolder.ofFloat("XProgress", 0.0f);
            ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider,
                    snapBackX, snapBackY);
            pa.setDuration(duration);
            pa.setInterpolator(new LinearInterpolator());
            pa.start();
        } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN) {
            // Didn't swipe down far enough, snap back up
            float finalYProgress = (mStackMode == ITEMS_SLIDE_DOWN) ? 0 : 1;
            int duration;
            if (mStackMode == ITEMS_SLIDE_DOWN || mStackSlider.mMode != StackSlider.NORMAL_MODE) {
                duration = Math.round(mStackSlider.getDurationForNeutralPosition());
            } else {
                duration = Math.round(mStackSlider.getDurationForOffscreenPosition());
            }

            StackSlider animationSlider = new StackSlider(mStackSlider);
            PropertyValuesHolder snapBackY =
                    PropertyValuesHolder.ofFloat("YProgress",finalYProgress);
            PropertyValuesHolder snapBackX = PropertyValuesHolder.ofFloat("XProgress", 0.0f);
            ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider,
                    snapBackX, snapBackY);
            pa.setDuration(duration);
            pa.start();
        }

        mActivePointerId = INVALID_POINTER;
        mSwipeGestureType = GESTURE_NONE;
    }

    private class StackSlider {
        View mView;
        float mYProgress;
        float mXProgress;

        static final int NORMAL_MODE = 0;
        static final int BEGINNING_OF_STACK_MODE = 1;
        static final int END_OF_STACK_MODE = 2;

        int mMode = NORMAL_MODE;

        public StackSlider() {
        }

        public StackSlider(StackSlider copy) {
            mView = copy.mView;
            mYProgress = copy.mYProgress;
            mXProgress = copy.mXProgress;
            mMode = copy.mMode;
        }

        private float cubic(float r) {
            return (float) (Math.pow(2 * r - 1, 3) + 1) / 2.0f;
        }

        private float highlightAlphaInterpolator(float r) {
            float pivot = 0.4f;
            if (r < pivot) {
                return 0.85f * cubic(r / pivot);
            } else {
                return 0.85f * cubic(1 - (r - pivot) / (1 - pivot));
            }
        }

        private float viewAlphaInterpolator(float r) {
            float pivot = 0.3f;
            if (r > pivot) {
                return (r - pivot) / (1 - pivot);
            } else {
                return 0;
            }
        }

        private float rotationInterpolator(float r) {
            float pivot = 0.2f;
            if (r < pivot) {
                return 0;
            } else {
                return (r - pivot) / (1 - pivot);
            }
        }

        void setView(View v) {
            mView = v;
        }

        public void setYProgress(float r) {
            // enforce r between 0 and 1
            r = Math.min(1.0f, r);
            r = Math.max(0, r);

            mYProgress = r;
            if (mView == null) return;

            final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
            final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();

            int stackDirection = (mStackMode == ITEMS_SLIDE_UP) ? 1 : -1;

            // We need to prevent any clipping issues which may arise by setting a layer type.
            // This doesn't come for free however, so we only want to enable it when required.
            if (Float.compare(0f, mYProgress) != 0 && Float.compare(1.0f, mYProgress) != 0) {
                if (mView.getLayerType() == LAYER_TYPE_NONE) {
                    mView.setLayerType(LAYER_TYPE_HARDWARE, null);
                }
            } else {
                if (mView.getLayerType() != LAYER_TYPE_NONE) {
                    mView.setLayerType(LAYER_TYPE_NONE, null);
                }
            }

            switch (mMode) {
                case NORMAL_MODE:
                    viewLp.setVerticalOffset(Math.round(-r * stackDirection * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(-r * stackDirection * mSlideAmount));
                    mHighlight.setAlpha(highlightAlphaInterpolator(r));

                    float alpha = viewAlphaInterpolator(1 - r);

                    // We make sure that views which can't be seen (have 0 alpha) are also invisible
                    // so that they don't interfere with click events.
                    if (mView.getAlpha() == 0 && alpha != 0 && mView.getVisibility() != VISIBLE) {
                        mView.setVisibility(VISIBLE);
                    } else if (alpha == 0 && mView.getAlpha() != 0
                            && mView.getVisibility() == VISIBLE) {
                        mView.setVisibility(INVISIBLE);
                    }

                    mView.setAlpha(alpha);
                    mView.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    mHighlight.setRotationX(stackDirection * 90.0f * rotationInterpolator(r));
                    break;
                case END_OF_STACK_MODE:
                    r = r * 0.2f;
                    viewLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(-stackDirection * r * mSlideAmount));
                    mHighlight.setAlpha(highlightAlphaInterpolator(r));
                    break;
                case BEGINNING_OF_STACK_MODE:
                    r = (1-r) * 0.2f;
                    viewLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
                    highlightLp.setVerticalOffset(Math.round(stackDirection * r * mSlideAmount));
                    mHighlight.setAlpha(highlightAlphaInterpolator(r));
                    break;
            }
        }

        public void setXProgress(float r) {
            // enforce r between 0 and 1
            r = Math.min(2.0f, r);
            r = Math.max(-2.0f, r);

            mXProgress = r;

            if (mView == null) return;
            final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();
            final LayoutParams highlightLp = (LayoutParams) mHighlight.getLayoutParams();

            r *= 0.2f;
            viewLp.setHorizontalOffset(Math.round(r * mSlideAmount));
            highlightLp.setHorizontalOffset(Math.round(r * mSlideAmount));
        }

        void setMode(int mode) {
            mMode = mode;
        }

        float getDurationForNeutralPosition() {
            return getDuration(false, 0);
        }

        float getDurationForOffscreenPosition() {
            return getDuration(true, 0);
        }

        float getDurationForNeutralPosition(float velocity) {
            return getDuration(false, velocity);
        }

        float getDurationForOffscreenPosition(float velocity) {
            return getDuration(true, velocity);
        }

        private float getDuration(boolean invert, float velocity) {
            if (mView != null) {
                final LayoutParams viewLp = (LayoutParams) mView.getLayoutParams();

                float d = (float) Math.sqrt(Math.pow(viewLp.horizontalOffset, 2) +
                        Math.pow(viewLp.verticalOffset, 2));
                float maxd = (float) Math.sqrt(Math.pow(mSlideAmount, 2) +
                        Math.pow(0.4f * mSlideAmount, 2));

                if (velocity == 0) {
                    return (invert ? (1 - d / maxd) : d / maxd) * DEFAULT_ANIMATION_DURATION;
                } else {
                    float duration = invert ? d / Math.abs(velocity) :
                            (maxd - d) / Math.abs(velocity);
                    if (duration < MINIMUM_ANIMATION_DURATION ||
                            duration > DEFAULT_ANIMATION_DURATION) {
                        return getDuration(invert, 0);
                    } else {
                        return duration;
                    }
                }
            }
            return 0;
        }

        // Used for animations
        @SuppressWarnings({"UnusedDeclaration"})
        public float getYProgress() {
            return mYProgress;
        }

        // Used for animations
        @SuppressWarnings({"UnusedDeclaration"})
        public float getXProgress() {
            return mXProgress;
        }
    }

    LayoutParams createOrReuseLayoutParams(View v) {
        final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
        if (currentLp instanceof LayoutParams) {
            LayoutParams lp = (LayoutParams) currentLp;
            lp.setHorizontalOffset(0);
            lp.setVerticalOffset(0);
            lp.width = 0;
            lp.width = 0;
            return lp;
        }
        return new LayoutParams(v);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        checkForAndHandleDataChanged();

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);

            int childRight = mPaddingLeft + child.getMeasuredWidth();
            int childBottom = mPaddingTop + child.getMeasuredHeight();
            LayoutParams lp = (LayoutParams) child.getLayoutParams();

            child.layout(mPaddingLeft + lp.horizontalOffset, mPaddingTop + lp.verticalOffset,
                    childRight + lp.horizontalOffset, childBottom + lp.verticalOffset);

        }
        onLayout();
    }

    @Override
    public void advance() {
        long timeSinceLastInteraction = System.currentTimeMillis() - mLastInteractionTime;

        if (mAdapter == null) return;
        final int adapterCount = getCount();
        if (adapterCount == 1 && mLoopViews) return;

        if (mSwipeGestureType == GESTURE_NONE &&
                timeSinceLastInteraction > MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE) {
            showNext();
        }
    }

    private void measureChildren() {
        final int count = getChildCount();

        final int measuredWidth = getMeasuredWidth();
        final int measuredHeight = getMeasuredHeight();

        final int childWidth = Math.round(measuredWidth*(1-PERSPECTIVE_SHIFT_FACTOR_X))
                - mPaddingLeft - mPaddingRight;
        final int childHeight = Math.round(measuredHeight*(1-PERSPECTIVE_SHIFT_FACTOR_Y))
                - mPaddingTop - mPaddingBottom;

        int maxWidth = 0;
        int maxHeight = 0;

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST));

            if (child != mHighlight && child != mClickFeedback) {
                final int childMeasuredWidth = child.getMeasuredWidth();
                final int childMeasuredHeight = child.getMeasuredHeight();
                if (childMeasuredWidth > maxWidth) {
                    maxWidth = childMeasuredWidth;
                }
                if (childMeasuredHeight > maxHeight) {
                    maxHeight = childMeasuredHeight;
                }
            }
        }

        mNewPerspectiveShiftX = PERSPECTIVE_SHIFT_FACTOR_X * measuredWidth;
        mNewPerspectiveShiftY = PERSPECTIVE_SHIFT_FACTOR_Y * measuredHeight;

        // If we have extra space, we try and spread the items out
        if (maxWidth > 0 && count > 0 && maxWidth < childWidth) {
            mNewPerspectiveShiftX = measuredWidth - maxWidth;
        }

        if (maxHeight > 0 && count > 0 && maxHeight < childHeight) {
            mNewPerspectiveShiftY = measuredHeight - maxHeight;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

        boolean haveChildRefSize = (mReferenceChildWidth != -1 && mReferenceChildHeight != -1);

        // We need to deal with the case where our parent hasn't told us how
        // big we should be. In this case we should
        float factorY = 1/(1 - PERSPECTIVE_SHIFT_FACTOR_Y);
        if (heightSpecMode == MeasureSpec.UNSPECIFIED) {
            heightSpecSize = haveChildRefSize ?
                    Math.round(mReferenceChildHeight * (1 + factorY)) +
                    mPaddingTop + mPaddingBottom : 0;
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            if (haveChildRefSize) {
                int height = Math.round(mReferenceChildHeight * (1 + factorY))
                        + mPaddingTop + mPaddingBottom;
                if (height <= heightSpecSize) {
                    heightSpecSize = height;
                } else {
                    heightSpecSize |= MEASURED_STATE_TOO_SMALL;

                }
            } else {
                heightSpecSize = 0;
            }
        }

        float factorX = 1/(1 - PERSPECTIVE_SHIFT_FACTOR_X);
        if (widthSpecMode == MeasureSpec.UNSPECIFIED) {
            widthSpecSize = haveChildRefSize ?
                    Math.round(mReferenceChildWidth * (1 + factorX)) +
                    mPaddingLeft + mPaddingRight : 0;
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            if (haveChildRefSize) {
                int width = mReferenceChildWidth + mPaddingLeft + mPaddingRight;
                if (width <= widthSpecSize) {
                    widthSpecSize = width;
                } else {
                    widthSpecSize |= MEASURED_STATE_TOO_SMALL;
                }
            } else {
                widthSpecSize = 0;
            }
        }
        setMeasuredDimension(widthSpecSize, heightSpecSize);
        measureChildren();
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(event);
        event.setClassName(StackView.class.getName());
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(info);
        info.setClassName(StackView.class.getName());
        info.setScrollable(getChildCount() > 1);
        if (isEnabled()) {
            if (getDisplayedChild() < getChildCount() - 1) {
                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
            if (getDisplayedChild() > 0) {
                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
            }
        }
    }

    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (super.performAccessibilityAction(action, arguments)) {
            return true;
        }
        if (!isEnabled()) {
            return false;
        }
        switch (action) {
            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
                if (getDisplayedChild() < getChildCount() - 1) {
                    showNext();
                    return true;
                }
            } return false;
            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
                if (getDisplayedChild() > 0) {
                    showPrevious();
                    return true;
                }
            } return false;
        }
        return false;
    }

    class LayoutParams extends ViewGroup.LayoutParams {
        int horizontalOffset;
        int verticalOffset;
        View mView;
        private final Rect parentRect = new Rect();
        private final Rect invalidateRect = new Rect();
        private final RectF invalidateRectf = new RectF();
        private final Rect globalInvalidateRect = new Rect();

        LayoutParams(View view) {
            super(0, 0);
            width = 0;
            height = 0;
            horizontalOffset = 0;
            verticalOffset = 0;
            mView = view;
        }

        LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            horizontalOffset = 0;
            verticalOffset = 0;
            width = 0;
            height = 0;
        }

        void invalidateGlobalRegion(View v, Rect r) {
            // We need to make a new rect here, so as not to modify the one passed
            globalInvalidateRect.set(r);
            globalInvalidateRect.union(0, 0, getWidth(), getHeight());
            View p = v;
            if (!(v.getParent() != null && v.getParent() instanceof View)) return;

            boolean firstPass = true;
            parentRect.set(0, 0, 0, 0);
            while (p.getParent() != null && p.getParent() instanceof View
                    && !parentRect.contains(globalInvalidateRect)) {
                if (!firstPass) {
                    globalInvalidateRect.offset(p.getLeft() - p.getScrollX(), p.getTop()
                            - p.getScrollY());
                }
                firstPass = false;
                p = (View) p.getParent();
                parentRect.set(p.getScrollX(), p.getScrollY(),
                        p.getWidth() + p.getScrollX(), p.getHeight() + p.getScrollY());
                p.invalidate(globalInvalidateRect.left, globalInvalidateRect.top,
                        globalInvalidateRect.right, globalInvalidateRect.bottom);
            }

            p.invalidate(globalInvalidateRect.left, globalInvalidateRect.top,
                    globalInvalidateRect.right, globalInvalidateRect.bottom);
        }

        Rect getInvalidateRect() {
            return invalidateRect;
        }

        void resetInvalidateRect() {
            invalidateRect.set(0, 0, 0, 0);
        }

        // This is public so that ObjectAnimator can access it
        public void setVerticalOffset(int newVerticalOffset) {
            setOffsets(horizontalOffset, newVerticalOffset);
        }

        public void setHorizontalOffset(int newHorizontalOffset) {
            setOffsets(newHorizontalOffset, verticalOffset);
        }

        public void setOffsets(int newHorizontalOffset, int newVerticalOffset) {
            int horizontalOffsetDelta = newHorizontalOffset - horizontalOffset;
            horizontalOffset = newHorizontalOffset;
            int verticalOffsetDelta = newVerticalOffset - verticalOffset;
            verticalOffset = newVerticalOffset;

            if (mView != null) {
                mView.requestLayout();
                int left = Math.min(mView.getLeft() + horizontalOffsetDelta, mView.getLeft());
                int right = Math.max(mView.getRight() + horizontalOffsetDelta, mView.getRight());
                int top = Math.min(mView.getTop() + verticalOffsetDelta, mView.getTop());
                int bottom = Math.max(mView.getBottom() + verticalOffsetDelta, mView.getBottom());

                invalidateRectf.set(left, top, right, bottom);

                float xoffset = -invalidateRectf.left;
                float yoffset = -invalidateRectf.top;
                invalidateRectf.offset(xoffset, yoffset);
                mView.getMatrix().mapRect(invalidateRectf);
                invalidateRectf.offset(-xoffset, -yoffset);

                invalidateRect.set((int) Math.floor(invalidateRectf.left),
                        (int) Math.floor(invalidateRectf.top),
                        (int) Math.ceil(invalidateRectf.right),
                        (int) Math.ceil(invalidateRectf.bottom));

                invalidateGlobalRegion(mView, invalidateRect);
            }
        }
    }

    private static class HolographicHelper {
        private final Paint mHolographicPaint = new Paint();
        private final Paint mErasePaint = new Paint();
        private final Paint mBlurPaint = new Paint();
        private static final int RES_OUT = 0;
        private static final int CLICK_FEEDBACK = 1;
        private float mDensity;
        private BlurMaskFilter mSmallBlurMaskFilter;
        private BlurMaskFilter mLargeBlurMaskFilter;
        private final Canvas mCanvas = new Canvas();
        private final Canvas mMaskCanvas = new Canvas();
        private final int[] mTmpXY = new int[2];
        private final Matrix mIdentityMatrix = new Matrix();

        HolographicHelper(Context context) {
            mDensity = context.getResources().getDisplayMetrics().density;

            mHolographicPaint.setFilterBitmap(true);
            mHolographicPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
            mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
            mErasePaint.setFilterBitmap(true);

            mSmallBlurMaskFilter = new BlurMaskFilter(2 * mDensity, BlurMaskFilter.Blur.NORMAL);
            mLargeBlurMaskFilter = new BlurMaskFilter(4 * mDensity, BlurMaskFilter.Blur.NORMAL);
        }

        Bitmap createClickOutline(View v, int color) {
            return createOutline(v, CLICK_FEEDBACK, color);
        }

        Bitmap createResOutline(View v, int color) {
            return createOutline(v, RES_OUT, color);
        }

        Bitmap createOutline(View v, int type, int color) {
            mHolographicPaint.setColor(color);
            if (type == RES_OUT) {
                mBlurPaint.setMaskFilter(mSmallBlurMaskFilter);
            } else if (type == CLICK_FEEDBACK) {
                mBlurPaint.setMaskFilter(mLargeBlurMaskFilter);
            }

            if (v.getMeasuredWidth() == 0 || v.getMeasuredHeight() == 0) {
                return null;
            }

            Bitmap bitmap = Bitmap.createBitmap(v.getResources().getDisplayMetrics(),
                    v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            mCanvas.setBitmap(bitmap);

            float rotationX = v.getRotationX();
            float rotation = v.getRotation();
            float translationY = v.getTranslationY();
            float translationX = v.getTranslationX();
            v.setRotationX(0);
            v.setRotation(0);
            v.setTranslationY(0);
            v.setTranslationX(0);
            v.draw(mCanvas);
            v.setRotationX(rotationX);
            v.setRotation(rotation);
            v.setTranslationY(translationY);
            v.setTranslationX(translationX);

            drawOutline(mCanvas, bitmap);
            mCanvas.setBitmap(null);
            return bitmap;
        }

        void drawOutline(Canvas dest, Bitmap src) {
            final int[] xy = mTmpXY;
            Bitmap mask = src.extractAlpha(mBlurPaint, xy);
            mMaskCanvas.setBitmap(mask);
            mMaskCanvas.drawBitmap(src, -xy[0], -xy[1], mErasePaint);
            dest.drawColor(0, PorterDuff.Mode.CLEAR);
            dest.setMatrix(mIdentityMatrix);
            dest.drawBitmap(mask, xy[0], xy[1], mHolographicPaint);
            mMaskCanvas.setBitmap(null);
            mask.recycle();
        }
    }
}
