/*
 * 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.settings.accessibility;

import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;

import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.IntDef;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;

import com.android.settings.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Utility class for creating the dialog that guides users for gesture navigation for
 * accessibility services.
 */
public class AccessibilityGestureNavigationTutorial {

    /** IntDef enum for dialog type. */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            DialogType.LAUNCH_SERVICE_BY_ACCESSIBILITY_BUTTON,
            DialogType.LAUNCH_SERVICE_BY_GESTURE_NAVIGATION,
            DialogType.GESTURE_NAVIGATION_SETTINGS,
    })

    private @interface DialogType {
        int LAUNCH_SERVICE_BY_ACCESSIBILITY_BUTTON = 0;
        int LAUNCH_SERVICE_BY_GESTURE_NAVIGATION = 1;
        int GESTURE_NAVIGATION_SETTINGS = 2;
    }

    private static final DialogInterface.OnClickListener mOnClickListener =
            (DialogInterface dialog, int which) -> dialog.dismiss();

    public static void showGestureNavigationSettingsTutorialDialog(Context context,
            DialogInterface.OnDismissListener dismissListener) {
        final AlertDialog alertDialog = new AlertDialog.Builder(context)
                .setView(createTutorialDialogContentView(context,
                        DialogType.GESTURE_NAVIGATION_SETTINGS))
                .setNegativeButton(R.string.accessibility_tutorial_dialog_button, mOnClickListener)
                .setOnDismissListener(dismissListener)
                .create();

        alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();
    }

    static AlertDialog showAccessibilityButtonTutorialDialog(Context context) {
        final AlertDialog alertDialog = createDialog(context,
                DialogType.LAUNCH_SERVICE_BY_ACCESSIBILITY_BUTTON);

        if (!isGestureNavigateEnabled(context)) {
            updateMessageWithIcon(context, alertDialog);
        }

        return alertDialog;
    }

    static AlertDialog showGestureNavigationTutorialDialog(Context context) {
        return createDialog(context, DialogType.LAUNCH_SERVICE_BY_GESTURE_NAVIGATION);
    }

    /**
     * Get a content View for a dialog to confirm that they want to enable a service.
     *
     * @param context    A valid context
     * @param dialogType The type of tutorial dialog
     * @return A content view suitable for viewing
     */
    private static View createTutorialDialogContentView(Context context, int dialogType) {
        final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

        View content = null;

        switch (dialogType) {
            case DialogType.LAUNCH_SERVICE_BY_ACCESSIBILITY_BUTTON:
                content = inflater.inflate(
                        R.layout.tutorial_dialog_launch_service_by_accessibility_button, null);
                break;
            case DialogType.LAUNCH_SERVICE_BY_GESTURE_NAVIGATION:
                content = inflater.inflate(
                        R.layout.tutorial_dialog_launch_service_by_gesture_navigation, null);
                final TextureView gestureTutorialVideo = content.findViewById(
                        R.id.gesture_tutorial_video);
                final TextView gestureTutorialMessage = content.findViewById(
                        R.id.gesture_tutorial_message);
                VideoPlayer.create(context, isTouchExploreOn(context)
                                ? R.raw.illustration_accessibility_gesture_three_finger
                                : R.raw.illustration_accessibility_gesture_two_finger,
                        gestureTutorialVideo);
                gestureTutorialMessage.setText(isTouchExploreOn(context)
                        ? R.string.accessibility_tutorial_dialog_message_gesture_with_talkback
                        : R.string.accessibility_tutorial_dialog_message_gesture_without_talkback);
                break;
            case DialogType.GESTURE_NAVIGATION_SETTINGS:
                content = inflater.inflate(
                        R.layout.tutorial_dialog_launch_by_gesture_navigation_settings, null);
                final TextureView gestureSettingsTutorialVideo = content.findViewById(
                        R.id.gesture_tutorial_video);
                final TextView gestureSettingsTutorialMessage = content.findViewById(
                        R.id.gesture_tutorial_message);
                VideoPlayer.create(context, isTouchExploreOn(context)
                                ? R.raw.illustration_accessibility_gesture_three_finger
                                : R.raw.illustration_accessibility_gesture_two_finger,
                        gestureSettingsTutorialVideo);
                gestureSettingsTutorialMessage.setText(isTouchExploreOn(context)
                        ?
                        R.string.accessibility_tutorial_dialog_message_gesture_settings_with_talkback
                        : R.string.accessibility_tutorial_dialog_message_gesture_settings_without_talkback);
                break;
        }

        return content;
    }

    private static AlertDialog createDialog(Context context, int dialogType) {
        final AlertDialog alertDialog = new AlertDialog.Builder(context)
                .setView(createTutorialDialogContentView(context, dialogType))
                .setNegativeButton(R.string.accessibility_tutorial_dialog_button, mOnClickListener)
                .create();

        alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        alertDialog.setCanceledOnTouchOutside(false);
        alertDialog.show();

        return alertDialog;
    }

    private static void updateMessageWithIcon(Context context, AlertDialog alertDialog) {
        final TextView gestureTutorialMessage = alertDialog.findViewById(
                R.id.button_tutorial_message);

        // Get the textView line height to update [icon] size. Must be called after show()
        final int lineHeight = gestureTutorialMessage.getLineHeight();
        gestureTutorialMessage.setText(getMessageStringWithIcon(context, lineHeight));
    }

    private static SpannableString getMessageStringWithIcon(Context context, int lineHeight) {
        final String messageString = context
                .getString(R.string.accessibility_tutorial_dialog_message_button);
        final SpannableString spannableMessage = SpannableString.valueOf(messageString);

        // Icon
        final int indexIconStart = messageString.indexOf("%s");
        final int indexIconEnd = indexIconStart + 2;
        final Drawable icon = context.getDrawable(R.drawable.ic_accessibility_new);
        icon.setTint(getThemeAttrColor(context, android.R.attr.textColorPrimary));
        icon.setBounds(0, 0, lineHeight, lineHeight);
        spannableMessage.setSpan(
                new ImageSpan(icon), indexIconStart, indexIconEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        return spannableMessage;
    }

    /** Returns the color associated with the specified attribute in the context's theme. */
    @ColorInt
    private static int getThemeAttrColor(final Context context, final int attributeColor) {
        final int colorResId = getAttrResourceId(context, attributeColor);
        return ContextCompat.getColor(context, colorResId);
    }

    /** Returns the identifier of the resolved resource assigned to the given attribute. */
    private static int getAttrResourceId(final Context context, final int attributeColor) {
        final int[] attrs = {attributeColor};
        final TypedArray typedArray = context.obtainStyledAttributes(attrs);
        final int colorResId = typedArray.getResourceId(0, 0);
        typedArray.recycle();
        return colorResId;
    }

    private static boolean isGestureNavigateEnabled(Context context) {
        return context.getResources().getInteger(
                com.android.internal.R.integer.config_navBarInteractionMode)
                == NAV_BAR_MODE_GESTURAL;
    }

    private static boolean isTouchExploreOn(Context context) {
        return ((AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE))
                .isTouchExplorationEnabled();
    }
}
