/*
 * Copyright (C) 2015 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.assist;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;

import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;

/**
 * Visually discloses that contextual data was provided to an assistant.
 */
public class AssistDisclosure {
    private final Context mContext;
    private final WindowManager mWm;
    private final Handler mHandler;

    private AssistDisclosureView mView;
    private boolean mViewAdded;

    public AssistDisclosure(Context context, Handler handler) {
        mContext = context;
        mHandler = handler;
        mWm = mContext.getSystemService(WindowManager.class);
    }

    public void postShow() {
        mHandler.removeCallbacks(mShowRunnable);
        mHandler.post(mShowRunnable);
    }

    private void show() {
        if (mView == null) {
            mView = new AssistDisclosureView(mContext);
        }
        if (!mViewAdded) {
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                            | WindowManager.LayoutParams.FLAG_FULLSCREEN
                            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
                    PixelFormat.TRANSLUCENT);
            lp.setTitle("AssistDisclosure");
            lp.setFitInsetsTypes(0 /* types */);

            mWm.addView(mView, lp);
            mViewAdded = true;
        }
    }

    private void hide() {
        if (mViewAdded) {
            mWm.removeView(mView);
            mViewAdded = false;
        }
    }

    private Runnable mShowRunnable = new Runnable() {
        @Override
        public void run() {
            show();
        }
    };

    private class AssistDisclosureView extends View
            implements ValueAnimator.AnimatorUpdateListener {

        static final int FULL_ALPHA = 222; // 87%
        static final int ALPHA_IN_ANIMATION_DURATION = 400;
        static final int ALPHA_OUT_ANIMATION_DURATION = 300;


        private float mThickness;
        private float mShadowThickness;
        private final Paint mPaint = new Paint();
        private final Paint mShadowPaint = new Paint();

        private final ValueAnimator mAlphaOutAnimator;
        private final ValueAnimator mAlphaInAnimator;
        private final AnimatorSet mAnimator;

        private int mAlpha = 0;

        public AssistDisclosureView(Context context) {
            super(context);

            mAlphaInAnimator = ValueAnimator.ofInt(0, FULL_ALPHA)
                    .setDuration(ALPHA_IN_ANIMATION_DURATION);
            mAlphaInAnimator.addUpdateListener(this);
            mAlphaInAnimator.setInterpolator(Interpolators.CUSTOM_40_40);
            mAlphaOutAnimator = ValueAnimator.ofInt(FULL_ALPHA, 0).setDuration(
                    ALPHA_OUT_ANIMATION_DURATION);
            mAlphaOutAnimator.addUpdateListener(this);
            mAlphaOutAnimator.setInterpolator(Interpolators.CUSTOM_40_40);
            mAnimator = new AnimatorSet();
            mAnimator.play(mAlphaInAnimator).before(mAlphaOutAnimator);
            mAnimator.addListener(new AnimatorListenerAdapter() {
                boolean mCancelled;

                @Override
                public void onAnimationStart(Animator animation) {
                    mCancelled = false;
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    mCancelled = true;
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    if (!mCancelled) {
                        hide();
                    }
                }
            });

            PorterDuffXfermode srcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
            mPaint.setColor(Color.WHITE);
            mPaint.setXfermode(srcMode);
            mShadowPaint.setColor(Color.DKGRAY);
            mShadowPaint.setXfermode(srcMode);

            mThickness = getResources().getDimension(R.dimen.assist_disclosure_thickness);
            mShadowThickness = getResources().getDimension(
                    R.dimen.assist_disclosure_shadow_thickness);
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();

            startAnimation();
            sendAccessibilityEvent(AccessibilityEvent.TYPE_ASSIST_READING_CONTEXT);
        }

        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();

            mAnimator.cancel();
            mAlpha = 0;
        }

        private void startAnimation() {
            mAnimator.cancel();
            mAnimator.start();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            mPaint.setAlpha(mAlpha);
            mShadowPaint.setAlpha(mAlpha / 4);

            drawGeometry(canvas, mShadowPaint, mShadowThickness);
            drawGeometry(canvas, mPaint, 0);
        }

        private void drawGeometry(Canvas canvas, Paint paint, float padding) {
            final int width = getWidth();
            final int height = getHeight();
            float thickness = mThickness;

            // bottom
            drawBeam(canvas,
                    0,
                    height - thickness,
                    width,
                    height, paint, padding);

            // sides
            drawBeam(canvas,
                    0,
                    0,
                    thickness,
                    height - thickness, paint, padding);
            drawBeam(canvas,
                    width - thickness,
                    0,
                    width,
                    height - thickness, paint, padding);

            // top
            drawBeam(canvas,
                    thickness,
                    0,
                    width - thickness,
                    thickness, paint, padding);
        }

        private void drawBeam(Canvas canvas, float left, float top, float right, float bottom,
                Paint paint, float padding) {
            canvas.drawRect(left - padding,
                    top - padding,
                    right + padding,
                    bottom + padding,
                    paint);
        }

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            if (animation == mAlphaOutAnimator) {
                mAlpha = (int) mAlphaOutAnimator.getAnimatedValue();
            } else if (animation == mAlphaInAnimator) {
                mAlpha = (int) mAlphaInAnimator.getAnimatedValue();
            }
            invalidate();
        }
    }
}
