/*
 * Copyright (C) 2016 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.internal.view;

import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.Slog;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.widget.TextView;

public class TooltipPopup {
    private static final String TAG = "TooltipPopup";

    private final Context mContext;

    private final View mContentView;
    private final TextView mMessageView;

    private final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams();
    private final Rect mTmpDisplayFrame = new Rect();
    private final int[] mTmpAnchorPos = new int[2];
    private final int[] mTmpAppPos = new int[2];

    public TooltipPopup(Context context) {
        mContext = context;

        mContentView = LayoutInflater.from(mContext).inflate(
                com.android.internal.R.layout.tooltip, null);
        mMessageView = (TextView) mContentView.findViewById(
                com.android.internal.R.id.message);

        mLayoutParams.setTitle(
                mContext.getString(com.android.internal.R.string.tooltip_popup_title));
        mLayoutParams.packageName = mContext.getOpPackageName();
        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
        mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        mLayoutParams.format = PixelFormat.TRANSLUCENT;
        mLayoutParams.windowAnimations = com.android.internal.R.style.Animation_Tooltip;
        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
    }

    public void show(View anchorView, int anchorX, int anchorY, boolean fromTouch,
            CharSequence tooltipText) {
        if (isShowing()) {
            hide();
        }

        mMessageView.setText(tooltipText);

        computePosition(anchorView, anchorX, anchorY, fromTouch, mLayoutParams);

        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.addView(mContentView, mLayoutParams);
    }

    public void hide() {
        if (!isShowing()) {
            return;
        }

        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.removeView(mContentView);
    }

    public View getContentView() {
        return mContentView;
    }

    public boolean isShowing() {
        return mContentView.getParent() != null;
    }

    private void computePosition(View anchorView, int anchorX, int anchorY, boolean fromTouch,
            WindowManager.LayoutParams outParams) {
        outParams.token = anchorView.getWindowToken();

        final int tooltipPreciseAnchorThreshold = mContext.getResources().getDimensionPixelOffset(
                com.android.internal.R.dimen.tooltip_precise_anchor_threshold);

        final int offsetX;
        if (anchorView.getWidth() >= tooltipPreciseAnchorThreshold) {
            // Wide view. Align the tooltip horizontally to the precise X position.
            offsetX = anchorX;
        } else {
            // Otherwise anchor the tooltip to the view center.
            offsetX = anchorView.getWidth() / 2;  // Center on the view horizontally.
        }

        final int offsetBelow;
        final int offsetAbove;
        if (anchorView.getHeight() >= tooltipPreciseAnchorThreshold) {
            // Tall view. Align the tooltip vertically to the precise Y position.
            final int offsetExtra = mContext.getResources().getDimensionPixelOffset(
                    com.android.internal.R.dimen.tooltip_precise_anchor_extra_offset);
            offsetBelow = anchorY + offsetExtra;
            offsetAbove = anchorY - offsetExtra;
        } else {
            // Otherwise anchor the tooltip to the view center.
            offsetBelow = anchorView.getHeight();  // Place below the view in most cases.
            offsetAbove = 0;  // Place above the view if the tooltip does not fit below.
        }

        outParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;

        final int tooltipOffset = mContext.getResources().getDimensionPixelOffset(
                fromTouch ? com.android.internal.R.dimen.tooltip_y_offset_touch
                        : com.android.internal.R.dimen.tooltip_y_offset_non_touch);

        // Find the main app window. The popup window will be positioned relative to it.
        final View appView = WindowManagerGlobal.getInstance().getWindowView(
                anchorView.getApplicationWindowToken());
        if (appView == null) {
            Slog.e(TAG, "Cannot find app view");
            return;
        }
        appView.getWindowVisibleDisplayFrame(mTmpDisplayFrame);
        appView.getLocationOnScreen(mTmpAppPos);

        anchorView.getLocationOnScreen(mTmpAnchorPos);
        mTmpAnchorPos[0] -= mTmpAppPos[0];
        mTmpAnchorPos[1] -= mTmpAppPos[1];
        // mTmpAnchorPos is now relative to the main app window.

        outParams.x = mTmpAnchorPos[0] + offsetX - mTmpDisplayFrame.width() / 2;

        final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        mContentView.measure(spec, spec);
        final int tooltipHeight = mContentView.getMeasuredHeight();

        final int yAbove = mTmpAnchorPos[1] + offsetAbove - tooltipOffset - tooltipHeight;
        final int yBelow = mTmpAnchorPos[1] + offsetBelow + tooltipOffset;
        if (fromTouch) {
            if (yAbove >= 0) {
                outParams.y = yAbove;
            } else {
                outParams.y = yBelow;
            }
        } else {
            if (yBelow + tooltipHeight <= mTmpDisplayFrame.height()) {
                outParams.y = yBelow;
            } else {
                outParams.y = yAbove;
            }
        }
    }
}
