/*
 * Copyright (C) 2013 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 android.media;

import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.media.MediaPlayer.TrackInfo;
import android.media.SubtitleTrack.RenderingWidget;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.accessibility.CaptioningManager;

import java.util.Locale;
import java.util.Vector;

/**
 * The subtitle controller provides the architecture to display subtitles for a
 * media source.  It allows specifying which tracks to display, on which anchor
 * to display them, and also allows adding external, out-of-band subtitle tracks.
 *
 * @hide
 */
public class SubtitleController {
    private MediaTimeProvider mTimeProvider;
    private Vector<Renderer> mRenderers;
    private Vector<SubtitleTrack> mTracks;
    private SubtitleTrack mSelectedTrack;
    private boolean mShowing;
    private CaptioningManager mCaptioningManager;
    @UnsupportedAppUsage
    private Handler mHandler;

    private static final int WHAT_SHOW = 1;
    private static final int WHAT_HIDE = 2;
    private static final int WHAT_SELECT_TRACK = 3;
    private static final int WHAT_SELECT_DEFAULT_TRACK = 4;

    private final Handler.Callback mCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
            case WHAT_SHOW:
                doShow();
                return true;
            case WHAT_HIDE:
                doHide();
                return true;
            case WHAT_SELECT_TRACK:
                doSelectTrack((SubtitleTrack)msg.obj);
                return true;
            case WHAT_SELECT_DEFAULT_TRACK:
                doSelectDefaultTrack();
                return true;
            default:
                return false;
            }
        }
    };

    private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
        new CaptioningManager.CaptioningChangeListener() {
            /** @hide */
            @Override
            public void onEnabledChanged(boolean enabled) {
                selectDefaultTrack();
            }

            /** @hide */
            @Override
            public void onLocaleChanged(Locale locale) {
                selectDefaultTrack();
            }
        };

    /**
     * Creates a subtitle controller for a media playback object that implements
     * the MediaTimeProvider interface.
     *
     * @param timeProvider
     */
    @UnsupportedAppUsage
    public SubtitleController(
            Context context,
            MediaTimeProvider timeProvider,
            Listener listener) {
        mTimeProvider = timeProvider;
        mListener = listener;

        mRenderers = new Vector<Renderer>();
        mShowing = false;
        mTracks = new Vector<SubtitleTrack>();
        mCaptioningManager =
            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
    }

    @Override
    protected void finalize() throws Throwable {
        mCaptioningManager.removeCaptioningChangeListener(
                mCaptioningChangeListener);
        super.finalize();
    }

    /**
     * @return the available subtitle tracks for this media. These include
     * the tracks found by {@link MediaPlayer} as well as any tracks added
     * manually via {@link #addTrack}.
     */
    public SubtitleTrack[] getTracks() {
        synchronized(mTracks) {
            SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
            mTracks.toArray(tracks);
            return tracks;
        }
    }

    /**
     * @return the currently selected subtitle track
     */
    public SubtitleTrack getSelectedTrack() {
        return mSelectedTrack;
    }

    private RenderingWidget getRenderingWidget() {
        if (mSelectedTrack == null) {
            return null;
        }
        return mSelectedTrack.getRenderingWidget();
    }

    /**
     * Selects a subtitle track.  As a result, this track will receive
     * in-band data from the {@link MediaPlayer}.  However, this does
     * not change the subtitle visibility.
     *
     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
     *
     * @param track The subtitle track to select.  This must be one of the
     *              tracks in {@link #getTracks}.
     * @return true if the track was successfully selected.
     */
    public boolean selectTrack(SubtitleTrack track) {
        if (track != null && !mTracks.contains(track)) {
            return false;
        }

        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
        return true;
    }

    private void doSelectTrack(SubtitleTrack track) {
        mTrackIsExplicit = true;
        if (mSelectedTrack == track) {
            return;
        }

        if (mSelectedTrack != null) {
            mSelectedTrack.hide();
            mSelectedTrack.setTimeProvider(null);
        }

        mSelectedTrack = track;
        if (mAnchor != null) {
            mAnchor.setSubtitleWidget(getRenderingWidget());
        }

        if (mSelectedTrack != null) {
            mSelectedTrack.setTimeProvider(mTimeProvider);
            mSelectedTrack.show();
        }

        if (mListener != null) {
            mListener.onSubtitleTrackSelected(track);
        }
    }

    /**
     * @return the default subtitle track based on system preferences, or null,
     * if no such track exists in this manager.
     *
     * Supports HLS-flags: AUTOSELECT, FORCED & DEFAULT.
     *
     * 1. If captioning is disabled, only consider FORCED tracks. Otherwise,
     * consider all tracks, but prefer non-FORCED ones.
     * 2. If user selected "Default" caption language:
     *   a. If there is a considered track with DEFAULT=yes, returns that track
     *      (favor the first one in the current language if there are more than
     *      one default tracks, or the first in general if none of them are in
     *      the current language).
     *   b. Otherwise, if there is a track with AUTOSELECT=yes in the current
     *      language, return that one.
     *   c. If there are no default tracks, and no autoselectable tracks in the
     *      current language, return null.
     * 3. If there is a track with the caption language, select that one.  Prefer
     * the one with AUTOSELECT=no.
     *
     * The default values for these flags are DEFAULT=no, AUTOSELECT=yes
     * and FORCED=no.
     */
    public SubtitleTrack getDefaultTrack() {
        SubtitleTrack bestTrack = null;
        int bestScore = -1;

        Locale selectedLocale = mCaptioningManager.getLocale();
        Locale locale = selectedLocale;
        if (locale == null) {
            locale = Locale.getDefault();
        }
        boolean selectForced = !mCaptioningManager.isEnabled();

        synchronized(mTracks) {
            for (SubtitleTrack track: mTracks) {
                MediaFormat format = track.getFormat();
                String language = format.getString(MediaFormat.KEY_LANGUAGE);
                boolean forced =
                    format.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0;
                boolean autoselect =
                    format.getInteger(MediaFormat.KEY_IS_AUTOSELECT, 1) != 0;
                boolean is_default =
                    format.getInteger(MediaFormat.KEY_IS_DEFAULT, 0) != 0;

                boolean languageMatches =
                    (locale == null ||
                    locale.getLanguage().equals("") ||
                    locale.getISO3Language().equals(language) ||
                    locale.getLanguage().equals(language));
                // is_default is meaningless unless caption language is 'default'
                int score = (forced ? 0 : 8) +
                    (((selectedLocale == null) && is_default) ? 4 : 0) +
                    (autoselect ? 0 : 2) + (languageMatches ? 1 : 0);

                if (selectForced && !forced) {
                    continue;
                }

                // we treat null locale/language as matching any language
                if ((selectedLocale == null && is_default) ||
                    (languageMatches &&
                     (autoselect || forced || selectedLocale != null))) {
                    if (score > bestScore) {
                        bestScore = score;
                        bestTrack = track;
                    }
                }
            }
        }
        return bestTrack;
    }

    private boolean mTrackIsExplicit = false;
    private boolean mVisibilityIsExplicit = false;

    /** @hide - should be called from anchor thread */
    public void selectDefaultTrack() {
        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
    }

    private void doSelectDefaultTrack() {
        if (mTrackIsExplicit) {
            // If track selection is explicit, but visibility
            // is not, it falls back to the captioning setting
            if (!mVisibilityIsExplicit) {
                if (mCaptioningManager.isEnabled() ||
                    (mSelectedTrack != null &&
                     mSelectedTrack.getFormat().getInteger(
                            MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
                    show();
                } else if (mSelectedTrack != null
                        && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
                    hide();
                }
                mVisibilityIsExplicit = false;
            }
            return;
        }

        // We can have a default (forced) track even if captioning
        // is not enabled.  This is handled by getDefaultTrack().
        // Show this track unless subtitles were explicitly hidden.
        SubtitleTrack track = getDefaultTrack();
        if (track != null) {
            selectTrack(track);
            mTrackIsExplicit = false;
            if (!mVisibilityIsExplicit) {
                show();
                mVisibilityIsExplicit = false;
            }
        }
    }

    /** @hide - must be called from anchor thread */
    @UnsupportedAppUsage
    public void reset() {
        checkAnchorLooper();
        hide();
        selectTrack(null);
        mTracks.clear();
        mTrackIsExplicit = false;
        mVisibilityIsExplicit = false;
        mCaptioningManager.removeCaptioningChangeListener(
                mCaptioningChangeListener);
    }

    /**
     * Adds a new, external subtitle track to the manager.
     *
     * @param format the format of the track that will include at least
     *               the MIME type {@link MediaFormat@KEY_MIME}.
     * @return the created {@link SubtitleTrack} object
     */
    public SubtitleTrack addTrack(MediaFormat format) {
        synchronized(mRenderers) {
            for (Renderer renderer: mRenderers) {
                if (renderer.supports(format)) {
                    SubtitleTrack track = renderer.createTrack(format);
                    if (track != null) {
                        synchronized(mTracks) {
                            if (mTracks.size() == 0) {
                                mCaptioningManager.addCaptioningChangeListener(
                                        mCaptioningChangeListener);
                            }
                            mTracks.add(track);
                        }
                        return track;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Show the selected (or default) subtitle track.
     *
     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
     */
    @UnsupportedAppUsage
    public void show() {
        processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
    }

    private void doShow() {
        mShowing = true;
        mVisibilityIsExplicit = true;
        if (mSelectedTrack != null) {
            mSelectedTrack.show();
        }
    }

    /**
     * Hide the selected (or default) subtitle track.
     *
     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
     */
    @UnsupportedAppUsage
    public void hide() {
        processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
    }

    private void doHide() {
        mVisibilityIsExplicit = true;
        if (mSelectedTrack != null) {
            mSelectedTrack.hide();
        }
        mShowing = false;
    }

    /**
     * Interface for supporting a single or multiple subtitle types in {@link
     * MediaPlayer}.
     */
    public abstract static class Renderer {
        /**
         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
         * subtitle track is detected, to see if it should use this object to
         * parse and display this subtitle track.
         *
         * @param format the format of the track that will include at least
         *               the MIME type {@link MediaFormat@KEY_MIME}.
         *
         * @return true if and only if the track format is supported by this
         * renderer
         */
        public abstract boolean supports(MediaFormat format);

        /**
         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
         * subtitle track that was detected and is supported by this object to
         * create a {@link SubtitleTrack} object.  This object will be created
         * for each track that was found.  If the track is selected for display,
         * this object will be used to parse and display the track data.
         *
         * @param format the format of the track that will include at least
         *               the MIME type {@link MediaFormat@KEY_MIME}.
         * @return a {@link SubtitleTrack} object that will be used to parse
         * and render the subtitle track.
         */
        public abstract SubtitleTrack createTrack(MediaFormat format);
    }

    /**
     * Add support for a subtitle format in {@link MediaPlayer}.
     *
     * @param renderer a {@link SubtitleController.Renderer} object that adds
     *                 support for a subtitle format.
     */
    @UnsupportedAppUsage
    public void registerRenderer(Renderer renderer) {
        synchronized(mRenderers) {
            // TODO how to get available renderers in the system
            if (!mRenderers.contains(renderer)) {
                // TODO should added renderers override existing ones (to allow replacing?)
                mRenderers.add(renderer);
            }
        }
    }

    /** @hide */
    public boolean hasRendererFor(MediaFormat format) {
        synchronized(mRenderers) {
            // TODO how to get available renderers in the system
            for (Renderer renderer: mRenderers) {
                if (renderer.supports(format)) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * Subtitle anchor, an object that is able to display a subtitle renderer,
     * e.g. a VideoView.
     */
    public interface Anchor {
        /**
         * Anchor should use the supplied subtitle rendering widget, or
         * none if it is null.
         * @hide
         */
        public void setSubtitleWidget(RenderingWidget subtitleWidget);

        /**
         * Anchors provide the looper on which all track visibility changes
         * (track.show/hide, setSubtitleWidget) will take place.
         * @hide
         */
        public Looper getSubtitleLooper();
    }

    private Anchor mAnchor;

    /**
     *  @hide - called from anchor's looper (if any, both when unsetting and
     *  setting)
     */
    public void setAnchor(Anchor anchor) {
        if (mAnchor == anchor) {
            return;
        }

        if (mAnchor != null) {
            checkAnchorLooper();
            mAnchor.setSubtitleWidget(null);
        }
        mAnchor = anchor;
        mHandler = null;
        if (mAnchor != null) {
            mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
            checkAnchorLooper();
            mAnchor.setSubtitleWidget(getRenderingWidget());
        }
    }

    private void checkAnchorLooper() {
        assert mHandler != null : "Should have a looper already";
        assert Looper.myLooper() == mHandler.getLooper() : "Must be called from the anchor's looper";
    }

    private void processOnAnchor(Message m) {
        assert mHandler != null : "Should have a looper already";
        if (Looper.myLooper() == mHandler.getLooper()) {
            mHandler.dispatchMessage(m);
        } else {
            mHandler.sendMessage(m);
        }
    }

    public interface Listener {
        /**
         * Called when a subtitle track has been selected.
         *
         * @param track selected subtitle track or null
         * @hide
         */
        public void onSubtitleTrackSelected(SubtitleTrack track);
    }

    private Listener mListener;
}
