/*
 * Copyright (C) 2011 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.nfc.beam;

import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

import com.android.nfc.R;
import com.android.nfc.beam.FireflyRenderer;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeAnimator;
import android.app.ActivityManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.AsyncTask;
import android.os.Binder;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ActionMode;
import android.view.Display;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import com.android.internal.policy.PhoneWindow;
import android.view.SearchEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

/**
 * This class is responsible for handling the UI animation
 * around Android Beam. The animation consists of the following
 * animators:
 *
 * mPreAnimator: scales the screenshot down to INTERMEDIATE_SCALE
 * mSlowSendAnimator: scales the screenshot down to 0.2f (used as a "send in progress" animation)
 * mFastSendAnimator: quickly scales the screenshot down to 0.0f (used for send success)
 * mFadeInAnimator: fades the current activity back in (used after mFastSendAnimator completes)
 * mScaleUpAnimator: scales the screenshot back up to full screen (used for failure or receiving)
 * mHintAnimator: Slowly turns up the alpha of the "Touch to Beam" hint
 *
 * Possible sequences are:
 *
 * mPreAnimator => mSlowSendAnimator => mFastSendAnimator => mFadeInAnimator (send success)
 * mPreAnimator => mSlowSendAnimator => mScaleUpAnimator (send failure)
 * mPreAnimator => mScaleUpAnimator (p2p link broken, or data received)
 *
 * Note that mFastSendAnimator and mFadeInAnimator are combined in a set, as they
 * are an atomic animation that cannot be interrupted.
 *
 * All methods of this class must be called on the UI thread
 */
