/*
 * Nextcloud - Android Client
 *
 * SPDX-FileCopyrightText: 2023 TSI-mc
 * SPDX-FileCopyrightText: 2023 Parneet Singh <gurayaparneet@gmail.com>
 * SPDX-FileCopyrightText: 2020 Andy Scherzinger <info@andy-scherzinger.de>
 * SPDX-FileCopyrightText: 2019 Chris Narkiewicz <hello@ezaquarii.com>
 * SPDX-FileCopyrightText: 2016 ownCloud Inc.
 * SPDX-FileCopyrightText: 2013 David A. Velasco <dvelasco@solidgear.es>
 * SPDX-License-Identifier: GPL-2.0-only AND AGPL-3.0-or-later
 */
package com.owncloud.android.ui.preview;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;

import com.nextcloud.client.account.User;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.jobs.BackgroundJobManager;
import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.media.ExoplayerListener;
import com.nextcloud.client.media.NextcloudExoPlayer;
import com.nextcloud.client.media.PlayerServiceConnection;
import com.nextcloud.client.network.ClientFactory;
import com.nextcloud.common.NextcloudClient;
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
import com.nextcloud.utils.extensions.BundleExtensionsKt;
import com.owncloud.android.R;
import com.owncloud.android.databinding.FragmentPreviewMediaBinding;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.files.StreamMediaFileOperation;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.ui.activity.DrawerActivity;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.utils.MimeTypeUtil;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;

import javax.inject.Inject;

import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.annotation.StringRes;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;

/**
 * This fragment shows a preview of a downloaded media file (audio or video).
 * <p>
 * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link User} values will produce an
 * {@link IllegalStateException}.
 * <p>
 * By now, if the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on
 * instantiation too.
 */
