/*
 * 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 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.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) {
                if (result != null) {
                    mScreenshotBitmap = result;
                    boolean requestTap = (mState == STATE_W4_SCREENSHOT_PRESEND_NFC_TAP_REQUESTED);
                    mState = STATE_W4_PRESEND;
                    showPreSend(requestTap);
                } else {
                    // Failed to take screenshot; reset state to idle
                    // and don't do anything
                    Log.e(TAG, "Failed to create screenshot");
                    mState = STATE_IDLE;
                }
            } 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) {
    }

    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();
            }
        }
    };
}
