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

import android.content.Context;
import android.os.Bundle;
import android.view.View;

import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.settings.R;

/**
 * Add accessibility actions to the drag-and-drop locale list
 *
 * <p>Dragging is not supported neither by TalkBack or the accessibility
 * framework at the moment. So we need custom actions to be able
 * to change the order of the locales.</p>
 *
 * <p>Also, the remove functionality is difficult to discover and use
 * with TalkBack only, so we are also adding a "remove" action.</p>
 *
 * <p>It only removes one locale at the time, but most users don't
 * really add many locales "by mistake", so there is no real need
 * to delete a lot of locales at once.</p>
 */
public class LocaleLinearLayoutManager extends LinearLayoutManager {
    private final LocaleDragAndDropAdapter mAdapter;
    private final Context mContext;

    private final AccessibilityNodeInfoCompat.AccessibilityActionCompat mActionMoveUp;
    private final AccessibilityNodeInfoCompat.AccessibilityActionCompat mActionMoveDown;
    private final AccessibilityNodeInfoCompat.AccessibilityActionCompat mActionMoveTop;
    private final AccessibilityNodeInfoCompat.AccessibilityActionCompat mActionMoveBottom;
    private final AccessibilityNodeInfoCompat.AccessibilityActionCompat mActionRemove;

    public LocaleLinearLayoutManager(Context context, LocaleDragAndDropAdapter adapter) {
        super(context);
        this.mContext = context;
        this.mAdapter = adapter;

        this.mActionMoveUp = new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                R.id.action_drag_move_up,
                mContext.getString(R.string.action_drag_label_move_up));
        this.mActionMoveDown = new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                R.id.action_drag_move_down,
                mContext.getString(R.string.action_drag_label_move_down));
        this.mActionMoveTop = new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                R.id.action_drag_move_top,
                mContext.getString(R.string.action_drag_label_move_top));
        this.mActionMoveBottom = new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                R.id.action_drag_move_bottom,
                mContext.getString(R.string.action_drag_label_move_bottom));
        this.mActionRemove = new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
                R.id.action_drag_remove,
                mContext.getString(R.string.action_drag_label_remove));
    }

    @Override
    public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
            RecyclerView.State state, View host, AccessibilityNodeInfoCompat info) {

        super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info);

        final int itemCount = this.getItemCount();
        final int position = this.getPosition(host);
        final LocaleDragCell dragCell = (LocaleDragCell) host;

        // We want the description to be something not localizable, so that any TTS engine for
        // any language can handle it. And we want the position to be part of it.
        // So we use something like "2, French (France)"
        final String description =
                (position + 1) + ", " + dragCell.getCheckbox().getContentDescription();
        info.setContentDescription(description);

        if (mAdapter.isRemoveMode()) { // We don't move things around in remove mode
            return;
        }

        // The order in which we add the actions is important for the circular selection menu.
        // With the current order the "up" action will be (more or less) up, and "down" more
        // or less down ("more or less" because we have 5 actions)
        if (position > 0) { // it is not the first one
            info.addAction(mActionMoveUp);
            info.addAction(mActionMoveTop);
        }
        if (position + 1 < itemCount) { // it is not the last one
            info.addAction(mActionMoveDown);
            info.addAction(mActionMoveBottom);
        }
        if (itemCount > 1) {
            info.addAction(mActionRemove);
        }
    }

    @Override
    public boolean performAccessibilityActionForItem(RecyclerView.Recycler recycler,
            RecyclerView.State state, View host, int action, Bundle args) {

        final int itemCount = this.getItemCount();
        final int position = this.getPosition(host);
        boolean result = false;

        if (action == R.id.action_drag_move_up) {
            if (position > 0) {
                mAdapter.onItemMove(position, position - 1);
                result = true;
            }
        } else if (action == R.id.action_drag_move_down) {
            if (position + 1 < itemCount) {
                mAdapter.onItemMove(position, position + 1);
                result = true;
            }
        } else if (action == R.id.action_drag_move_top) {
            if (position != 0) {
                mAdapter.onItemMove(position, 0);
                result = true;
            }
        } else if (action == R.id.action_drag_move_bottom) {
            if (position != itemCount - 1) {
                mAdapter.onItemMove(position, itemCount - 1);
                result = true;
            }
        } else if (action == R.id.action_drag_remove) {
            if (itemCount > 1) {
                mAdapter.removeItem(position);
                result = true;
            }
        } else {
            return super.performAccessibilityActionForItem(recycler, state, host, action, args);
        }

        if (result) {
            mAdapter.doTheUpdate();
        }
        return result;
    }
}
