/*
 * Copyright (C) 2021 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.systemui.screenshot;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.Range;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.SeekBar;

import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.customview.widget.ExploreByTouchHelper;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;

import com.android.internal.graphics.ColorUtils;
import com.android.systemui.R;

import java.util.List;

/**
 * CropView has top and bottom draggable crop handles, with a scrim to darken the areas being
 * cropped out.
 */
public class CropView extends View {
    private static final String TAG = "CropView";

    public enum CropBoundary {
        NONE, TOP, BOTTOM, LEFT, RIGHT
    }

    private final float mCropTouchMargin;
    private final Paint mShadePaint;
    private final Paint mHandlePaint;
    private final Paint mContainerBackgroundPaint;

    // Crop rect with each element represented as [0,1] along its proper axis.
    private RectF mCrop = new RectF(0, 0, 1, 1);

    private int mExtraTopPadding;
    private int mExtraBottomPadding;
    private int mImageWidth;

    private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
    private int mActivePointerId;
    // The starting value of mCurrentDraggingBoundary's crop, used to compute touch deltas.
    private float mMovementStartValue;
    private float mStartingY;  // y coordinate of ACTION_DOWN
    private float mStartingX;
    // The allowable values for the current boundary being dragged
    private Range<Float> mMotionRange;

    // Value [0,1] indicating progress in animateEntrance()
    private float mEntranceInterpolation = 1f;

    private CropInteractionListener mCropInteractionListener;
    private final ExploreByTouchHelper mExploreByTouchHelper;

