/*
 * Copyright (C) 2015 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.tv.menu;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import com.android.tv.menu.Menu.MenuShowReason;
import java.util.ArrayList;
import java.util.List;

/** A view that represents TV main menu. */
public class MenuView extends FrameLayout implements IMenuView {
    static final String TAG = MenuView.class.getSimpleName();
    static final boolean DEBUG = false;

    private final LayoutInflater mLayoutInflater;
    private final List<MenuRow> mMenuRows = new ArrayList<>();
    private final List<MenuRowView> mMenuRowViews = new ArrayList<>();

    @MenuShowReason private int mShowReason = Menu.REASON_NONE;

    private final MenuLayoutManager mLayoutManager;

    public MenuView(Context context) {
        this(context, null, 0);
    }

    public MenuView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MenuView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mLayoutInflater = LayoutInflater.from(context);
        // Set hardware layer type for smooth animation of lots of views.
        setLayerType(LAYER_TYPE_HARDWARE, null);
        getViewTreeObserver()
                .addOnGlobalFocusChangeListener(
                        new OnGlobalFocusChangeListener() {
                            @Override
                            public void onGlobalFocusChanged(View oldFocus, View newFocus) {
                                MenuRowView newParent = getParentMenuRowView(newFocus);
                                if (newParent != null) {
                                    if (DEBUG) Log.d(TAG, "Focus changed to " + newParent);
                                    // When the row is selected, the row view itself has the focus
                                    // because the row
                                    // is collapsed. To make the child of the row have the focus,
                                    // requestFocus()
                                    // should be called again after the row is expanded. It's done
                                    // in
                                    // setSelectedPosition().
                                    setSelectedPositionSmooth(mMenuRowViews.indexOf(newParent));
                                }
                            }
                        });
        mLayoutManager = new MenuLayoutManager(context, this);
    }

    @Override
    public void setMenuRows(List<MenuRow> menuRows) {
        mMenuRows.clear();
        mMenuRows.addAll(menuRows);
        for (MenuRow row : menuRows) {
            MenuRowView view = createMenuRowView(row);
            mMenuRowViews.add(view);
            addView(view);
        }
        mLayoutManager.setMenuRowsAndViews(mMenuRows, mMenuRowViews);
    }

    private MenuRowView createMenuRowView(MenuRow row) {
        MenuRowView view = (MenuRowView) mLayoutInflater.inflate(row.getLayoutResId(), this, false);
        view.onBind(row);
        row.setMenuRowView(view);
        return view;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mLayoutManager.layout(left, top, right, bottom);
    }

    @Override
    public void onShow(
            @MenuShowReason int reason, String rowIdToSelect, final Runnable runnableAfterShow) {
        if (DEBUG) {
            Log.d(TAG, "onShow(reason=" + reason + ", rowIdToSelect=" + rowIdToSelect + ")");
        }
        mShowReason = reason;
        if (getVisibility() == VISIBLE) {
            if (rowIdToSelect != null) {
                int position = getItemPosition(rowIdToSelect);
                if (position >= 0) {
                    MenuRowView rowView = mMenuRowViews.get(position);
                    rowView.initialize(reason);
                    setSelectedPosition(position);
                }
            }
            return;
        }
        initializeChildren();
        update(true);
        int position = getItemPosition(rowIdToSelect);
        if (position == -1 || !mMenuRows.get(position).isVisible()) {
            // Channels row is always visible.
            position = getItemPosition(ChannelsRow.ID);
        }
        setSelectedPosition(position);
        // Change the visibility as late as possible to avoid the unnecessary animation.
        setVisibility(VISIBLE);
        // Make the selected row have the focus.
        requestFocus();
        if (runnableAfterShow != null) {
            getViewTreeObserver()
                    .addOnGlobalLayoutListener(
                            new OnGlobalLayoutListener() {
                                @Override
                                public void onGlobalLayout() {
                                    getViewTreeObserver().removeOnGlobalLayoutListener(this);
                                    // Start show animation after layout finishes for smooth
                                    // animation because the
                                    // layout can take long time.
                                    runnableAfterShow.run();
                                }
                            });
        }
        mLayoutManager.onMenuShow();
    }

    @Override
    public void onHide() {
        if (getVisibility() == GONE) {
            return;
        }
        mLayoutManager.onMenuHide();
        setVisibility(GONE);
    }

    @Override
    public boolean isVisible() {
        return getVisibility() == VISIBLE;
    }

    @Override
    public boolean update(boolean menuActive) {
        if (menuActive) {
            for (MenuRow row : mMenuRows) {
                row.update();
            }
            mLayoutManager.onMenuRowUpdated();
            return true;
        }
        return false;
    }

    @Override
    public boolean update(String rowId, boolean menuActive) {
        if (menuActive) {
            MenuRow row = getMenuRow(rowId);
            if (row != null) {
                row.update();
                mLayoutManager.onMenuRowUpdated();
                return true;
            }
        }
        return false;
    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
        int selectedPosition = mLayoutManager.getSelectedPosition();
        // When the menu shows up, the selected row should have focus.
        AccessibilityManager mAccessibilityManager =
                getContext().getSystemService(AccessibilityManager.class);
        if (selectedPosition >= 0 && selectedPosition < mMenuRowViews.size()) {
            if(mAccessibilityManager.isEnabled())
                mMenuRowViews.get(selectedPosition)
                        .sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
            return mMenuRowViews.get(selectedPosition).requestFocus();
        }
        return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
    }

    @Override
    public void focusableViewAvailable(View v) {
        // Workaround of b/30788222 and b/32074688.
        // The re-layout of RecyclerView gives the focus to the card view even when the menu is not
        // visible. Don't report focusable view when the menu is not visible.
        if (getVisibility() == VISIBLE) {
            super.focusableViewAvailable(v);
        }
    }

    private void setSelectedPosition(int position) {
        mLayoutManager.setSelectedPosition(position);
    }

    private void setSelectedPositionSmooth(int position) {
        mLayoutManager.setSelectedPositionSmooth(position);
    }

    private void initializeChildren() {
        for (MenuRowView view : mMenuRowViews) {
            view.initialize(mShowReason);
        }
    }

    private MenuRow getMenuRow(String rowId) {
        for (MenuRow item : mMenuRows) {
            if (rowId.equals(item.getId())) {
                return item;
            }
        }
        return null;
    }

    private int getItemPosition(String rowIdToSelect) {
        if (rowIdToSelect == null) {
            return -1;
        }
        int position = 0;
        for (MenuRow item : mMenuRows) {
            if (rowIdToSelect.equals(item.getId())) {
                return position;
            }
            ++position;
        }
        return -1;
    }

    @Override
    public View focusSearch(View focused, int direction) {
        // The bounds of the views move and overlap with each other during the animation. In this
        // situation, the framework can't perform the correct focus navigation. So the menu view
        // should search by itself.
        if (direction == View.FOCUS_UP || direction == View.FOCUS_DOWN) {
            return getUpDownFocus(focused, direction);
        }
        return super.focusSearch(focused, direction);
    }

    private View getUpDownFocus(View focused, int direction) {
        View newView = super.focusSearch(focused, direction);
        MenuRowView oldfocusedParent = getParentMenuRowView(focused);
        MenuRowView newFocusedParent = getParentMenuRowView(newView);
        int selectedPosition = mLayoutManager.getSelectedPosition();
        int start, delta;
        if (direction == View.FOCUS_UP) {
            start = selectedPosition - 1;
            delta = -1;
        } else {
            start = selectedPosition + 1;
            delta = 1;
        }
        if (newFocusedParent != oldfocusedParent) {
            // The focus leaves from the current menu row view.
            int count = mMenuRowViews.size();
            int i = start;
            while (i < count && i >= 0) {
                MenuRowView view = mMenuRowViews.get(i);
                if (view.getVisibility() == View.VISIBLE) {
                    mMenuRows.get(i).setIsReselected(false);
                    return view;
                }
                i += delta;
            }
        }
        mMenuRows.get(selectedPosition).setIsReselected(true);
        return newView;
    }

    private MenuRowView getParentMenuRowView(View view) {
        if (view == null) {
            return null;
        }
        ViewParent parent = view.getParent();
        if (parent == MenuView.this) {
            return (MenuRowView) view;
        }
        if (parent instanceof View) {
            return getParentMenuRowView((View) parent);
        }
        return null;
    }
}
