/*
 * Copyright (C) 2014 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.example.android.leanback;

import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.widget.Action;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.ClassPresenterSelector;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
import android.support.v17.leanback.widget.PlaybackControlsRow;
import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.RowPresenter;
import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
import android.util.Log;

public class PlaybackOverlayFragment
        extends android.support.v17.leanback.app.PlaybackOverlayFragment
        implements PlaybackOverlayActivity.PictureInPictureListener {
    private static final String TAG = "leanback.PlaybackControlsFragment";

    /**
     * Change this to choose a different overlay background.
     */
    private static final int BACKGROUND_TYPE = PlaybackOverlayFragment.BG_LIGHT;

    /**
     * Change the number of related content rows.
     */
    private static final int RELATED_CONTENT_ROWS = 3;

    /**
     * Change this to select hidden
     */
    private static final boolean SECONDARY_HIDDEN = false;

    private static final int ROW_CONTROLS = 0;

    private PlaybackControlHelper mGlue;
    final Handler mHandler = new Handler();

    // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
    // called and the playback row UI should be updated after this delay.
    private static final int MEDIA_PREPARATION_DELAY = 500;

    private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
        @Override
        public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
                                  RowPresenter.ViewHolder rowViewHolder, Row row) {
            Log.i(TAG, "onItemClicked: " + item + " row " + row);
            if (item instanceof Action) {
                mGlue.onActionClicked((Action) item);
            }
        }
    };

    private OnItemViewSelectedListener mOnItemViewSelectedListener =
            new OnItemViewSelectedListener() {
                @Override
                public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
                                           RowPresenter.ViewHolder rowViewHolder, Row row) {
                    Log.i(TAG, "onItemSelected: " + item + " row " + row);
                }
    };

    @Override
    public SparseArrayObjectAdapter getAdapter() {
        return (SparseArrayObjectAdapter) super.getAdapter();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "onCreate");
        super.onCreate(savedInstanceState);

        setBackgroundType(BACKGROUND_TYPE);
        setOnItemViewSelectedListener(mOnItemViewSelectedListener);

        createComponents(getActivity());
    }

    private void createComponents(Context context) {
        mGlue = new PlaybackControlHelper(context, this) {
            @Override
            public int getUpdatePeriod() {
                long totalTime = getControlsRow().getDuration();
                if (getView() == null || getView().getWidth() == 0 || totalTime <= 0) {
                    return 1000;
                }
                return 16;
            }

            @Override
            protected void onRowChanged(PlaybackControlsRow row) {
                if (getAdapter() == null) {
                    return;
                }
                int index = getAdapter().indexOf(row);
                if (index >= 0) {
                    getAdapter().notifyArrayItemRangeChanged(index, 1);
                }
            }

            @Override
            public void onActionClicked(Action action) {
                if (action.getId() == R.id.lb_control_picture_in_picture) {
                    if (Build.VERSION.SDK_INT >= 24) {
                        getActivity().enterPictureInPictureMode();
                    }
                    return;
                }
                super.onActionClicked(action);
            }
        };

        mGlue.setInitialized(false);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mGlue.setInitialized(true);
            }
        }, MEDIA_PREPARATION_DELAY);
        mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);

        PlaybackControlsRowPresenter playbackControlsRowPresenter =
                mGlue.createControlsRowAndPresenter();
        playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
        ClassPresenterSelector selector = new ClassPresenterSelector();
        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
        selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);

        setAdapter(new SparseArrayObjectAdapter(selector));

        // Add the controls row
        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());

        // Add related content rows
        for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
            ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new StringPresenter());
            listRowAdapter.add("Some related content");
            listRowAdapter.add("Other related content");
            HeaderItem header = new HeaderItem(i, "Row " + i);
            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
        }

    }

    @Override
    public void onStart() {
        super.onStart();
        mGlue.setFadingEnabled(true);
        mGlue.enableProgressUpdating(true);
        ((PlaybackOverlayActivity) getActivity()).registerPictureInPictureListener(this);
    }

    @Override
    public void onStop() {
        mGlue.enableProgressUpdating(false);
        ((PlaybackOverlayActivity) getActivity()).unregisterPictureInPictureListener(this);
        super.onStop();
    }

    @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
        if (isInPictureInPictureMode) {
            // Hide the controls in picture-in-picture mode.
            setFadingEnabled(true);
            fadeOut();
        } else {
            setFadingEnabled(mGlue.isPlaying());
        }
    }
}