    public CropView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CropView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray t = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.CropView, 0, 0);
        mShadePaint = new Paint();
        int alpha = t.getInteger(R.styleable.CropView_scrimAlpha, 255);
        int scrimColor = t.getColor(R.styleable.CropView_scrimColor, Color.TRANSPARENT);
        mShadePaint.setColor(ColorUtils.setAlphaComponent(scrimColor, alpha));
        mContainerBackgroundPaint = new Paint();
        mContainerBackgroundPaint.setColor(t.getColor(R.styleable.CropView_containerBackgroundColor,
                Color.TRANSPARENT));
        mHandlePaint = new Paint();
        mHandlePaint.setColor(t.getColor(R.styleable.CropView_handleColor, Color.BLACK));
        mHandlePaint.setStrokeCap(Paint.Cap.ROUND);
        mHandlePaint.setStrokeWidth(
                t.getDimensionPixelSize(R.styleable.CropView_handleThickness, 20));
        t.recycle();
        // 48 dp touchable region around each handle.
        mCropTouchMargin = 24 * getResources().getDisplayMetrics().density;

        mExploreByTouchHelper = new AccessibilityHelper();
        ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();

        SavedState ss = new SavedState(superState);
        ss.mCrop = mCrop;
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        mCrop = ss.mCrop;
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // Top and bottom borders reflect the boundary between the (scrimmed) image and the
        // opaque container background. This is only meaningful during an entrance transition.
        float topBorder = MathUtils.lerp(mCrop.top, 0, mEntranceInterpolation);
        float bottomBorder = MathUtils.lerp(mCrop.bottom, 1, mEntranceInterpolation);
        drawShade(canvas, 0, topBorder, 1, mCrop.top);
        drawShade(canvas, 0, mCrop.bottom, 1, bottomBorder);
        drawShade(canvas, 0, mCrop.top, mCrop.left, mCrop.bottom);
        drawShade(canvas, mCrop.right, mCrop.top, 1, mCrop.bottom);

        // Entrance transition expects the crop bounds to be full width, so we only draw container
        // background on the top and bottom.
        drawContainerBackground(canvas, 0, 0, 1, topBorder);
        drawContainerBackground(canvas, 0, bottomBorder, 1, 1);

        mHandlePaint.setAlpha((int) (mEntranceInterpolation * 255));

        drawHorizontalHandle(canvas, mCrop.top, /* draw the handle tab up */ true);
        drawHorizontalHandle(canvas, mCrop.bottom, /* draw the handle tab down */ false);
        drawVerticalHandle(canvas, mCrop.left, /* left */ true);
        drawVerticalHandle(canvas, mCrop.right, /* right */ false);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int topPx = fractionToVerticalPixels(mCrop.top);
        int bottomPx = fractionToVerticalPixels(mCrop.bottom);
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mCurrentDraggingBoundary = nearestBoundary(event, topPx, bottomPx,
                        fractionToHorizontalPixels(mCrop.left),
                        fractionToHorizontalPixels(mCrop.right));
                if (mCurrentDraggingBoundary != CropBoundary.NONE) {
                    mActivePointerId = event.getPointerId(0);
                    mStartingY = event.getY();
                    mStartingX = event.getX();
                    mMovementStartValue = getBoundaryPosition(mCurrentDraggingBoundary);
                    updateListener(MotionEvent.ACTION_DOWN, event.getX());
                    mMotionRange = getAllowedValues(mCurrentDraggingBoundary);
                }
                return true;
            case MotionEvent.ACTION_MOVE:
                if (mCurrentDraggingBoundary != CropBoundary.NONE) {
                    int pointerIndex = event.findPointerIndex(mActivePointerId);
                    if (pointerIndex >= 0) {
                        // Original pointer still active, do the move.
                        float deltaPx = isVertical(mCurrentDraggingBoundary)
                                ? event.getY(pointerIndex) - mStartingY
                                : event.getX(pointerIndex) - mStartingX;
                        float delta = pixelDistanceToFraction((int) deltaPx,
                                mCurrentDraggingBoundary);
                        setBoundaryPosition(mCurrentDraggingBoundary,
                                mMotionRange.clamp(mMovementStartValue + delta));
                        updateListener(MotionEvent.ACTION_MOVE, event.getX(pointerIndex));
                        invalidate();
                    }
                    return true;
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                if (mActivePointerId == event.getPointerId(event.getActionIndex())
                        && mCurrentDraggingBoundary != CropBoundary.NONE) {
                    updateListener(MotionEvent.ACTION_DOWN, event.getX(event.getActionIndex()));
                    return true;
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                if (mActivePointerId == event.getPointerId(event.getActionIndex())
                        && mCurrentDraggingBoundary != CropBoundary.NONE) {
                    updateListener(MotionEvent.ACTION_UP, event.getX(event.getActionIndex()));
                    return true;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mCurrentDraggingBoundary != CropBoundary.NONE
                        && mActivePointerId == event.getPointerId(mActivePointerId)) {
                    updateListener(MotionEvent.ACTION_UP, event.getX(0));
                    return true;
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean dispatchHoverEvent(MotionEvent event) {
        return mExploreByTouchHelper.dispatchHoverEvent(event)
                || super.dispatchHoverEvent(event);
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        return mExploreByTouchHelper.dispatchKeyEvent(event)
                || super.dispatchKeyEvent(event);
    }

    @Override
    public void onFocusChanged(boolean gainFocus, int direction,
            Rect previouslyFocusedRect) {
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        mExploreByTouchHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
    }

    /**
     * Set the given boundary to the given value without animation.
     */
    public void setBoundaryPosition(CropBoundary boundary, float position) {
        position = (float) getAllowedValues(boundary).clamp(position);
        switch (boundary) {
            case TOP:
                mCrop.top = position;
                break;
            case BOTTOM:
                mCrop.bottom = position;
                break;
            case LEFT:
                mCrop.left = position;
                break;
            case RIGHT:
                mCrop.right = position;
                break;
            case NONE:
                Log.w(TAG, "No boundary selected");
                break;
        }

        invalidate();
    }

    private float getBoundaryPosition(CropBoundary boundary) {
        switch (boundary) {
            case TOP:
                return mCrop.top;
            case BOTTOM:
                return mCrop.bottom;
            case LEFT:
                return mCrop.left;
            case RIGHT:
                return mCrop.right;
        }
        return 0;
    }

    private static boolean isVertical(CropBoundary boundary) {
        return boundary == CropBoundary.TOP || boundary == CropBoundary.BOTTOM;
    }

    /**
     * Animate the given boundary to the given value.
     */
    public void animateBoundaryTo(CropBoundary boundary, float value) {
        if (boundary == CropBoundary.NONE) {
            Log.w(TAG, "No boundary selected for animation");
            return;
        }
        float start = getBoundaryPosition(boundary);
        ValueAnimator animator = new ValueAnimator();
        animator.addUpdateListener(animation -> {
            setBoundaryPosition(boundary,
                    MathUtils.lerp(start, value, animation.getAnimatedFraction()));
            invalidate();
        });
        animator.setFloatValues(0f, 1f);
        animator.setDuration(750);
        animator.setInterpolator(new FastOutSlowInInterpolator());
        animator.start();
    }

    /**
     * Fade in crop bounds, animate reveal of cropped-out area from current crop bounds.
     */
    public void animateEntrance() {
        mEntranceInterpolation = 0;
        ValueAnimator animator = new ValueAnimator();
        animator.addUpdateListener(animation -> {
            mEntranceInterpolation = animation.getAnimatedFraction();
            invalidate();
        });
        animator.setFloatValues(0f, 1f);
        animator.setDuration(750);
        animator.setInterpolator(new FastOutSlowInInterpolator());
        animator.start();
    }

    /**
     * Set additional top and bottom padding for the image being cropped (used when the
     * corresponding ImageView doesn't take the full height).
     */
    public void setExtraPadding(int top, int bottom) {
        mExtraTopPadding = top;
        mExtraBottomPadding = bottom;
        invalidate();
    }

    /**
     * Set the pixel width of the image on the screen (on-screen dimension, not actual bitmap
     * dimension)
     */
    public void setImageWidth(int width) {
        mImageWidth = width;
        invalidate();
    }

    /**
     * @return RectF with values [0,1] representing the position of the boundaries along image axes.
     */
    public Rect getCropBoundaries(int imageWidth, int imageHeight) {
        return new Rect((int) (mCrop.left * imageWidth), (int) (mCrop.top * imageHeight),
                (int) (mCrop.right * imageWidth), (int) (mCrop.bottom * imageHeight));
    }

    public void setCropInteractionListener(CropInteractionListener listener) {
        mCropInteractionListener = listener;
    }

    private Range getAllowedValues(CropBoundary boundary) {
        switch (boundary) {
            case TOP:
                return new Range<>(0f,
                        mCrop.bottom - pixelDistanceToFraction(mCropTouchMargin,
                                CropBoundary.BOTTOM));
            case BOTTOM:
                return new Range<>(
                        mCrop.top + pixelDistanceToFraction(mCropTouchMargin,
                                CropBoundary.TOP), 1f);
            case LEFT:
                return new Range<>(0f,
                        mCrop.right - pixelDistanceToFraction(mCropTouchMargin,
                                CropBoundary.RIGHT));
            case RIGHT:
                return new Range<>(
                        mCrop.left + pixelDistanceToFraction(mCropTouchMargin,
                                CropBoundary.LEFT), 1f);
        }
        return null;
    }

    /**
     * @param action either ACTION_DOWN, ACTION_UP or ACTION_MOVE.
     * @param x coordinate of the relevant pointer.
     */
    private void updateListener(int action, float x) {
        if (mCropInteractionListener != null && isVertical(mCurrentDraggingBoundary)) {
            float boundaryPosition = getBoundaryPosition(mCurrentDraggingBoundary);
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    mCropInteractionListener.onCropDragStarted(mCurrentDraggingBoundary,
                            boundaryPosition, fractionToVerticalPixels(boundaryPosition),
                            (mCrop.left + mCrop.right) / 2, x);
                    break;
                case MotionEvent.ACTION_MOVE:
                    mCropInteractionListener.onCropDragMoved(mCurrentDraggingBoundary,
                            boundaryPosition, fractionToVerticalPixels(boundaryPosition),
                            (mCrop.left + mCrop.right) / 2, x);
                    break;
                case MotionEvent.ACTION_UP:
                    mCropInteractionListener.onCropDragComplete();
                    break;

            }
        }
    }

    /**
     * Draw a shade to the given canvas with the given [0,1] fractional image bounds.
     */
    private void drawShade(Canvas canvas, float left, float top, float right, float bottom) {
        canvas.drawRect(fractionToHorizontalPixels(left), fractionToVerticalPixels(top),
                fractionToHorizontalPixels(right),
                fractionToVerticalPixels(bottom), mShadePaint);
    }

    private void drawContainerBackground(Canvas canvas, float left, float top, float right,
            float bottom) {
        canvas.drawRect(fractionToHorizontalPixels(left), fractionToVerticalPixels(top),
                fractionToHorizontalPixels(right),
                fractionToVerticalPixels(bottom), mContainerBackgroundPaint);
    }

    private void drawHorizontalHandle(Canvas canvas, float frac, boolean handleTabUp) {
        int y = fractionToVerticalPixels(frac);
        canvas.drawLine(fractionToHorizontalPixels(mCrop.left), y,
                fractionToHorizontalPixels(mCrop.right), y, mHandlePaint);
        float radius = 8 * getResources().getDisplayMetrics().density;
        int x = (fractionToHorizontalPixels(mCrop.left) + fractionToHorizontalPixels(mCrop.right))
                / 2;
        canvas.drawArc(x - radius, y - radius, x + radius, y + radius, handleTabUp ? 180 : 0, 180,
                true, mHandlePaint);
    }

    private void drawVerticalHandle(Canvas canvas, float frac, boolean handleTabLeft) {
        int x = fractionToHorizontalPixels(frac);
        canvas.drawLine(x, fractionToVerticalPixels(mCrop.top), x,
                fractionToVerticalPixels(mCrop.bottom), mHandlePaint);
        float radius = 8 * getResources().getDisplayMetrics().density;
        int y = (fractionToVerticalPixels(getBoundaryPosition(CropBoundary.TOP))
                + fractionToVerticalPixels(
                getBoundaryPosition(CropBoundary.BOTTOM))) / 2;
        canvas.drawArc(x - radius, y - radius, x + radius, y + radius, handleTabLeft ? 90 : 270,
                180,
                true, mHandlePaint);
    }

    /**
     * Convert the given fraction position to pixel position within the View.
     */
    private int fractionToVerticalPixels(float frac) {
        return (int) (mExtraTopPadding + frac * getImageHeight());
    }

    private int fractionToHorizontalPixels(float frac) {
        return (int) ((getWidth() - mImageWidth) / 2 + frac * mImageWidth);
    }

    private int getImageHeight() {
        return getHeight() - mExtraTopPadding - mExtraBottomPadding;
    }

    /**
     * Convert the given pixel distance to fraction of the image.
     */
    private float pixelDistanceToFraction(float px, CropBoundary boundary) {
        if (isVertical(boundary)) {
            return px / getImageHeight();
        } else {
            return px / mImageWidth;
        }
    }

    private CropBoundary nearestBoundary(MotionEvent event, int topPx, int bottomPx, int leftPx,
            int rightPx) {
        if (Math.abs(event.getY() - topPx) < mCropTouchMargin) {
            return CropBoundary.TOP;
        }
        if (Math.abs(event.getY() - bottomPx) < mCropTouchMargin) {
            return CropBoundary.BOTTOM;
        }
        if (event.getY() > topPx || event.getY() < bottomPx) {
            if (Math.abs(event.getX() - leftPx) < mCropTouchMargin) {
                return CropBoundary.LEFT;
            }
            if (Math.abs(event.getX() - rightPx) < mCropTouchMargin) {
                return CropBoundary.RIGHT;
            }
        }
        return CropBoundary.NONE;
    }

    private class AccessibilityHelper extends ExploreByTouchHelper {

        private static final int TOP_HANDLE_ID = 1;
        private static final int BOTTOM_HANDLE_ID = 2;
        private static final int LEFT_HANDLE_ID = 3;
        private static final int RIGHT_HANDLE_ID = 4;

        AccessibilityHelper() {
            super(CropView.this);
        }

        @Override
        protected int getVirtualViewAt(float x, float y) {
            if (Math.abs(y - fractionToVerticalPixels(mCrop.top)) < mCropTouchMargin) {
                return TOP_HANDLE_ID;
            }
            if (Math.abs(y - fractionToVerticalPixels(mCrop.bottom)) < mCropTouchMargin) {
                return BOTTOM_HANDLE_ID;
            }
            if (y > fractionToVerticalPixels(mCrop.top)
                    && y < fractionToVerticalPixels(mCrop.bottom)) {
                if (Math.abs(x - fractionToHorizontalPixels(mCrop.left)) < mCropTouchMargin) {
                    return LEFT_HANDLE_ID;
                }
                if (Math.abs(x - fractionToHorizontalPixels(mCrop.right)) < mCropTouchMargin) {
                    return RIGHT_HANDLE_ID;
                }
            }

            return ExploreByTouchHelper.HOST_ID;
        }

        @Override
        protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
            // Add views in traversal order
            virtualViewIds.add(TOP_HANDLE_ID);
            virtualViewIds.add(LEFT_HANDLE_ID);
            virtualViewIds.add(RIGHT_HANDLE_ID);
            virtualViewIds.add(BOTTOM_HANDLE_ID);
        }

        @Override
        protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
            CropBoundary boundary = viewIdToBoundary(virtualViewId);
            event.setContentDescription(getBoundaryContentDescription(boundary));
        }

        @Override
        protected void onPopulateNodeForVirtualView(int virtualViewId,
                AccessibilityNodeInfoCompat node) {
            CropBoundary boundary = viewIdToBoundary(virtualViewId);
            node.setContentDescription(getBoundaryContentDescription(boundary));
            setNodePosition(getNodeRect(boundary), node);

            // Intentionally set the class name to SeekBar so that TalkBack uses volume control to
            // scroll.
            node.setClassName(SeekBar.class.getName());
            node.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
            node.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
        }

        @Override
        protected boolean onPerformActionForVirtualView(
                int virtualViewId, int action, Bundle arguments) {
            if (action != AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
                    && action != AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
                return false;
            }
            CropBoundary boundary = viewIdToBoundary(virtualViewId);
            float delta = pixelDistanceToFraction(mCropTouchMargin, boundary);
            if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
                delta = -delta;
            }
            setBoundaryPosition(boundary, delta + getBoundaryPosition(boundary));
            invalidateVirtualView(virtualViewId);
            sendEventForVirtualView(virtualViewId, AccessibilityEvent.TYPE_VIEW_SELECTED);
            return true;
        }

        private CharSequence getBoundaryContentDescription(CropBoundary boundary) {
            int template;
            switch (boundary) {
                case TOP:
                    template = R.string.screenshot_top_boundary_pct;
                    break;
                case BOTTOM:
                    template = R.string.screenshot_bottom_boundary_pct;
                    break;
                case LEFT:
                    template = R.string.screenshot_left_boundary_pct;
                    break;
                case RIGHT:
                    template = R.string.screenshot_right_boundary_pct;
                    break;
                default:
                    return "";
            }

            return getResources().getString(template,
                    Math.round(getBoundaryPosition(boundary) * 100));
        }

        private CropBoundary viewIdToBoundary(int viewId) {
            switch (viewId) {
                case TOP_HANDLE_ID:
                    return CropBoundary.TOP;
                case BOTTOM_HANDLE_ID:
                    return CropBoundary.BOTTOM;
                case LEFT_HANDLE_ID:
                    return CropBoundary.LEFT;
                case RIGHT_HANDLE_ID:
                    return CropBoundary.RIGHT;
            }
            return CropBoundary.NONE;
        }

        private Rect getNodeRect(CropBoundary boundary) {
            Rect rect;
            if (isVertical(boundary)) {
                int pixels = fractionToVerticalPixels(getBoundaryPosition(boundary));
                rect = new Rect(0, (int) (pixels - mCropTouchMargin),
                        getWidth(), (int) (pixels + mCropTouchMargin));
                // Top boundary can sometimes go beyond the view, shift it down to compensate so
                // the area is big enough.
                if (rect.top < 0) {
                    rect.offset(0, -rect.top);
                }
            } else {
                int pixels = fractionToHorizontalPixels(getBoundaryPosition(boundary));
                rect = new Rect((int) (pixels - mCropTouchMargin),
                        (int) (fractionToVerticalPixels(mCrop.top) + mCropTouchMargin),
                        (int) (pixels + mCropTouchMargin),
                        (int) (fractionToVerticalPixels(mCrop.bottom) - mCropTouchMargin));
            }
            return rect;
        }

        private void setNodePosition(Rect rect, AccessibilityNodeInfoCompat node) {
            node.setBoundsInParent(rect);
            int[] pos = new int[2];
            getLocationOnScreen(pos);
            rect.offset(pos[0], pos[1]);
            node.setBoundsInScreen(rect);
        }
    }

    /**
     * Listen for crop motion events and state.
     */
    public interface CropInteractionListener {
        void onCropDragStarted(CropBoundary boundary, float boundaryPosition,
                int boundaryPositionPx, float horizontalCenter, float x);
        void onCropDragMoved(CropBoundary boundary, float boundaryPosition,
                int boundaryPositionPx, float horizontalCenter, float x);
        void onCropDragComplete();
    }

    static class SavedState extends BaseSavedState {
        RectF mCrop;

        /**
         * Constructor called from {@link CropView#onSaveInstanceState()}
         */
        SavedState(Parcelable superState) {
            super(superState);
        }

        /**
         * Constructor called from {@link #CREATOR}
         */
        private SavedState(Parcel in) {
            super(in);
            mCrop = in.readParcelable(ClassLoader.getSystemClassLoader());
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeParcelable(mCrop, 0);
        }

        public static final Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}
