/*
 * Copyright (C) 2017 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 static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;

import com.android.systemui.globalactions.GlobalActionsDialog;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;

import java.util.ArrayList;

/**
 * Layout for placing two containers at a specific physical position on the device, relative to the
 * device's hardware, regardless of screen rotation.
 */
public class HardwareUiLayout extends MultiListLayout implements Tunable {

    private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
    private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
    private final int[] mTmp2 = new int[2];
    private ViewGroup mList;
    private ViewGroup mSeparatedView;
    private int mOldHeight;
    private boolean mAnimating;
    private AnimatorSet mAnimation;
    private View mDivision;
    private HardwareBgDrawable mListBackground;
    private HardwareBgDrawable mSeparatedViewBackground;
    private Animator mAnimator;
    private boolean mCollapse;
    private int mEndPoint;
    private boolean mEdgeBleed;
    private boolean mRoundedDivider;
    private boolean mRotatedBackground;
    private boolean mSwapOrientation = true;

    public HardwareUiLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // Manually re-initialize mRotation to portrait-mode, since this view must always
        // be constructed in portrait mode and rotated into the correct initial position.
        mRotation = ROTATION_NONE;
        updateSettings();
    }

    @Override
    protected ViewGroup getSeparatedView() {
        return findViewById(com.android.systemui.R.id.separated_button);
    }

    @Override
    protected ViewGroup getListView() {
        return findViewById(android.R.id.list);
    }

    @Override
    public void removeAllItems() {
        if (mList != null) {
            mList.removeAllViews();
        }
        if (mSeparatedView != null) {
            mSeparatedView.removeAllViews();
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        updateSettings();
        Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
        getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
        Dependency.get(TunerService.class).removeTunable(this);
    }

    @Override
    public void onTuningChanged(String key, String newValue) {
        updateSettings();
    }

    private void updateSettings() {
        mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
                EDGE_BLEED, 0) != 0;
        mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
                ROUNDED_DIVIDER, 0) != 0;
        updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
        mListBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
        mSeparatedViewBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed,
                getContext());
        if (mList != null) {
            mList.setBackground(mListBackground);
            mSeparatedView.setBackground(mSeparatedViewBackground);
            requestLayout();
        }
    }

    private void updateEdgeMargin(int edge) {
        if (mList != null) {
            MarginLayoutParams params = (MarginLayoutParams) mList.getLayoutParams();
            if (mRotation == ROTATION_LANDSCAPE) {
                params.topMargin = edge;
            } else if (mRotation == ROTATION_SEASCAPE) {
                params.bottomMargin = edge;
            } else {
                params.rightMargin = edge;
            }
            mList.setLayoutParams(params);
        }

        if (mSeparatedView != null) {
            MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
            if (mRotation == ROTATION_LANDSCAPE) {
                params.topMargin = edge;
            } else if (mRotation == ROTATION_SEASCAPE) {
                params.bottomMargin = edge;
            } else {
                params.rightMargin = edge;
            }
            mSeparatedView.setLayoutParams(params);
        }
    }

    private int getEdgePadding() {
        return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (mList == null) {
            if (getChildCount() != 0) {
                mList = getListView();
                mList.setBackground(mListBackground);
                mSeparatedView = getSeparatedView();
                mSeparatedView.setBackground(mSeparatedViewBackground);
                updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
                mOldHeight = mList.getMeasuredHeight();

                // Must be called to initialize view rotation correctly.
                // Requires LayoutParams, hence why this isn't called during the constructor.
                updateRotation();
            } else {
                return;
            }
        }
        int newHeight = mList.getMeasuredHeight();
        if (newHeight != mOldHeight) {
            animateChild(mOldHeight, newHeight);
        }

        post(() -> updatePaddingAndGravityIfTooTall());
        post(() -> updatePosition());
    }

    public void setSwapOrientation(boolean swapOrientation) {
        mSwapOrientation = swapOrientation;
    }

    private void updateRotation() {
        int rotation = RotationUtils.getRotation(getContext());
        if (rotation != mRotation) {
            rotate(mRotation, rotation);
            mRotation = rotation;
        }
    }

    /**
     *  Requires LayoutParams to be set to work correctly, and therefore must be run after after
     *  the HardwareUILayout has been added to the view hierarchy.
     */
    protected void rotate(int from, int to) {
        super.rotate(from, to);
        if (from != ROTATION_NONE && to != ROTATION_NONE) {
            // Rather than handling this confusing case, just do 2 rotations.
            rotate(from, ROTATION_NONE);
            rotate(ROTATION_NONE, to);
            return;
        }
        if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) {
            rotateRight();
        } else {
            rotateLeft();
        }
        if (mSeparated) {
            if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) {
                // Separated view has top margin, so seascape separated view need special rotation,
                // not a full left or right rotation.
                swapLeftAndTop(mSeparatedView);
            } else if (from == ROTATION_LANDSCAPE) {
                rotateRight(mSeparatedView);
            } else {
                rotateLeft(mSeparatedView);
            }
        }
        if (to != ROTATION_NONE) {
            if (mList instanceof LinearLayout) {
                mRotatedBackground = true;
                mListBackground.setRotatedBackground(true);
                mSeparatedViewBackground.setRotatedBackground(true);
                LinearLayout linearLayout = (LinearLayout) mList;
                if (mSwapOrientation) {
                    linearLayout.setOrientation(LinearLayout.HORIZONTAL);
                    setOrientation(LinearLayout.HORIZONTAL);
                }
                swapDimens(mList);
                swapDimens(mSeparatedView);
            }
        } else {
            if (mList instanceof LinearLayout) {
                mRotatedBackground = false;
                mListBackground.setRotatedBackground(false);
                mSeparatedViewBackground.setRotatedBackground(false);
                LinearLayout linearLayout = (LinearLayout) mList;
                if (mSwapOrientation) {
                    linearLayout.setOrientation(LinearLayout.VERTICAL);
                    setOrientation(LinearLayout.VERTICAL);
                }
                swapDimens(mList);
                swapDimens(mSeparatedView);
            }
        }
    }

    @Override
    public void onUpdateList() {
        removeAllItems();
        ArrayList<GlobalActionsDialog.Action> separatedActions =
                mAdapter.getSeparatedItems(mSeparated);
        ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems(mSeparated);

        for (int i = 0; i < mAdapter.getCount(); i++) {
            Object action = mAdapter.getItem(i);
            int separatedIndex = separatedActions.indexOf(action);
            ViewGroup parent;
            if (separatedIndex != -1) {
                parent = getSeparatedView();
            } else {
                int listIndex = listActions.indexOf(action);
                parent = getListView();
            }
            View v = mAdapter.getView(i, null, parent);
            final int pos = i;
            v.setOnClickListener(view -> mAdapter.onClickItem(pos));
            v.setOnLongClickListener(view -> mAdapter.onLongClickItem(pos));
            parent.addView(v);
        }
    }

    private void rotateRight() {
        rotateRight(this);
        rotateRight(mList);
        swapDimens(this);

        LayoutParams p = (LayoutParams) mList.getLayoutParams();
        p.gravity = rotateGravityRight(p.gravity);
        mList.setLayoutParams(p);

        LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
        separatedViewLayoutParams.gravity = rotateGravityRight(separatedViewLayoutParams.gravity);
        mSeparatedView.setLayoutParams(separatedViewLayoutParams);

        setGravity(rotateGravityRight(getGravity()));
    }

    private void swapDimens(View v) {
        ViewGroup.LayoutParams params = v.getLayoutParams();
        int h = params.width;
        params.width = params.height;
        params.height = h;
        v.setLayoutParams(params);
    }

    private int rotateGravityRight(int gravity) {
        int retGravity = 0;
        int layoutDirection = getLayoutDirection();
        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
            case Gravity.CENTER_HORIZONTAL:
                retGravity |= Gravity.CENTER_VERTICAL;
                break;
            case Gravity.RIGHT:
                retGravity |= Gravity.BOTTOM;
                break;
            case Gravity.LEFT:
            default:
                retGravity |= Gravity.TOP;
                break;
        }

        switch (verticalGravity) {
            case Gravity.CENTER_VERTICAL:
                retGravity |= Gravity.CENTER_HORIZONTAL;
                break;
            case Gravity.BOTTOM:
                retGravity |= Gravity.LEFT;
                break;
            case Gravity.TOP:
            default:
                retGravity |= Gravity.RIGHT;
                break;
        }
        return retGravity;
    }

    private void rotateLeft() {
        rotateLeft(this);
        rotateLeft(mList);
        swapDimens(this);

        LayoutParams p = (LayoutParams) mList.getLayoutParams();
        p.gravity = rotateGravityLeft(p.gravity);
        mList.setLayoutParams(p);

        LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
        separatedViewLayoutParams.gravity = rotateGravityLeft(separatedViewLayoutParams.gravity);
        mSeparatedView.setLayoutParams(separatedViewLayoutParams);

        setGravity(rotateGravityLeft(getGravity()));
    }

    private int rotateGravityLeft(int gravity) {
        if (gravity == -1) {
            gravity = Gravity.TOP | Gravity.START;
        }
        int retGravity = 0;
        int layoutDirection = getLayoutDirection();
        final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
        final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;

        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
            case Gravity.CENTER_HORIZONTAL:
                retGravity |= Gravity.CENTER_VERTICAL;
                break;
            case Gravity.RIGHT:
                retGravity |= Gravity.TOP;
                break;
            case Gravity.LEFT:
            default:
                retGravity |= Gravity.BOTTOM;
                break;
        }

        switch (verticalGravity) {
            case Gravity.CENTER_VERTICAL:
                retGravity |= Gravity.CENTER_HORIZONTAL;
                break;
            case Gravity.BOTTOM:
                retGravity |= Gravity.RIGHT;
                break;
            case Gravity.TOP:
            default:
                retGravity |= Gravity.LEFT;
                break;
        }
        return retGravity;
    }

    private void rotateLeft(View v) {
        v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
                v.getPaddingLeft());
        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
        params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
                params.leftMargin);
        v.setLayoutParams(params);
    }

    private void rotateRight(View v) {
        v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
                v.getPaddingRight());
        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
        params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
                params.rightMargin);
        v.setLayoutParams(params);
    }

    private void swapLeftAndTop(View v) {
        v.setPadding(v.getPaddingTop(), v.getPaddingLeft(), v.getPaddingBottom(),
                v.getPaddingRight());
        MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
        params.setMargins(params.topMargin, params.leftMargin, params.bottomMargin,
                params.rightMargin);
        v.setLayoutParams(params);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        post(() -> updatePosition());
    }

    private void animateChild(int oldHeight, int newHeight) {
        if (true) return;
        if (mAnimating) {
            mAnimation.cancel();
        }
        mAnimating = true;
        mAnimation = new AnimatorSet();
        mAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mAnimating = false;
            }
        });
        int fromTop = mList.getTop();
        int fromBottom = mList.getBottom();
        int toTop = fromTop - ((newHeight - oldHeight) / 2);
        int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
        ObjectAnimator top = ObjectAnimator.ofInt(mList, "top", fromTop, toTop);
        top.addUpdateListener(animation -> mListBackground.invalidateSelf());
        mAnimation.playTogether(top,
                ObjectAnimator.ofInt(mList, "bottom", fromBottom, toBottom));
    }

    public void setDivisionView(View v) {
        mDivision = v;
        if (mDivision != null) {
            mDivision.addOnLayoutChangeListener(
                    (v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
                            updatePosition());
        }
        updatePosition();
    }

    private void updatePosition() {
        if (mList == null) return;
        // If got separated button, setRotatedBackground to false,
        // all items won't get white background.
        mListBackground.setRotatedBackground(mSeparated);
        mSeparatedViewBackground.setRotatedBackground(mSeparated);
        if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
            int index = mRotatedBackground ? 0 : 1;
            mDivision.getLocationOnScreen(mTmp2);
            float trans = mRotatedBackground ? mDivision.getTranslationX()
                    : mDivision.getTranslationY();
            int viewTop = (int) (mTmp2[index] + trans);
            mList.getLocationOnScreen(mTmp2);
            viewTop -= mTmp2[index];
            setCutPoint(viewTop);
        } else {
            setCutPoint(mList.getMeasuredHeight());
        }
    }

    private void setCutPoint(int point) {
        int curPoint = mListBackground.getCutPoint();
        if (curPoint == point) return;
        if (getAlpha() == 0 || curPoint == 0) {
            mListBackground.setCutPoint(point);
            return;
        }
        if (mAnimator != null) {
            if (mEndPoint == point) {
                return;
            }
            mAnimator.cancel();
        }
        mEndPoint = point;
        mAnimator = ObjectAnimator.ofInt(mListBackground, "cutPoint", curPoint, point);
        if (mCollapse) {
            mAnimator.setStartDelay(300);
            mCollapse = false;
        }
        mAnimator.start();
    }

    // If current power menu height larger then screen height, remove padding to break power menu
    // alignment and set menu center vertical within the screen.
    private void updatePaddingAndGravityIfTooTall() {
        int defaultTopPadding;
        int viewsTotalHeight;
        int separatedViewTopMargin;
        int screenHeight;
        int totalHeight;
        int targetGravity;
        MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
        switch (RotationUtils.getRotation(getContext())) {
            case RotationUtils.ROTATION_LANDSCAPE:
                defaultTopPadding = getPaddingLeft();
                viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
                separatedViewTopMargin = mSeparated ? params.leftMargin : 0;
                screenHeight = getMeasuredWidth();
                targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
                break;
            case RotationUtils.ROTATION_SEASCAPE:
                defaultTopPadding = getPaddingRight();
                viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
                separatedViewTopMargin = mSeparated ? params.leftMargin : 0;
                screenHeight = getMeasuredWidth();
                targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
                break;
            default: // Portrait
                defaultTopPadding = getPaddingTop();
                viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight();
                separatedViewTopMargin = mSeparated ? params.topMargin : 0;
                screenHeight = getMeasuredHeight();
                targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT;
                break;
        }
        totalHeight = defaultTopPadding + viewsTotalHeight + separatedViewTopMargin;
        if (totalHeight >= screenHeight) {
            setPadding(0, 0, 0, 0);
            setGravity(targetGravity);
        }
    }

    @Override
    public ViewOutlineProvider getOutlineProvider() {
        return super.getOutlineProvider();
    }

    public void setCollapse() {
        mCollapse = true;
    }

    private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
        if (mHasOutsideTouch || (mList == null)) {
            inoutInfo.setTouchableInsets(
                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
            return;
        }
        inoutInfo.setTouchableInsets(
                ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
        inoutInfo.contentInsets.set(mList.getLeft(), mList.getTop(),
                0, getBottom() - mList.getBottom());
    };
}