/*
 * 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 androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;

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;

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

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