public class PreviewMediaFragment extends FileFragment implements OnTouchListener,
    Injectable {

    private static final String TAG = PreviewMediaFragment.class.getSimpleName();

    public static final String EXTRA_FILE = "FILE";
    public static final String EXTRA_USER = "USER";
    public static final String EXTRA_AUTOPLAY = "AUTOPLAY";
    public static final String EXTRA_START_POSITION = "START_POSITION";

    private static final String EXTRA_PLAY_POSITION = "PLAY_POSITION";
    private static final String EXTRA_PLAYING = "PLAYING";
    private static final double MIN_DENSITY_RATIO = 24.0;


    private static final String FILE = "FILE";
    private static final String USER = "USER";
    private static final String PLAYBACK_POSITION = "PLAYBACK_POSITION";
    private static final String AUTOPLAY = "AUTOPLAY";
    private static final String IS_LIVE_PHOTO = "IS_LIVE_PHOTO";

    private User user;
    private long savedPlaybackPosition;

    private boolean autoplay;
    private boolean isLivePhoto;
    private boolean prepared;
    private PlayerServiceConnection mediaPlayerServiceConnection;

    private Uri videoUri;
    @Inject ClientFactory clientFactory;
    @Inject UserAccountManager accountManager;
    @Inject BackgroundJobManager backgroundJobManager;
    FragmentPreviewMediaBinding binding;
    private ViewGroup emptyListView;
    private ExoPlayer exoPlayer;
    private NextcloudClient nextcloudClient;

    /**
     * Creates a fragment to preview a file.
     * <p>
     * When 'fileToDetail' or 'user' are null
     *
     * @param fileToDetail An {@link OCFile} to preview in the fragment
     * @param user         Currently active user
     */
    public static PreviewMediaFragment newInstance(OCFile fileToDetail,
                                                   User user,
                                                   long startPlaybackPosition,
                                                   boolean autoplay,
                                                   boolean isLivePhoto) {
        PreviewMediaFragment previewMediaFragment = new PreviewMediaFragment();

        Bundle bundle = new Bundle();
        bundle.putParcelable(FILE, fileToDetail);
        bundle.putParcelable(USER, user);
        bundle.putLong(PLAYBACK_POSITION, startPlaybackPosition);
        bundle.putBoolean(AUTOPLAY, autoplay);
        bundle.putBoolean(IS_LIVE_PHOTO, isLivePhoto);

        previewMediaFragment.setArguments(bundle);

        return previewMediaFragment;
    }

    /**
     * Creates an empty fragment for previews.
     * <p/>
     * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically (for instance, when the
     * device is turned a aside).
     * <p/>
     * DO NOT CALL IT: an {@link OCFile} and {@link User} must be provided for a successful construction
     */
    public PreviewMediaFragment() {
        super();

        savedPlaybackPosition = 0;
        autoplay = true;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

        Bundle bundle = getArguments();

        setFile(BundleExtensionsKt.getParcelableArgument(bundle, FILE, OCFile.class));
        user = BundleExtensionsKt.getParcelableArgument(bundle, USER, User.class);

        savedPlaybackPosition = bundle.getLong(PLAYBACK_POSITION);
        autoplay = bundle.getBoolean(AUTOPLAY);
        isLivePhoto = bundle.getBoolean(IS_LIVE_PHOTO);

        mediaPlayerServiceConnection = new PlayerServiceConnection(requireContext());
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        Log_OC.v(TAG, "onCreateView");

        binding = FragmentPreviewMediaBinding.inflate(inflater, container, false);
        View view = binding.getRoot();

        emptyListView = binding.emptyView.emptyListView;

        setLoadingView();
        return view;
    }

    private void setLoadingView() {
        binding.progress.setVisibility(View.VISIBLE);
        binding.emptyView.emptyListView.setVisibility(View.GONE);
    }

    private void setVideoErrorMessage(String headline, @StringRes int message) {
        binding.emptyView.emptyListViewHeadline.setText(headline);
        binding.emptyView.emptyListViewText.setText(message);
        binding.emptyView.emptyListIcon.setImageResource(R.drawable.file_movie);
        binding.emptyView.emptyListViewText.setVisibility(View.VISIBLE);
        binding.emptyView.emptyListIcon.setVisibility(View.VISIBLE);
        binding.progress.setVisibility(View.GONE);
        binding.emptyView.emptyListView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log_OC.v(TAG, "onActivityCreated");

        OCFile file = getFile();
        if (savedInstanceState == null) {
            if (file == null) {
                throw new IllegalStateException("Instanced with a NULL OCFile");
            }
            if (user == null) {
                throw new IllegalStateException("Instanced with a NULL ownCloud Account");
            }
        } else {
            file = BundleExtensionsKt.getParcelableArgument(savedInstanceState, EXTRA_FILE, OCFile.class);
            setFile(file);
            user = BundleExtensionsKt.getParcelableArgument(savedInstanceState, EXTRA_USER, User.class);
            savedPlaybackPosition = savedInstanceState.getInt(EXTRA_PLAY_POSITION);
            autoplay = savedInstanceState.getBoolean(EXTRA_PLAYING);
        }

        if (file != null) {
            if (MimeTypeUtil.isVideo(file)) {
                binding.exoplayerView.setVisibility(View.VISIBLE);
                binding.imagePreview.setVisibility(View.GONE);
            } else {
                binding.exoplayerView.setVisibility(View.GONE);
                binding.imagePreview.setVisibility(View.VISIBLE);
                extractAndSetCoverArt(file);
            }
        }
        toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }

    /**
     * tries to read the cover art from the audio file and sets it as cover art.
     *
     * @param file audio file with potential cover art
     */
    private void extractAndSetCoverArt(OCFile file) {
        if (MimeTypeUtil.isAudio(file)) {
            if (file.getStoragePath() == null) {
                setThumbnailForAudio(file);
            } else {
                try {
                    MediaMetadataRetriever mmr = new MediaMetadataRetriever();
                    mmr.setDataSource(file.getStoragePath());
                    byte[] data = mmr.getEmbeddedPicture();
                    if (data != null) {
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        binding.imagePreview.setImageBitmap(bitmap); //associated cover art in bitmap
                    } else {
                        setThumbnailForAudio(file);
                    }
                } catch (Throwable t) {
                    setGenericThumbnail();
                }
            }
        }
    }

    private void setThumbnailForAudio(OCFile file) {
        Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
            ThumbnailsCacheManager.PREFIX_THUMBNAIL + file.getRemoteId());

        if (thumbnail != null) {
            binding.imagePreview.setImageBitmap(thumbnail);
        } else {
            setGenericThumbnail();
        }
    }

    /**
     * Set generic icon (logo) as placeholder for thumbnail in preview.
     */
    private void setGenericThumbnail() {
        Drawable logo = AppCompatResources.getDrawable(requireContext(), R.drawable.logo);
        if (logo != null) {
            if (!getResources().getBoolean(R.bool.is_branded_client)) {
                // only colour logo of non-branded client
                DrawableCompat.setTint(logo, getResources().getColor(R.color.primary, requireContext().getTheme()));
            }
            binding.imagePreview.setImageDrawable(logo);
        }
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        Log_OC.v(TAG, "onSaveInstanceState");
        toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        outState.putParcelable(EXTRA_FILE, getFile());
        outState.putParcelable(EXTRA_USER, user);

        if (MimeTypeUtil.isVideo(getFile()) && exoPlayer != null) {
            savedPlaybackPosition = exoPlayer.getCurrentPosition();
            autoplay = exoPlayer.isPlaying();
            outState.putLong(EXTRA_PLAY_POSITION, savedPlaybackPosition);
            outState.putBoolean(EXTRA_PLAYING, autoplay);
        } else if (mediaPlayerServiceConnection != null && mediaPlayerServiceConnection.isConnected()) {
            outState.putInt(EXTRA_PLAY_POSITION, mediaPlayerServiceConnection.getCurrentPosition());
            outState.putBoolean(EXTRA_PLAYING, mediaPlayerServiceConnection.isPlaying());
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        Log_OC.v(TAG, "onStart");
        OCFile file = getFile();
        if (file != null) {
            // bind to any existing player
            mediaPlayerServiceConnection.bind();

            if (MimeTypeUtil.isAudio(file)) {
                binding.mediaController.setMediaPlayer(mediaPlayerServiceConnection);
                binding.mediaController.setVisibility(View.VISIBLE);
                mediaPlayerServiceConnection.start(user, file, autoplay, savedPlaybackPosition);
                binding.emptyView.emptyListView.setVisibility(View.GONE);
                binding.progress.setVisibility(View.GONE);
            } else if (MimeTypeUtil.isVideo(file)) {
                if (mediaPlayerServiceConnection.isConnected()) {
                    // always stop player
                    stopAudio();
                }
                if (exoPlayer != null) {
                    playVideo();
                } else {
                    final Handler handler = new Handler(Looper.getMainLooper());
                    Executors.newSingleThreadExecutor().execute(() -> {
                        try {
                            nextcloudClient = clientFactory.createNextcloudClient(accountManager.getUser());
                            handler.post(() -> {
                                exoPlayer = NextcloudExoPlayer.createNextcloudExoplayer(requireContext(), nextcloudClient);

                                exoPlayer.addListener(new ExoplayerListener(requireContext(), binding.exoplayerView, exoPlayer, () -> {
                                    goBackToLivePhoto();
                                    return null;
                                }));

                                playVideo();
                            });
                        } catch (ClientFactory.CreationException e) {
                            handler.post(() -> Log_OC.e(TAG, "error setting up ExoPlayer", e));
                        }
                    });
                }
            }
        }
    }

    private void goBackToLivePhoto() {
        if (!isLivePhoto) {
            return;
        }

        showActionBar();

        requireActivity().getSupportFragmentManager().popBackStack();
    }

    private void showActionBar() {
        Activity currentActivity = requireActivity();
        if (currentActivity instanceof PreviewImageActivity activity) {
            activity.toggleActionBarVisibility(false);
        }
    }
    @OptIn(markerClass = UnstableApi.class)
    private void setupVideoView() {
        binding.exoplayerView.setShowNextButton(false);
        binding.exoplayerView.setShowPreviousButton(false);
        binding.exoplayerView.setPlayer(exoPlayer);
        binding.exoplayerView.setFullscreenButtonClickListener(isFullScreen -> startFullScreenVideo());
    }

    private void stopAudio() {
        mediaPlayerServiceConnection.stop();
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        menu.removeItem(R.id.action_search);
        inflater.inflate(R.menu.custom_menu_placeholder, menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.custom_menu_placeholder_item) {
            final OCFile file = getFile();
            if (containerActivity.getStorageManager() != null && file != null) {
                // Update the file
                final OCFile updatedFile = containerActivity.getStorageManager().getFileById(file.getFileId());
                setFile(updatedFile);

                final OCFile fileNew = getFile();
                if (fileNew != null) {
                    showFileActions(fileNew);
                }
            }
        }
        return super.onOptionsItemSelected(item);
    }

    private void showFileActions(OCFile file) {
        final List<Integer> additionalFilter = new ArrayList<>(
            Arrays.asList(
                R.id.action_rename_file,
                R.id.action_sync_file,
                R.id.action_move_or_copy,
                R.id.action_favorite,
                R.id.action_unset_favorite,
                R.id.action_pin_to_homescreen
                         ));
        if (getFile() != null && getFile().isSharedWithMe() && !getFile().canReshare()) {
            additionalFilter.add(R.id.action_send_share_file);
        }
        final FragmentManager fragmentManager = getChildFragmentManager();
        FileActionsBottomSheet.newInstance(file, false, additionalFilter)
            .setResultListener(fragmentManager, this, this::onFileActionChosen)
            .show(fragmentManager, "actions");
    }

    public void onFileActionChosen(final int itemId) {
        if (itemId == R.id.action_send_share_file) {
            sendShareFile();
        } else if (itemId == R.id.action_open_file_with) {
            openFile();
        } else if (itemId == R.id.action_remove_file) {
            RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(getFile());
            dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
        } else if (itemId == R.id.action_see_details) {
            seeDetails();
        } else if (itemId == R.id.action_sync_file) {
            containerActivity.getFileOperationsHelper().syncFile(getFile());
        } else if (itemId == R.id.action_cancel_sync) {
            containerActivity.getFileOperationsHelper().cancelTransference(getFile());
        } else if (itemId == R.id.action_stream_media) {
            containerActivity.getFileOperationsHelper().streamMediaFile(getFile());
        } else if (itemId == R.id.action_export_file) {
            ArrayList<OCFile> list = new ArrayList<>();
            list.add(getFile());
            containerActivity.getFileOperationsHelper().exportFiles(list,
                                                                    getContext(),
                                                                    getView(),
                                                                    backgroundJobManager);
        } else if (itemId == R.id.action_download_file) {
            FileDownloadHelper.Companion.instance().downloadFileIfNotStartedBefore(user, getFile());
        }
    }

    /**
     * Update the file of the fragment with file value
     *
     * @param file Replaces the held file with a new one
     */
    public void updateFile(OCFile file) {
        setFile(file);
    }

    private void seeDetails() {
        stopPreview(false);
        containerActivity.showDetails(getFile());
    }

    private void sendShareFile() {
        stopPreview(false);
        containerActivity.getFileOperationsHelper().sendShareFile(getFile());
    }

    private void playVideo() {
        setupVideoView();
        // load the video file in the video player
        // when done, VideoHelper#onPrepared() will be called
        if (getFile().isDown()) {
            playVideoUri(getFile().getStorageUri());
        } else {
            try {
                new LoadStreamUrl(this, user, clientFactory).execute(getFile().getLocalId());
            } catch (Exception e) {
                Log_OC.e(TAG, "Loading stream url not possible: " + e);
            }
        }
    }

    private void playVideoUri(final Uri uri) {
        binding.progress.setVisibility(View.GONE);

        exoPlayer.setMediaItem(MediaItem.fromUri(uri));
        exoPlayer.setPlayWhenReady(autoplay);
        exoPlayer.prepare();

        if (savedPlaybackPosition >= 0) {
            exoPlayer.seekTo(savedPlaybackPosition);
        }

        // only autoplay video once
        autoplay = false;
    }

    private static class LoadStreamUrl extends AsyncTask<Long, Void, Uri> {

        private final ClientFactory clientFactory;
        private final User user;
        private final WeakReference<PreviewMediaFragment> previewMediaFragmentWeakReference;

        public LoadStreamUrl(PreviewMediaFragment previewMediaFragment, User user, ClientFactory clientFactory) {
            this.previewMediaFragmentWeakReference = new WeakReference<>(previewMediaFragment);
            this.user = user;
            this.clientFactory = clientFactory;
        }

        @Override
        protected Uri doInBackground(Long... fileId) {
            OwnCloudClient client;
            try {
                client = clientFactory.create(user);
            } catch (ClientFactory.CreationException e) {
                Log_OC.e(TAG, "Loading stream url not possible: " + e);
                return null;
            }

            StreamMediaFileOperation sfo = new StreamMediaFileOperation(fileId[0]);
            RemoteOperationResult result = sfo.execute(client);

            if (!result.isSuccess()) {
                return null;
            }

            return Uri.parse((String) result.getData().get(0));
        }

        @Override
        protected void onPostExecute(Uri uri) {
            final PreviewMediaFragment previewMediaFragment = previewMediaFragmentWeakReference.get();
            final Context context = previewMediaFragment != null ? previewMediaFragment.getContext() : null;
            if (previewMediaFragment != null && previewMediaFragment.binding != null && context != null) {
                if (uri != null) {
                    previewMediaFragment.videoUri = uri;
                    previewMediaFragment.playVideoUri(uri);
                } else {
                    previewMediaFragment.emptyListView.setVisibility(View.VISIBLE);
                    previewMediaFragment.setVideoErrorMessage(
                        previewMediaFragment.getString(R.string.stream_not_possible_headline),
                        R.string.stream_not_possible_message);
                }
            } else {
                Log_OC.e(TAG, "Error streaming file: no previewMediaFragment!");
            }
        }
    }

    @Override
    public void onPause() {
        Log_OC.v(TAG, "onPause");
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        Log_OC.v(TAG, "onResume");
    }

    @Override
    public void onDestroy() {
        Log_OC.v(TAG, "onDestroy");
        super.onDestroy();
    }

    @Override
    public void onDestroyView() {
        Log_OC.v(TAG, "onDestroyView");
        super.onDestroyView();
        binding = null;
    }

    @Override
    public void onStop() {
        Log_OC.v(TAG, "onStop");
        final OCFile file = getFile();
        if (MimeTypeUtil.isAudio(file) && !mediaPlayerServiceConnection.isPlaying()) {
            stopAudio();
        } else if (MimeTypeUtil.isVideo(file) && exoPlayer != null && exoPlayer.isPlaying()) {
            savedPlaybackPosition = exoPlayer.getCurrentPosition();
            exoPlayer.pause();
        }

        mediaPlayerServiceConnection.unbind();
        toggleDrawerLockMode(containerActivity, DrawerLayout.LOCK_MODE_UNLOCKED);
        super.onStop();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN && v.equals(binding.exoplayerView)) {
            // added a margin on the left to avoid interfering with gesture to open navigation drawer
            if (event.getX() / Resources.getSystem().getDisplayMetrics().density > MIN_DENSITY_RATIO) {
                startFullScreenVideo();
            }
            return true;
        }
        return false;
    }

    private void startFullScreenVideo() {
        final FragmentActivity activity = getActivity();
        if (activity != null) {
            new PreviewVideoFullscreenDialog(activity, nextcloudClient, exoPlayer, binding.exoplayerView).show();
        }
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log_OC.v(TAG, "onConfigurationChanged " + this);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log_OC.v(TAG, "onActivityResult " + this);
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            savedPlaybackPosition = data.getLongExtra(PreviewMediaFragment.EXTRA_START_POSITION, 0);
            autoplay = data.getBooleanExtra(PreviewMediaFragment.EXTRA_AUTOPLAY, false);
        }
    }

    /**
     * Opens the previewed file with an external application.
     */
    private void openFile() {
        stopPreview(true);
        containerActivity.getFileOperationsHelper().openFile(getFile());
    }

    /**
     * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewMediaFragment} to be previewed.
     *
     * @param file File to test if can be previewed.
     * @return 'True' if the file can be handled by the fragment.
     */
    public static boolean canBePreviewed(OCFile file) {
        return file != null && (MimeTypeUtil.isAudio(file) || MimeTypeUtil.isVideo(file));
    }

    public void stopPreview(boolean stopAudio) {
        if (stopAudio && mediaPlayerServiceConnection != null) {
            mediaPlayerServiceConnection.stop();
        } else if (exoPlayer != null) {
            savedPlaybackPosition = exoPlayer.getCurrentPosition();
            exoPlayer.stop();
        }
    }

    public long getPosition() {
        if (prepared) {
            savedPlaybackPosition = exoPlayer.getCurrentPosition();
        }
        Log_OC.v(TAG, "getting position: " + savedPlaybackPosition);
        return savedPlaybackPosition;
    }

    private void toggleDrawerLockMode(ContainerActivity containerActivity, int lockMode) {
        ((DrawerActivity) containerActivity).setDrawerLockMode(lockMode);
    }

    @Override
    public void onDetach() {

        if (exoPlayer != null) {
            exoPlayer.stop();
            exoPlayer.release();
        }

        super.onDetach();
    }
}
