/*
 * 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.statusbar.phone;

import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.VisibleForTesting;

import java.util.ArrayList;
import java.util.Comparator;

/**
 * Redirects touches that aren't handled by any child view to the nearest
 * clickable child. Only takes effect on <sw600dp.
 */
public class NearestTouchFrame extends FrameLayout {

    private final ArrayList<View> mClickableChildren = new ArrayList<>();
    private final boolean mIsActive;
    private final int[] mTmpInt = new int[2];
    private final int[] mOffset = new int[2];
    private View mTouchingChild;

    public NearestTouchFrame(Context context, AttributeSet attrs) {
        this(context, attrs, context.getResources().getConfiguration());
    }

    @VisibleForTesting
    NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
        super(context, attrs);
        mIsActive = c.smallestScreenWidthDp < 600;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mClickableChildren.clear();
        addClickableChildren(this);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        getLocationInWindow(mOffset);
    }

    private void addClickableChildren(ViewGroup group) {
        final int N = group.getChildCount();
        for (int i = 0; i < N; i++) {
            View child = group.getChildAt(i);
            if (child.isClickable()) {
                mClickableChildren.add(child);
            } else if (child instanceof ViewGroup) {
                addClickableChildren((ViewGroup) child);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mIsActive) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mTouchingChild = findNearestChild(event);
            }
            if (mTouchingChild != null) {
                event.offsetLocation(mTouchingChild.getWidth() / 2 - event.getX(),
                        mTouchingChild.getHeight() / 2 - event.getY());
                return mTouchingChild.getVisibility() == VISIBLE
                        && mTouchingChild.dispatchTouchEvent(event);
            }
        }
        return super.onTouchEvent(event);
    }

    private View findNearestChild(MotionEvent event) {
        if (mClickableChildren.isEmpty()) {
            return null;
        }
        return mClickableChildren
                .stream()
                .filter(View::isAttachedToWindow)
                .map(v -> new Pair<>(distance(v, event), v))
                .min(Comparator.comparingInt(f -> f.first))
                .map(data -> data.second)
                .orElse(null);
    }

    private int distance(View v, MotionEvent event) {
        v.getLocationInWindow(mTmpInt);
        int left = mTmpInt[0] - mOffset[0];
        int top = mTmpInt[1] - mOffset[1];
        int right = left + v.getWidth();
        int bottom = top + v.getHeight();

        int x = Math.min(Math.abs(left - (int) event.getX()),
                Math.abs((int) event.getX() - right));
        int y = Math.min(Math.abs(top - (int) event.getY()),
                Math.abs((int) event.getY() - bottom));

        return Math.max(x, y);
    }
}
