/*
 * 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.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.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;
    }
}
