/*
 * Copyright (C) 2019 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;

import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.PopupWindow;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.CommandQueue;

import java.lang.ref.WeakReference;

/** Shows a restart-activity button when the foreground activity is in size compatibility mode. */
public class SizeCompatModeActivityController extends SystemUI implements CommandQueue.Callbacks {
    private static final String TAG = "SizeCompatMode";

    /** The showing buttons by display id. */
    private final SparseArray<RestartActivityButton> mActiveButtons = new SparseArray<>(1);
    /** Avoid creating display context frequently for non-default display. */
    private final SparseArray<WeakReference<Context>> mDisplayContextCache = new SparseArray<>(0);

    /** Only show once automatically in the process life. */
    private boolean mHasShownHint;

    public SizeCompatModeActivityController() {
        this(ActivityManagerWrapper.getInstance());
    }

    @VisibleForTesting
    SizeCompatModeActivityController(ActivityManagerWrapper am) {
        am.registerTaskStackListener(new TaskStackChangeListener() {
            @Override
            public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
                // Note the callback already runs on main thread.
                updateRestartButton(displayId, activityToken);
            }
        });
    }

    @Override
    public void start() {
        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
    }

    @Override
    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
            boolean showImeSwitcher) {
        RestartActivityButton button = mActiveButtons.get(displayId);
        if (button == null) {
            return;
        }
        boolean imeShown = (vis & InputMethodService.IME_VISIBLE) != 0;
        int newVisibility = imeShown ? View.GONE : View.VISIBLE;
        // Hide the button when input method is showing.
        if (button.getVisibility() != newVisibility) {
            button.setVisibility(newVisibility);
        }
    }

    @Override
    public void onDisplayRemoved(int displayId) {
        mDisplayContextCache.remove(displayId);
        removeRestartButton(displayId);
    }

    private void removeRestartButton(int displayId) {
        RestartActivityButton button = mActiveButtons.get(displayId);
        if (button != null) {
            button.remove();
            mActiveButtons.remove(displayId);
        }
    }

    private void updateRestartButton(int displayId, IBinder activityToken) {
        if (activityToken == null) {
            // Null token means the current foreground activity is not in size compatibility mode.
            removeRestartButton(displayId);
            return;
        }

        RestartActivityButton restartButton = mActiveButtons.get(displayId);
        if (restartButton != null) {
            restartButton.updateLastTargetActivity(activityToken);
            return;
        }

        Context context = getOrCreateDisplayContext(displayId);
        if (context == null) {
            Log.i(TAG, "Cannot get context for display " + displayId);
            return;
        }

        restartButton = createRestartButton(context);
        restartButton.updateLastTargetActivity(activityToken);
        restartButton.show();
        mActiveButtons.append(displayId, restartButton);
    }

    @VisibleForTesting
    RestartActivityButton createRestartButton(Context context) {
        RestartActivityButton button = new RestartActivityButton(context, mHasShownHint);
        mHasShownHint = true;
        return button;
    }

    private Context getOrCreateDisplayContext(int displayId) {
        if (displayId == Display.DEFAULT_DISPLAY) {
            return mContext;
        }
        Context context = null;
        WeakReference<Context> ref = mDisplayContextCache.get(displayId);
        if (ref != null) {
            context = ref.get();
        }
        if (context == null) {
            Display display = mContext.getSystemService(DisplayManager.class).getDisplay(displayId);
            if (display != null) {
                context = mContext.createDisplayContext(display);
                mDisplayContextCache.put(displayId, new WeakReference<Context>(context));
            }
        }
        return context;
    }

    @VisibleForTesting
    static class RestartActivityButton extends ImageButton implements View.OnClickListener,
            View.OnLongClickListener {

        final WindowManager.LayoutParams mWinParams;
        final boolean mShouldShowHint;
        IBinder mLastActivityToken;

        final int mPopupOffsetX;
        final int mPopupOffsetY;
        PopupWindow mShowingHint;

        RestartActivityButton(Context context, boolean hasShownHint) {
            super(context);
            mShouldShowHint = !hasShownHint;
            Drawable drawable = context.getDrawable(R.drawable.btn_restart);
            setImageDrawable(drawable);
            setContentDescription(context.getString(R.string.restart_button_description));

            int drawableW = drawable.getIntrinsicWidth();
            int drawableH = drawable.getIntrinsicHeight();
            mPopupOffsetX = drawableW / 2;
            mPopupOffsetY = drawableH * 2;

            ColorStateList color = ColorStateList.valueOf(Color.LTGRAY);
            GradientDrawable mask = new GradientDrawable();
            mask.setShape(GradientDrawable.OVAL);
            mask.setColor(color);
            setBackground(new RippleDrawable(color, null /* content */, mask));
            setOnClickListener(this);
            setOnLongClickListener(this);

            mWinParams = new WindowManager.LayoutParams();
            mWinParams.gravity = getGravity(getResources().getConfiguration().getLayoutDirection());
            mWinParams.width = drawableW * 2;
            mWinParams.height = drawableH * 2;
            mWinParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            mWinParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            mWinParams.format = PixelFormat.TRANSLUCENT;
            mWinParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
            mWinParams.setTitle(SizeCompatModeActivityController.class.getSimpleName()
                    + context.getDisplayId());
        }

        void updateLastTargetActivity(IBinder activityToken) {
            mLastActivityToken = activityToken;
        }

        void show() {
            getContext().getSystemService(WindowManager.class).addView(this, mWinParams);
        }

        void remove() {
            getContext().getSystemService(WindowManager.class).removeViewImmediate(this);
        }

        @Override
        public void onClick(View v) {
            try {
                ActivityTaskManager.getService().restartActivityProcessIfVisible(
                        mLastActivityToken);
            } catch (RemoteException e) {
                Log.w(TAG, "Unable to restart activity", e);
            }
        }

        @Override
        public boolean onLongClick(View v) {
            showHint();
            return true;
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            if (mShouldShowHint) {
                showHint();
            }
        }

        @Override
        public void setLayoutDirection(int layoutDirection) {
            int gravity = getGravity(layoutDirection);
            if (mWinParams.gravity != gravity) {
                mWinParams.gravity = gravity;
                if (mShowingHint != null) {
                    mShowingHint.dismiss();
                    showHint();
                }
                getContext().getSystemService(WindowManager.class).updateViewLayout(this,
                        mWinParams);
            }
            super.setLayoutDirection(layoutDirection);
        }

        void showHint() {
            if (mShowingHint != null) {
                return;
            }

            View popupView = LayoutInflater.from(getContext()).inflate(
                    R.layout.size_compat_mode_hint, null /* root */);
            PopupWindow popupWindow = new PopupWindow(popupView,
                    LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            popupWindow.setElevation(getResources().getDimension(R.dimen.bubble_elevation));
            popupWindow.setAnimationStyle(android.R.style.Animation_InputMethod);
            popupWindow.setClippingEnabled(false);
            popupWindow.setOnDismissListener(() -> mShowingHint = null);
            mShowingHint = popupWindow;

            Button gotItButton = popupView.findViewById(R.id.got_it);
            gotItButton.setBackground(new RippleDrawable(ColorStateList.valueOf(Color.LTGRAY),
                    null /* content */, null /* mask */));
            gotItButton.setOnClickListener(view -> popupWindow.dismiss());
            popupWindow.showAtLocation(this, mWinParams.gravity, mPopupOffsetX, mPopupOffsetY);
        }

        private static int getGravity(int layoutDirection) {
            return Gravity.BOTTOM
                    | (layoutDirection == View.LAYOUT_DIRECTION_RTL ? Gravity.START : Gravity.END);
        }
    }
}
