// CHECKSTYLE:OFF Generated code
/* This file is auto-generated from NewDetailsFragment.java.  DO NOT MODIFY. */

/*
 * 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.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v17.leanback.app.DetailsSupportFragmentBackgroundController;
import android.support.v17.leanback.media.MediaPlayerAdapter;
import android.support.v17.leanback.media.MediaPlayerGlue;
import android.support.v17.leanback.media.PlaybackGlue;
import android.support.v17.leanback.media.PlaybackTransportControlGlue;
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.DetailsOverviewRow;
import android.support.v17.leanback.widget.FullWidthDetailsOverviewRowPresenter;
import android.support.v17.leanback.widget.FullWidthDetailsOverviewSharedElementHelper;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ImageCardView;
import android.support.v17.leanback.widget.ListRow;
import android.support.v17.leanback.widget.ListRowPresenter;
import android.support.v17.leanback.widget.OnActionClickedListener;
import android.support.v17.leanback.widget.OnItemViewClickedListener;
import android.support.v17.leanback.widget.OnItemViewSelectedListener;
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.support.v4.app.ActivityOptionsCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class NewDetailsSupportFragment extends android.support.v17.leanback.app.DetailsSupportFragment {

    private static final String TAG = "leanback.DetailsSupportFragment";
    private static final String ITEM = "item";

    private static final int NUM_ROWS = 3;
    private ArrayObjectAdapter mRowsAdapter;
    private PhotoItem mPhotoItem;
    final CardPresenter cardPresenter = new CardPresenter();

    private static final int ACTION_PLAY = 1;
    private static final int ACTION_RENT = 2;
    private static final int ACTION_BUY = 3;

    private boolean TEST_SHARED_ELEMENT_TRANSITION = true;
    private boolean TEST_BACKGROUND_PLAYER;

    private static final long TIME_TO_LOAD_OVERVIEW_ROW_MS = 1000;
    private static final long TIME_TO_LOAD_RELATED_ROWS_MS = 2000;

    private Action mActionPlay;
    private Action mActionRent;
    private Action mActionBuy;

    private FullWidthDetailsOverviewSharedElementHelper mHelper;
    private BackgroundHelper mBackgroundHelper; // used to download bitmap async.
    private final DetailsSupportFragmentBackgroundController mDetailsBackground =
            new DetailsSupportFragmentBackgroundController(this);

    void setupTrailerVideo() {
        MediaPlayerGlue mediaPlayerGlue = new MediaPlayerGlue(getActivity());
        mDetailsBackground.setupVideoPlayback(mediaPlayerGlue);
        mediaPlayerGlue.setMode(MediaPlayerGlue.REPEAT_ONE);
        mediaPlayerGlue.setArtist("A Googler");
        mediaPlayerGlue.setTitle("Diving with Sharks Trailer");
        mediaPlayerGlue.setMediaSource(Uri.parse("android.resource://com.example.android.leanback/"
                + "raw/browse"));
    }

    void setupMainVideo() {
        Context context = getActivity();
        MediaPlayerAdapter adapter = new MediaPlayerAdapter(context);
        PlaybackTransportControlGlue<MediaPlayerAdapter> mediaPlayerGlue =
                new PlaybackTransportControlGlue(context, adapter);
        mDetailsBackground.setupVideoPlayback(mediaPlayerGlue);
        mediaPlayerGlue.setSubtitle("A Googler");
        mediaPlayerGlue.setTitle("Diving with Sharks");
        mediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(
                "https://storage.googleapis.com/android-tv/Sample videos/April Fool's "
                        + "2013/Explore Treasure Mode with Google Maps.mp4"));
        mediaPlayerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() {
            @Override
            public void onPreparedStateChanged(PlaybackGlue glue) {
                super.onPreparedStateChanged(glue);
                PlaybackTransportControlGlue controlGlue = (PlaybackTransportControlGlue) glue;
                controlGlue.setSeekProvider(new PlaybackSeekDiskDataProvider(
                        controlGlue.getDuration(), 1000,
                        "/sdcard/seek/frame_%04d.jpg"));
            }
        });
    }

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

        mBackgroundHelper = new BackgroundHelper(getActivity());
        mDetailsBackground.enableParallax();
        if (TEST_BACKGROUND_PLAYER) {
            if (MovieData.sStatus == MovieData.STATUS_INIT) {
                // not own/rented, play trailer
                setupTrailerVideo();
            } else {
                // bought or rented, play the main content
                setupMainVideo();
                // hide details main ui
                mDetailsBackground.switchToVideo();
            }
        }

        final Context context = getActivity();
        setBadgeDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_title,
                context.getTheme()));
        setTitle("Leanback Sample App");
        if (!TEST_BACKGROUND_PLAYER) {
            setOnSearchClickedListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(getActivity(), SearchSupportActivity.class);
                    startActivity(intent);
                }
            });
        }

        mActionPlay = new Action(ACTION_PLAY, "Play");
        mActionRent = new Action(ACTION_RENT, "Rent", "$3.99", ResourcesCompat.getDrawable(
                context.getResources(), R.drawable.ic_action_a, context.getTheme()));
        mActionBuy = new Action(ACTION_BUY, "Buy $9.99");

        ClassPresenterSelector ps = new ClassPresenterSelector();
        FullWidthDetailsOverviewRowPresenter dorPresenter =
                new FullWidthDetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
        dorPresenter.setOnActionClickedListener(new OnActionClickedListener() {
            @Override
            public void onActionClicked(Action action) {
                final Context context = getActivity();
                DetailsOverviewRow dor = (DetailsOverviewRow) mRowsAdapter.get(0);
                if (action.getId() == ACTION_BUY) {
                    // on the UI thread, we can modify actions adapter directly
                    SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
                            dor.getActionsAdapter();
                    actions.set(ACTION_PLAY, mActionPlay);
                    actions.clear(ACTION_RENT);
                    actions.clear(ACTION_BUY);
                    boolean previousRented = MovieData.sStatus == MovieData.STATUS_RENTED;
                    MovieData.sStatus = MovieData.STATUS_OWN;
                    dor.setItem(getDisplayTitle(mPhotoItem.getTitle()));
                    dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
                            R.drawable.details_img_16x9, context.getTheme()));
                    if (TEST_BACKGROUND_PLAYER) {
                        if (!previousRented) {
                            setupMainVideo();
                            mDetailsBackground.switchToVideo();
                        }
                    } else {
                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                        getActivity().startActivity(intent);
                    }
                } else if (action.getId() == ACTION_RENT) {
                    // on the UI thread, we can modify actions adapter directly
                    SparseArrayObjectAdapter actions = (SparseArrayObjectAdapter)
                            dor.getActionsAdapter();
                    actions.set(ACTION_PLAY, mActionPlay);
                    actions.clear(ACTION_RENT);
                    MovieData.sStatus = MovieData.STATUS_RENTED;
                    dor.setItem(getDisplayTitle(mPhotoItem.getTitle()));
                    if (TEST_BACKGROUND_PLAYER) {
                        setupMainVideo();
                        mDetailsBackground.switchToVideo();
                    } else {
                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                        getActivity().startActivity(intent);
                    }
                } else if (action.getId() == ACTION_PLAY) {
                    if (TEST_BACKGROUND_PLAYER) {
                        mDetailsBackground.switchToVideo();
                    } else {
                        Intent intent = new Intent(context, PlaybackSupportActivity.class);
                        getActivity().startActivity(intent);
                    }
                }
            }
        });

        ps.addClassPresenter(DetailsOverviewRow.class, dorPresenter);
        ps.addClassPresenter(ListRow.class, new ListRowPresenter());

        mRowsAdapter = new ArrayObjectAdapter(ps);
        updateAdapter();

        setOnItemViewClickedListener(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 PhotoItem) {
                    Intent intent = new Intent(getActivity(), DetailsSupportActivity.class);
                    intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item);

                    Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
                            getActivity(),
                            ((ImageCardView) itemViewHolder.view).getMainImageView(),
                            DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle();
                    getActivity().startActivity(intent, bundle);
                }
            }
        });
        setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
            @Override
            public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
                    RowPresenter.ViewHolder rowViewHolder, Row row) {
                Log.i(TAG, "onItemSelected: " + item + " row " + row);
            }
        });

        if (TEST_SHARED_ELEMENT_TRANSITION) {
            mHelper = new FullWidthDetailsOverviewSharedElementHelper();
            mHelper.setSharedElementEnterTransition(getActivity(),
                    DetailsSupportActivity.SHARED_ELEMENT_NAME);
            dorPresenter.setListener(mHelper);
            dorPresenter.setParticipatingEntranceTransition(false);
        } else {
            dorPresenter.setParticipatingEntranceTransition(true);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        return view;
    }

    public void setBackgroundVideo(boolean backgroundVideo) {
        TEST_BACKGROUND_PLAYER = backgroundVideo;
    }

    public void setItem(PhotoItem photoItem) {
        mPhotoItem = photoItem;
        updateAdapter();
    }

    static String getDisplayTitle(String title) {
        switch (MovieData.sStatus) {
            case MovieData.STATUS_OWN:
                title = title + "(Owned)";
                break;
            case MovieData.STATUS_RENTED:
                title = title + "(Rented)";
                break;
            case MovieData.STATUS_INIT:
            default:
        }
        return title;
    }

    void updateAdapter() {
        if (mRowsAdapter == null) {
            return;
        }
        mRowsAdapter.clear();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                final Context context = getActivity();
                if (context == null) {
                    return;
                }

                DetailsOverviewRow dor = new DetailsOverviewRow(
                        getDisplayTitle(mPhotoItem.getTitle()));
                dor.setImageDrawable(ResourcesCompat.getDrawable(context.getResources(),
                        mPhotoItem.getImageResourceId(), context.getTheme()));
                SparseArrayObjectAdapter adapter = new SparseArrayObjectAdapter();
                switch (MovieData.sStatus) {
                    case MovieData.STATUS_INIT:
                        adapter.set(ACTION_RENT, mActionRent);
                        adapter.set(ACTION_BUY, mActionBuy);
                        break;
                    case MovieData.STATUS_OWN:
                        adapter.set(ACTION_PLAY, mActionPlay);
                        break;
                    case MovieData.STATUS_RENTED:
                        adapter.set(ACTION_PLAY, mActionPlay);
                        adapter.set(ACTION_BUY, mActionBuy);
                        break;
                }
                dor.setActionsAdapter(adapter);
                mRowsAdapter.add(0, dor);
                setSelectedPosition(0, true);
                if (TEST_SHARED_ELEMENT_TRANSITION) {
                    if (mHelper != null && !mHelper.getAutoStartSharedElementTransition()) {
                        mHelper.startPostponedEnterTransition();
                    }
                }
            }
        }, TIME_TO_LOAD_OVERVIEW_ROW_MS);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (getActivity() == null) {
                    return;
                }
                for (int i = 0; i < NUM_ROWS; ++i) {
                    ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
                    listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1));
                    listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2));
                    listRowAdapter.add(new PhotoItem("Android TV", R.drawable.gallery_photo_3));
                    listRowAdapter.add(new PhotoItem("Leanback", R.drawable.gallery_photo_4));
                    HeaderItem header = new HeaderItem(i, "Row " + i);
                    mRowsAdapter.add(new ListRow(header, listRowAdapter));
                }
            }
        }, TIME_TO_LOAD_RELATED_ROWS_MS);
        setAdapter(mRowsAdapter);
    }

    @Override
    public void onStart() {
        super.onStart();

        // Restore background drawable in onStart():
        mBackgroundHelper.loadBitmap(R.drawable.spiderman,
                new BackgroundHelper.BitmapLoadCallback() {
                    @Override
                    public void onBitmapLoaded(Bitmap bitmap) {
                        mDetailsBackground.setCoverBitmap(bitmap);
                    }
                });
    }

    @Override
    public void onStop() {
        mDetailsBackground.setCoverBitmap(null);
        super.onStop();
    }
}