public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
        TimeAnimator.TimeListener, TextureView.SurfaceTextureListener, android.view.Window.Callback {
    static final String TAG = "SendUi";

    static final float INTERMEDIATE_SCALE = 0.6f;

    static final float[] PRE_SCREENSHOT_SCALE = {1.0f, INTERMEDIATE_SCALE};
    static final int PRE_DURATION_MS = 350;

    static final float[] SEND_SCREENSHOT_SCALE = {INTERMEDIATE_SCALE, 0.2f};
    static final int SLOW_SEND_DURATION_MS = 8000; // Stretch out sending over 8s
    static final int FAST_SEND_DURATION_MS = 350;

    static final float[] SCALE_UP_SCREENSHOT_SCALE = {INTERMEDIATE_SCALE, 1.0f};
    static final int SCALE_UP_DURATION_MS = 300;

    static final int FADE_IN_DURATION_MS = 250;
    static final int FADE_IN_START_DELAY_MS = 350;

    static final int SLIDE_OUT_DURATION_MS = 300;

    static final float[] BLACK_LAYER_ALPHA_DOWN_RANGE = {0.9f, 0.0f};
    static final float[] BLACK_LAYER_ALPHA_UP_RANGE = {0.0f, 0.9f};

    static final float[] TEXT_HINT_ALPHA_RANGE = {0.0f, 1.0f};
    static final int TEXT_HINT_ALPHA_DURATION_MS = 500;
    static final int TEXT_HINT_ALPHA_START_DELAY_MS = 300;

    public static final int FINISH_SCALE_UP = 0;
    public static final int FINISH_SEND_SUCCESS = 1;

    static final int STATE_IDLE = 0;
    static final int STATE_W4_SCREENSHOT = 1;
    static final int STATE_W4_SCREENSHOT_PRESEND_REQUESTED = 2;
    static final int STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED = 3;
    static final int STATE_W4_SCREENSHOT_THEN_STOP = 4;
    static final int STATE_W4_PRESEND = 5;
    static final int STATE_W4_TOUCH = 6;
    static final int STATE_W4_NFC_TAP = 7;
    static final int STATE_SENDING = 8;
    static final int STATE_COMPLETE = 9;

    // all members are only used on UI thread
    final WindowManager mWindowManager;
    final Context mContext;
    final Display mDisplay;
    final DisplayMetrics mDisplayMetrics;
    final Matrix mDisplayMatrix;
    final WindowManager.LayoutParams mWindowLayoutParams;
    final LayoutInflater mLayoutInflater;
    final StatusBarManager mStatusBarManager;
    final View mScreenshotLayout;
    final ImageView mScreenshotView;
    final ImageView mBlackLayer;
    final TextureView mTextureView;
    final TextView mTextHint;
    final TextView mTextRetry;
    final Callback mCallback;

    // The mFrameCounter animation is purely used to count down a certain
    // number of (vsync'd) frames. This is needed because the first 3
    // times the animation internally calls eglSwapBuffers(), large buffers
    // are allocated by the graphics drivers. This causes the animation
    // to look janky. So on platforms where we can use hardware acceleration,
    // the animation order is:
    // Wait for hw surface => start frame counter => start pre-animation after 3 frames
    // For platforms where no hw acceleration can be used, the pre-animation
    // is started immediately.
    final TimeAnimator mFrameCounterAnimator;

    final ObjectAnimator mPreAnimator;
    final ObjectAnimator mSlowSendAnimator;
    final ObjectAnimator mFastSendAnimator;
    final ObjectAnimator mFadeInAnimator;
    final ObjectAnimator mHintAnimator;
    final ObjectAnimator mScaleUpAnimator;
    final ObjectAnimator mAlphaDownAnimator;
    final ObjectAnimator mAlphaUpAnimator;
    final AnimatorSet mSuccessAnimatorSet;

    // Besides animating the screenshot, the Beam UI also renders
    // fireflies on platforms where we can do hardware-acceleration.
    // Firefly rendering is only started once the initial
    // "pre-animation" has scaled down the screenshot, to avoid
    // that animation becoming janky. Likewise, the fireflies are
    // stopped in their tracks as soon as we finish the animation,
    // to make the finishing animation smooth.
    final boolean mHardwareAccelerated;
    final FireflyRenderer mFireflyRenderer;

    String mToastString;
    Bitmap mScreenshotBitmap;

    int mState;
    int mRenderedFrames;

    View mDecor;

    // Used for holding the surface
    SurfaceTexture mSurface;
    int mSurfaceWidth;
    int mSurfaceHeight;

    public interface Callback {
        public void onSendConfirmed();
        public void onCanceled();
    }

    public SendUi(Context context, Callback callback) {
        mContext = context;
        mCallback = callback;

        mDisplayMetrics = new DisplayMetrics();
        mDisplayMatrix = new Matrix();
        mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        mStatusBarManager = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE);

        mDisplay = mWindowManager.getDefaultDisplay();

        mLayoutInflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mScreenshotLayout = mLayoutInflater.inflate(R.layout.screenshot, null);

        mScreenshotView = (ImageView) mScreenshotLayout.findViewById(R.id.screenshot);
        mScreenshotLayout.setFocusable(true);

        mTextHint = (TextView) mScreenshotLayout.findViewById(R.id.calltoaction);
        mTextRetry = (TextView) mScreenshotLayout.findViewById(R.id.retrytext);
        mBlackLayer = (ImageView) mScreenshotLayout.findViewById(R.id.blacklayer);
        mTextureView = (TextureView) mScreenshotLayout.findViewById(R.id.fireflies);
        mTextureView.setSurfaceTextureListener(this);

        // We're only allowed to use hardware acceleration if
        // isHighEndGfx() returns true - otherwise, we're too limited
        // on resources to do it.
        mHardwareAccelerated = ActivityManager.isHighEndGfx();
        int hwAccelerationFlags = mHardwareAccelerated ?
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED : 0;

        mWindowLayoutParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                | hwAccelerationFlags
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.OPAQUE);
        mWindowLayoutParams.privateFlags |=
                WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
        mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        mWindowLayoutParams.token = new Binder();

        mFrameCounterAnimator = new TimeAnimator();
        mFrameCounterAnimator.setTimeListener(this);

        PropertyValuesHolder preX = PropertyValuesHolder.ofFloat("scaleX", PRE_SCREENSHOT_SCALE);
        PropertyValuesHolder preY = PropertyValuesHolder.ofFloat("scaleY", PRE_SCREENSHOT_SCALE);
        mPreAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, preX, preY);
        mPreAnimator.setInterpolator(new DecelerateInterpolator());
        mPreAnimator.setDuration(PRE_DURATION_MS);
        mPreAnimator.addListener(this);

        PropertyValuesHolder postX = PropertyValuesHolder.ofFloat("scaleX", SEND_SCREENSHOT_SCALE);
        PropertyValuesHolder postY = PropertyValuesHolder.ofFloat("scaleY", SEND_SCREENSHOT_SCALE);
        PropertyValuesHolder alphaDown = PropertyValuesHolder.ofFloat("alpha",
                new float[]{1.0f, 0.0f});

        mSlowSendAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, postX, postY);
        mSlowSendAnimator.setInterpolator(new DecelerateInterpolator());
        mSlowSendAnimator.setDuration(SLOW_SEND_DURATION_MS);

        mFastSendAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, postX,
                postY, alphaDown);
        mFastSendAnimator.setInterpolator(new DecelerateInterpolator());
        mFastSendAnimator.setDuration(FAST_SEND_DURATION_MS);
        mFastSendAnimator.addListener(this);

        PropertyValuesHolder scaleUpX = PropertyValuesHolder.ofFloat("scaleX", SCALE_UP_SCREENSHOT_SCALE);
        PropertyValuesHolder scaleUpY = PropertyValuesHolder.ofFloat("scaleY", SCALE_UP_SCREENSHOT_SCALE);

        mScaleUpAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, scaleUpX, scaleUpY);
        mScaleUpAnimator.setInterpolator(new DecelerateInterpolator());
        mScaleUpAnimator.setDuration(SCALE_UP_DURATION_MS);
        mScaleUpAnimator.addListener(this);

        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofFloat("alpha", 1.0f);
        mFadeInAnimator = ObjectAnimator.ofPropertyValuesHolder(mScreenshotView, fadeIn);
        mFadeInAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        mFadeInAnimator.setDuration(FADE_IN_DURATION_MS);
        mFadeInAnimator.setStartDelay(FADE_IN_START_DELAY_MS);
        mFadeInAnimator.addListener(this);

        PropertyValuesHolder alphaUp = PropertyValuesHolder.ofFloat("alpha", TEXT_HINT_ALPHA_RANGE);
        mHintAnimator = ObjectAnimator.ofPropertyValuesHolder(mTextHint, alphaUp);
        mHintAnimator.setInterpolator(null);
        mHintAnimator.setDuration(TEXT_HINT_ALPHA_DURATION_MS);
        mHintAnimator.setStartDelay(TEXT_HINT_ALPHA_START_DELAY_MS);

        alphaDown = PropertyValuesHolder.ofFloat("alpha", BLACK_LAYER_ALPHA_DOWN_RANGE);
        mAlphaDownAnimator = ObjectAnimator.ofPropertyValuesHolder(mBlackLayer, alphaDown);
        mAlphaDownAnimator.setInterpolator(new DecelerateInterpolator());
        mAlphaDownAnimator.setDuration(400);

        alphaUp = PropertyValuesHolder.ofFloat("alpha", BLACK_LAYER_ALPHA_UP_RANGE);
        mAlphaUpAnimator = ObjectAnimator.ofPropertyValuesHolder(mBlackLayer, alphaUp);
        mAlphaUpAnimator.setInterpolator(new DecelerateInterpolator());
        mAlphaUpAnimator.setDuration(200);

        mSuccessAnimatorSet = new AnimatorSet();
        mSuccessAnimatorSet.playSequentially(mFastSendAnimator, mFadeInAnimator);

        // Create a Window with a Decor view; creating a window allows us to get callbacks
        // on key events (which require a decor view to be dispatched).
        mContext.setTheme(android.R.style.Theme_Black_NoTitleBar_Fullscreen);
        Window window = new PhoneWindow(mContext);
        window.setCallback(this);
        window.requestFeature(Window.FEATURE_NO_TITLE);
        mDecor = window.getDecorView();
        window.setContentView(mScreenshotLayout, mWindowLayoutParams);

        if (mHardwareAccelerated) {
            mFireflyRenderer = new FireflyRenderer(context);
        } else {
            mFireflyRenderer = null;
        }
        mState = STATE_IDLE;
    }

    public void takeScreenshot() {
        // There's no point in taking the screenshot if
        // we're still finishing the previous animation.
        if (mState >= STATE_W4_TOUCH) {
            return;
        }
        mState = STATE_W4_SCREENSHOT;
        new ScreenshotTask().execute();

        final IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        mContext.registerReceiver(mReceiver, filter);
    }

    /** Show pre-send animation */
    public void showPreSend(boolean promptToNfcTap) {
        switch (mState) {
            case STATE_IDLE:
                Log.e(TAG, "Unexpected showPreSend() in STATE_IDLE");
                return;
            case STATE_W4_SCREENSHOT:
                // Still waiting for screenshot, store request in state
                // and wait for screenshot completion.
                if (promptToNfcTap) {
                    mState = STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED;
                } else {
                    mState = STATE_W4_SCREENSHOT_PRESEND_REQUESTED;
                }
                return;
            case STATE_W4_SCREENSHOT_PRESEND_REQUESTED:
            case STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED:
                Log.e(TAG, "Unexpected showPreSend() in STATE_W4_SCREENSHOT_PRESEND_REQUESTED");
                return;
            case STATE_W4_PRESEND:
                // Expected path, continue below
                break;
            default:
                Log.e(TAG, "Unexpected showPreSend() in state " + Integer.toString(mState));
                return;
        }
        // Update display metrics
        mDisplay.getRealMetrics(mDisplayMetrics);

        final int statusBarHeight = mContext.getResources().getDimensionPixelSize(
                                        com.android.internal.R.dimen.status_bar_height);

        mBlackLayer.setVisibility(View.GONE);
        mBlackLayer.setAlpha(0f);
        mScreenshotLayout.setOnTouchListener(this);
        mScreenshotView.setImageBitmap(mScreenshotBitmap);
        mScreenshotView.setTranslationX(0f);
        mScreenshotView.setAlpha(1.0f);
        mScreenshotView.setPadding(0, statusBarHeight, 0, 0);

        mScreenshotLayout.requestFocus();

        if (promptToNfcTap) {
            mTextHint.setText(mContext.getResources().getString(R.string.ask_nfc_tap));
        } else {
            mTextHint.setText(mContext.getResources().getString(R.string.tap_to_beam));
        }
        mTextHint.setAlpha(0.0f);
        mTextHint.setVisibility(View.VISIBLE);
        mHintAnimator.start();

        // Lock the orientation.
        // The orientation from the configuration does not specify whether
        // the orientation is reverse or not (ie landscape or reverse landscape).
        // So we have to use SENSOR_LANDSCAPE or SENSOR_PORTRAIT to make sure
        // we lock in portrait / landscape and have the sensor determine
        // which way is up.
        int orientation = mContext.getResources().getConfiguration().orientation;

        switch (orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                mWindowLayoutParams.screenOrientation =
                        ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                mWindowLayoutParams.screenOrientation =
                        ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
                break;
            default:
                mWindowLayoutParams.screenOrientation =
                        ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
                break;
        }

        mWindowManager.addView(mDecor, mWindowLayoutParams);
        // Disable statusbar pull-down
        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);

        mToastString = null;

        if (!mHardwareAccelerated) {
            mPreAnimator.start();
        } // else, we will start the animation once we get the hardware surface
        mState = promptToNfcTap ? STATE_W4_NFC_TAP : STATE_W4_TOUCH;
    }

    /** Show starting send animation */
    public void showStartSend() {
        if (mState < STATE_SENDING) return;

        mTextRetry.setVisibility(View.GONE);
        // Update the starting scale - touchscreen-mashers may trigger
        // this before the pre-animation completes.
        float currentScale = mScreenshotView.getScaleX();
        PropertyValuesHolder postX = PropertyValuesHolder.ofFloat("scaleX",
                new float[] {currentScale, 0.0f});
        PropertyValuesHolder postY = PropertyValuesHolder.ofFloat("scaleY",
                new float[] {currentScale, 0.0f});

        mSlowSendAnimator.setValues(postX, postY);

        float currentAlpha = mBlackLayer.getAlpha();
        if (mBlackLayer.isShown() && currentAlpha > 0.0f) {
            PropertyValuesHolder alphaDown = PropertyValuesHolder.ofFloat("alpha",
                    new float[] {currentAlpha, 0.0f});
            mAlphaDownAnimator.setValues(alphaDown);
            mAlphaDownAnimator.start();
        }
        mSlowSendAnimator.start();
    }

    public void finishAndToast(int finishMode, String toast) {
        mToastString = toast;

        finish(finishMode);
    }

    /** Return to initial state */
    public void finish(int finishMode) {
        switch (mState) {
            case STATE_IDLE:
                return;
            case STATE_W4_SCREENSHOT:
            case STATE_W4_SCREENSHOT_PRESEND_REQUESTED:
            case STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED:
                // Screenshot is still being captured on a separate thread.
                // Update state, and stop everything when the capture is done.
                mState = STATE_W4_SCREENSHOT_THEN_STOP;
                return;
            case STATE_W4_SCREENSHOT_THEN_STOP:
                Log.e(TAG, "Unexpected call to finish() in STATE_W4_SCREENSHOT_THEN_STOP");
                return;
            case STATE_W4_PRESEND:
                // We didn't build up any animation state yet, but
                // did store the bitmap. Clear out the bitmap, reset
                // state and bail.
                mScreenshotBitmap = null;
                mState = STATE_IDLE;
                return;
            default:
                // We've started animations and attached a view; tear stuff down below.
                break;
        }

        // Stop rendering the fireflies
        if (mFireflyRenderer != null) {
            mFireflyRenderer.stop();
        }

        mTextHint.setVisibility(View.GONE);
        mTextRetry.setVisibility(View.GONE);

        float currentScale = mScreenshotView.getScaleX();
        float currentAlpha = mScreenshotView.getAlpha();

        if (finishMode == FINISH_SCALE_UP) {
            mBlackLayer.setVisibility(View.GONE);
            PropertyValuesHolder scaleUpX = PropertyValuesHolder.ofFloat("scaleX",
                    new float[] {currentScale, 1.0f});
            PropertyValuesHolder scaleUpY = PropertyValuesHolder.ofFloat("scaleY",
                    new float[] {currentScale, 1.0f});
            PropertyValuesHolder scaleUpAlpha = PropertyValuesHolder.ofFloat("alpha",
                    new float[] {currentAlpha, 1.0f});
            mScaleUpAnimator.setValues(scaleUpX, scaleUpY, scaleUpAlpha);

            mScaleUpAnimator.start();
        } else if (finishMode == FINISH_SEND_SUCCESS){
            // Modify the fast send parameters to match the current scale
            PropertyValuesHolder postX = PropertyValuesHolder.ofFloat("scaleX",
                    new float[] {currentScale, 0.0f});
            PropertyValuesHolder postY = PropertyValuesHolder.ofFloat("scaleY",
                    new float[] {currentScale, 0.0f});
            PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha",
                    new float[] {currentAlpha, 0.0f});
            mFastSendAnimator.setValues(postX, postY, alpha);

            // Reset the fadeIn parameters to start from alpha 1
            PropertyValuesHolder fadeIn = PropertyValuesHolder.ofFloat("alpha",
                    new float[] {0.0f, 1.0f});
            mFadeInAnimator.setValues(fadeIn);

            mSlowSendAnimator.cancel();
            mSuccessAnimatorSet.start();
        }
        mState = STATE_COMPLETE;
    }

    void dismiss() {
        if (mState < STATE_W4_TOUCH) return;
        // Immediately set to IDLE, to prevent .cancel() calls
        // below from immediately calling into dismiss() again.
        // (They can do so on the same thread).
        mState = STATE_IDLE;
        mSurface = null;
        mFrameCounterAnimator.cancel();
        mPreAnimator.cancel();
        mSlowSendAnimator.cancel();
        mFastSendAnimator.cancel();
        mSuccessAnimatorSet.cancel();
        mScaleUpAnimator.cancel();
        mAlphaUpAnimator.cancel();
        mAlphaDownAnimator.cancel();
        mWindowManager.removeView(mDecor);
        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
        mScreenshotBitmap = null;
        mContext.unregisterReceiver(mReceiver);
        if (mToastString != null) {
            Toast toast = Toast.makeText(mContext, mToastString, Toast.LENGTH_LONG);
            toast.getWindowParams().privateFlags |= LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
            toast.show();
        }
        mToastString = null;
    }

    /**
     * @return the current display rotation in degrees
     */
    static float getDegreesForRotation(int value) {
        switch (value) {
        case Surface.ROTATION_90:
            return 90f;
        case Surface.ROTATION_180:
            return 180f;
        case Surface.ROTATION_270:
            return 270f;
        }
        return 0f;
    }

    final class ScreenshotTask extends AsyncTask<Void, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(Void... params) {
            return createScreenshot();
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (mState == STATE_W4_SCREENSHOT) {
                // Screenshot done, wait for request to start preSend anim
                mScreenshotBitmap = result;
                mState = STATE_W4_PRESEND;
            } else if (mState == STATE_W4_SCREENSHOT_THEN_STOP) {
                // We were asked to finish, move to idle state and exit
                mState = STATE_IDLE;
            } else if (mState == STATE_W4_SCREENSHOT_PRESEND_REQUESTED ||
                    mState == STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED) {
                mScreenshotBitmap = result;
                boolean requestTap = (mState == STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED);
                mState = STATE_W4_PRESEND;
                showPreSend(requestTap);
            } else {
                Log.e(TAG, "Invalid state on screenshot completion: " + Integer.toString(mState));
            }
        }
    };

    /**
     * Returns a screenshot of the current display contents.
     */
    Bitmap createScreenshot() {
        boolean hasNavBar =  mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_showNavigationBar);
        final int statusBarHeight = mContext.getResources().getDimensionPixelSize(
                                        com.android.internal.R.dimen.status_bar_height);

        // Navbar has different sizes, depending on orientation
        final int navBarHeight = hasNavBar ? mContext.getResources().getDimensionPixelSize(
                                        com.android.internal.R.dimen.navigation_bar_height) : 0;
        final int navBarHeightLandscape = hasNavBar ? mContext.getResources().getDimensionPixelSize(
                                        com.android.internal.R.dimen.navigation_bar_height_landscape) : 0;

        final int navBarWidth = hasNavBar ? mContext.getResources().getDimensionPixelSize(
                                        com.android.internal.R.dimen.navigation_bar_width) : 0;

        mDisplay.getRealMetrics(mDisplayMetrics);
        float smallestWidth = (float)Math.min(mDisplayMetrics.widthPixels,
                mDisplayMetrics.heightPixels);
        float smallestWidthDp = smallestWidth / (mDisplayMetrics.densityDpi / 160f);

        int rot = mDisplay.getRotation();

        // TODO this is somewhat device-specific; need generic solution.
        // The starting crop for the screenshot is the fullscreen without the status bar, which
        // is always on top. The conditional check will determine how to crop the navbar,
        // depending on orienation and screen size.
        Rect crop = new Rect(0, statusBarHeight, mDisplayMetrics.widthPixels,
                mDisplayMetrics.heightPixels);
        if (mDisplayMetrics.widthPixels < mDisplayMetrics.heightPixels) {
            // Portrait mode: crop the navbar out from the bottom, width unchanged
            crop.bottom -= navBarHeight;
        } else {
            // Landscape mode:
            if (smallestWidthDp > 599) {
                // Navbar on bottom on >599dp width devices, so crop navbar out from the bottom.
                crop.bottom -= navBarHeightLandscape;
            } else {
                // Navbar on right, so crop navbar out from right of screen.
                crop.right -= navBarWidth;
            }
        }

        int width = crop.width();
        int height = crop.height();
        // Take the screenshot. SurfaceControl will generate a hardware bitmap in the correct
        // orientation and size.
        Bitmap bitmap = SurfaceControl.screenshot(crop, width, height, rot);
        // Bail if we couldn't take the screenshot
        if (bitmap == null) {
            return null;
        }

        // Convert to a software bitmap so it can be set in an ImageView.
        Bitmap swBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
        return swBitmap;
    }

    @Override
    public void onAnimationStart(Animator animation) {  }

    @Override
    public void onAnimationEnd(Animator animation) {
        if (animation == mScaleUpAnimator || animation == mSuccessAnimatorSet ||
            animation == mFadeInAnimator) {
            // These all indicate the end of the animation
            dismiss();
        } else if (animation == mFastSendAnimator) {
            // After sending is done and we've faded out, reset the scale to 1
            // so we can fade it back in.
            mScreenshotView.setScaleX(1.0f);
            mScreenshotView.setScaleY(1.0f);
        } else if (animation == mPreAnimator) {
            if (mHardwareAccelerated && (mState == STATE_W4_TOUCH || mState == STATE_W4_NFC_TAP)) {
                mFireflyRenderer.start(mSurface, mSurfaceWidth, mSurfaceHeight);
            }
        }
    }

    @Override
    public void onAnimationCancel(Animator animation) {  }

    @Override
    public void onAnimationRepeat(Animator animation) {  }

    @Override
    public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
        // This gets called on animation vsync
        if (++mRenderedFrames < 4) {
            // For the first 3 frames, call invalidate(); this calls eglSwapBuffers
            // on the surface, which will allocate large buffers the first three calls
            // as Android uses triple buffering.
            mScreenshotLayout.invalidate();
        } else {
            // Buffers should be allocated, start the real animation
            mFrameCounterAnimator.cancel();
            mPreAnimator.start();
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (mState != STATE_W4_TOUCH) {
            return false;
        }
        mState = STATE_SENDING;
        // Ignore future touches
        mScreenshotView.setOnTouchListener(null);

        // Cancel any ongoing animations
        mFrameCounterAnimator.cancel();
        mPreAnimator.cancel();

        mCallback.onSendConfirmed();
        return true;
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        if (mHardwareAccelerated && mState < STATE_COMPLETE) {
            mRenderedFrames = 0;

            mFrameCounterAnimator.start();
            mSurface = surface;
            mSurfaceWidth = width;
            mSurfaceHeight = height;
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // Since we've disabled orientation changes, we can safely ignore this
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        mSurface = null;

        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) { }

    public void showSendHint() {
        if (mAlphaDownAnimator.isRunning()) {
           mAlphaDownAnimator.cancel();
        }
        if (mSlowSendAnimator.isRunning()) {
            mSlowSendAnimator.cancel();
        }
        mBlackLayer.setScaleX(mScreenshotView.getScaleX());
        mBlackLayer.setScaleY(mScreenshotView.getScaleY());
        mBlackLayer.setVisibility(View.VISIBLE);
        mTextHint.setVisibility(View.GONE);

        mTextRetry.setText(mContext.getResources().getString(R.string.beam_try_again));
        mTextRetry.setVisibility(View.VISIBLE);

        PropertyValuesHolder alphaUp = PropertyValuesHolder.ofFloat("alpha",
                new float[] {mBlackLayer.getAlpha(), 0.9f});
        mAlphaUpAnimator.setValues(alphaUp);
        mAlphaUpAnimator.start();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            mCallback.onCanceled();
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
                keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
            // Treat as if it's a touch event
            return onTouch(mScreenshotView, null);
        } else {
            return false;
        }
    }

    @Override
    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return mScreenshotLayout.dispatchTouchEvent(event);
    }

    @Override
    public boolean dispatchTrackballEvent(MotionEvent event) {
        return false;
    }

    @Override
    public boolean dispatchGenericMotionEvent(MotionEvent event) {
        return false;
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        return false;
    }

    @Override
    public View onCreatePanelView(int featureId) {
        return null;
    }

    @Override
    public boolean onCreatePanelMenu(int featureId, Menu menu) {
        return false;
    }

    @Override
    public boolean onPreparePanel(int featureId, View view, Menu menu) {
        return false;
    }

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        return false;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        return false;
    }

    @Override
    public void onWindowAttributesChanged(LayoutParams attrs) {
    }

    @Override
    public void onContentChanged() {
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
    }

    @Override
    public void onAttachedToWindow() {

    }

    @Override
    public void onDetachedFromWindow() {
    }

    @Override
    public void onPanelClosed(int featureId, Menu menu) {

    }

    @Override
    public boolean onSearchRequested(SearchEvent searchEvent) {
        return onSearchRequested();
    }

    @Override
    public boolean onSearchRequested() {
        return false;
    }

    @Override
    public ActionMode onWindowStartingActionMode(
            android.view.ActionMode.Callback callback) {
        return null;
    }

    public ActionMode onWindowStartingActionMode(
            android.view.ActionMode.Callback callback, int type) {
        return null;
    }

    @Override
    public void onActionModeStarted(ActionMode mode) {
    }

    @Override
    public void onActionModeFinished(ActionMode mode) {
    }

    public boolean isSendUiInIdleState() {
        return mState == STATE_IDLE;
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
                mCallback.onCanceled();
            }
        }
    };
}
