/*
 * 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 android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Configuration;
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.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;

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;

public class HardwareUiLayout extends LinearLayout 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 View mList;
    private View mSeparatedView;
    private int mOldHeight;
    private boolean mAnimating;
    private AnimatorSet mAnimation;
    private View mDivision;
    private boolean mHasOutsideTouch;
    private HardwareBgDrawable mListBackground;
    private HardwareBgDrawable mSeparatedViewBackground;
    private Animator mAnimator;
    private boolean mCollapse;
    private boolean mHasSeparatedButton;
    private int mEndPoint;
    private boolean mEdgeBleed;
    private boolean mRoundedDivider;
    private int mRotation = ROTATION_NONE;
    private boolean mRotatedBackground;
    private boolean mSwapOrientation = true;

    public HardwareUiLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        updateSettings();
    }

    @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 = getChildAt(0);
                mList.setBackground(mListBackground);
                mSeparatedView = getChildAt(1);
                mSeparatedView.setBackground(mSeparatedViewBackground);
                updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
                mOldHeight = mList.getMeasuredHeight();
                mList.addOnLayoutChangeListener(
                        (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
                                updatePosition());
                updateRotation();
            } else {
                return;
            }
        }
        int newHeight = mList.getMeasuredHeight();
        if (newHeight != mOldHeight) {
            animateChild(mOldHeight, newHeight);
        }
        post(() -> updatePosition());
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        updateRotation();
    }

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

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

    private void rotate(int from, int 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 (mHasSeparatedButton) {
            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);
            }
        }
    }

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

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

    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(mHasSeparatedButton);
        mSeparatedViewBackground.setRotatedBackground(mHasSeparatedButton);
        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();
    }

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

    public void setOutsideTouchListener(OnClickListener onClickListener) {
        mHasOutsideTouch = true;
        requestLayout();
        setOnClickListener(onClickListener);
        setClickable(true);
        setFocusable(true);
    }

    public void setCollapse() {
        mCollapse = true;
    }

    public void setHasSeparatedButton(boolean hasSeparatedButton) {
        mHasSeparatedButton = hasSeparatedButton;
    }

    public static HardwareUiLayout get(View v) {
        if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
        if (v.getParent() instanceof View) {
            return get((View) v.getParent());
        }
        return null;
    }

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