/*
 * 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.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.
        if (selectedPosition >= 0 && selectedPosition < mMenuRowViews.size()) {
            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;
    }
}
