/*
 * 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 android.media;

import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.accessibility.CaptioningManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** @hide */
public class TtmlRenderer extends SubtitleController.Renderer {
    private final Context mContext;

    private static final String MEDIA_MIMETYPE_TEXT_TTML = "application/ttml+xml";

    private TtmlRenderingWidget mRenderingWidget;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public TtmlRenderer(Context context) {
        mContext = context;
    }

    @Override
    public boolean supports(MediaFormat format) {
        if (format.containsKey(MediaFormat.KEY_MIME)) {
            return format.getString(MediaFormat.KEY_MIME).equals(MEDIA_MIMETYPE_TEXT_TTML);
        }
        return false;
    }

    @Override
    public SubtitleTrack createTrack(MediaFormat format) {
        if (mRenderingWidget == null) {
            mRenderingWidget = new TtmlRenderingWidget(mContext);
        }
        return new TtmlTrack(mRenderingWidget, format);
    }
}

/**
 * A class which provides utillity methods for TTML parsing.
 *
 * @hide
 */
final class TtmlUtils {
    public static final String TAG_TT = "tt";
    public static final String TAG_HEAD = "head";
    public static final String TAG_BODY = "body";
    public static final String TAG_DIV = "div";
    public static final String TAG_P = "p";
    public static final String TAG_SPAN = "span";
    public static final String TAG_BR = "br";
    public static final String TAG_STYLE = "style";
    public static final String TAG_STYLING = "styling";
    public static final String TAG_LAYOUT = "layout";
    public static final String TAG_REGION = "region";
    public static final String TAG_METADATA = "metadata";
    public static final String TAG_SMPTE_IMAGE = "smpte:image";
    public static final String TAG_SMPTE_DATA = "smpte:data";
    public static final String TAG_SMPTE_INFORMATION = "smpte:information";
    public static final String PCDATA = "#pcdata";
    public static final String ATTR_BEGIN = "begin";
    public static final String ATTR_DURATION = "dur";
    public static final String ATTR_END = "end";
    public static final long INVALID_TIMESTAMP = Long.MAX_VALUE;

    /**
     * Time expression RE according to the spec:
     * http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression
     */
    private static final Pattern CLOCK_TIME = Pattern.compile(
            "^([0-9][0-9]+):([0-9][0-9]):([0-9][0-9])"
            + "(?:(\\.[0-9]+)|:([0-9][0-9])(?:\\.([0-9]+))?)?$");

    private static final Pattern OFFSET_TIME = Pattern.compile(
            "^([0-9]+(?:\\.[0-9]+)?)(h|m|s|ms|f|t)$");

    private TtmlUtils() {
    }

    /**
     * Parses the given time expression and returns a timestamp in millisecond.
     * <p>
     * For the format of the time expression, please refer <a href=
     * "http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression">timeExpression</a>
     *
     * @param time A string which includes time expression.
     * @param frameRate the framerate of the stream.
     * @param subframeRate the sub-framerate of the stream
     * @param tickRate the tick rate of the stream.
     * @return the parsed timestamp in micro-second.
     * @throws NumberFormatException if the given string does not match to the
     *             format.
     */
    public static long parseTimeExpression(String time, int frameRate, int subframeRate,
            int tickRate) throws NumberFormatException {
        Matcher matcher = CLOCK_TIME.matcher(time);
        if (matcher.matches()) {
            String hours = matcher.group(1);
            double durationSeconds = Long.parseLong(hours) * 3600;
            String minutes = matcher.group(2);
            durationSeconds += Long.parseLong(minutes) * 60;
            String seconds = matcher.group(3);
            durationSeconds += Long.parseLong(seconds);
            String fraction = matcher.group(4);
            durationSeconds += (fraction != null) ? Double.parseDouble(fraction) : 0;
            String frames = matcher.group(5);
            durationSeconds += (frames != null) ? ((double)Long.parseLong(frames)) / frameRate : 0;
            String subframes = matcher.group(6);
            durationSeconds += (subframes != null) ? ((double)Long.parseLong(subframes))
                    / subframeRate / frameRate
                    : 0;
            return (long)(durationSeconds * 1000);
        }
        matcher = OFFSET_TIME.matcher(time);
        if (matcher.matches()) {
            String timeValue = matcher.group(1);
            double value = Double.parseDouble(timeValue);
            String unit = matcher.group(2);
            if (unit.equals("h")) {
                value *= 3600L * 1000000L;
            } else if (unit.equals("m")) {
                value *= 60 * 1000000;
            } else if (unit.equals("s")) {
                value *= 1000000;
            } else if (unit.equals("ms")) {
                value *= 1000;
            } else if (unit.equals("f")) {
                value = value / frameRate * 1000000;
            } else if (unit.equals("t")) {
                value = value / tickRate * 1000000;
            }
            return (long)value;
        }
        throw new NumberFormatException("Malformed time expression : " + time);
    }

    /**
     * Applies <a href
     * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
     * default space policy</a> to the given string.
     *
     * @param in A string to apply the policy.
     */
    public static String applyDefaultSpacePolicy(String in) {
        return applySpacePolicy(in, true);
    }

    /**
     * Applies the space policy to the given string. This applies <a href
     * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
     * default space policy</a> with linefeed-treatment as treat-as-space
     * or preserve.
     *
     * @param in A string to apply the policy.
     * @param treatLfAsSpace Whether convert line feeds to spaces or not.
     */
    public static String applySpacePolicy(String in, boolean treatLfAsSpace) {
        // Removes CR followed by LF. ref:
        // http://www.w3.org/TR/xml/#sec-line-ends
        String crRemoved = in.replaceAll("\r\n", "\n");
        // Apply suppress-at-line-break="auto" and
        // white-space-treatment="ignore-if-surrounding-linefeed"
        String spacesNeighboringLfRemoved = crRemoved.replaceAll(" *\n *", "\n");
        // Apply linefeed-treatment="treat-as-space"
        String lfToSpace = treatLfAsSpace ? spacesNeighboringLfRemoved.replaceAll("\n", " ")
                : spacesNeighboringLfRemoved;
        // Apply white-space-collapse="true"
        String spacesCollapsed = lfToSpace.replaceAll("[ \t\\x0B\f\r]+", " ");
        return spacesCollapsed;
    }

    /**
     * Returns the timed text for the given time period.
     *
     * @param root The root node of the TTML document.
     * @param startUs The start time of the time period in microsecond.
     * @param endUs The end time of the time period in microsecond.
     */
    public static String extractText(TtmlNode root, long startUs, long endUs) {
        StringBuilder text = new StringBuilder();
        extractText(root, startUs, endUs, text, false);
        return text.toString().replaceAll("\n$", "");
    }

    private static void extractText(TtmlNode node, long startUs, long endUs, StringBuilder out,
            boolean inPTag) {
        if (node.mName.equals(TtmlUtils.PCDATA) && inPTag) {
            out.append(node.mText);
        } else if (node.mName.equals(TtmlUtils.TAG_BR) && inPTag) {
            out.append("\n");
        } else if (node.mName.equals(TtmlUtils.TAG_METADATA)) {
            // do nothing.
        } else if (node.isActive(startUs, endUs)) {
            boolean pTag = node.mName.equals(TtmlUtils.TAG_P);
            int length = out.length();
            for (int i = 0; i < node.mChildren.size(); ++i) {
                extractText(node.mChildren.get(i), startUs, endUs, out, pTag || inPTag);
            }
            if (pTag && length != out.length()) {
                out.append("\n");
            }
        }
    }

    /**
     * Returns a TTML fragment string for the given time period.
     *
     * @param root The root node of the TTML document.
     * @param startUs The start time of the time period in microsecond.
     * @param endUs The end time of the time period in microsecond.
     */
    public static String extractTtmlFragment(TtmlNode root, long startUs, long endUs) {
        StringBuilder fragment = new StringBuilder();
        extractTtmlFragment(root, startUs, endUs, fragment);
        return fragment.toString();
    }

    private static void extractTtmlFragment(TtmlNode node, long startUs, long endUs,
            StringBuilder out) {
        if (node.mName.equals(TtmlUtils.PCDATA)) {
            out.append(node.mText);
        } else if (node.mName.equals(TtmlUtils.TAG_BR)) {
            out.append("<br/>");
        } else if (node.isActive(startUs, endUs)) {
            out.append("<");
            out.append(node.mName);
            out.append(node.mAttributes);
            out.append(">");
            for (int i = 0; i < node.mChildren.size(); ++i) {
                extractTtmlFragment(node.mChildren.get(i), startUs, endUs, out);
            }
            out.append("</");
            out.append(node.mName);
            out.append(">");
        }
    }
}

/**
 * A container class which represents a cue in TTML.
 * @hide
 */
class TtmlCue extends SubtitleTrack.Cue {
    public String mText;
    public String mTtmlFragment;

    public TtmlCue(long startTimeMs, long endTimeMs, String text, String ttmlFragment) {
        this.mStartTimeMs = startTimeMs;
        this.mEndTimeMs = endTimeMs;
        this.mText = text;
        this.mTtmlFragment = ttmlFragment;
    }
}

/**
 * A container class which represents a node in TTML.
 *
 * @hide
 */
class TtmlNode {
    public final String mName;
    public final String mAttributes;
    public final TtmlNode mParent;
    public final String mText;
    public final List<TtmlNode> mChildren = new ArrayList<TtmlNode>();
    public final long mRunId;
    public final long mStartTimeMs;
    public final long mEndTimeMs;

    public TtmlNode(String name, String attributes, String text, long startTimeMs, long endTimeMs,
            TtmlNode parent, long runId) {
        this.mName = name;
        this.mAttributes = attributes;
        this.mText = text;
        this.mStartTimeMs = startTimeMs;
        this.mEndTimeMs = endTimeMs;
        this.mParent = parent;
        this.mRunId = runId;
    }

    /**
     * Check if this node is active in the given time range.
     *
     * @param startTimeMs The start time of the range to check in microsecond.
     * @param endTimeMs The end time of the range to check in microsecond.
     * @return return true if the given range overlaps the time range of this
     *         node.
     */
    public boolean isActive(long startTimeMs, long endTimeMs) {
        return this.mEndTimeMs > startTimeMs && this.mStartTimeMs < endTimeMs;
    }
}

/**
 * A simple TTML parser (http://www.w3.org/TR/ttaf1-dfxp/) which supports DFXP
 * presentation profile.
 * <p>
 * Supported features in this parser are:
 * <ul>
 * <li>content
 * <li>core
 * <li>presentation
 * <li>profile
 * <li>structure
 * <li>time-offset
 * <li>timing
 * <li>tickRate
 * <li>time-clock-with-frames
 * <li>time-clock
 * <li>time-offset-with-frames
 * <li>time-offset-with-ticks
 * </ul>
 * </p>
 *
 * @hide
 */
class TtmlParser {
    static final String TAG = "TtmlParser";

    // TODO: read and apply the following attributes if specified.
    private static final int DEFAULT_FRAMERATE = 30;
    private static final int DEFAULT_SUBFRAMERATE = 1;
    private static final int DEFAULT_TICKRATE = 1;

    private XmlPullParser mParser;
    private final TtmlNodeListener mListener;
    private long mCurrentRunId;

    public TtmlParser(TtmlNodeListener listener) {
        mListener = listener;
    }

    /**
     * Parse TTML data. Once this is called, all the previous data are
     * reset and it starts parsing for the given text.
     *
     * @param ttmlText TTML text to parse.
     * @throws XmlPullParserException
     * @throws IOException
     */
    public void parse(String ttmlText, long runId) throws XmlPullParserException, IOException {
        mParser = null;
        mCurrentRunId = runId;
        loadParser(ttmlText);
        parseTtml();
    }

    private void loadParser(String ttmlFragment) throws XmlPullParserException {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        mParser = factory.newPullParser();
        StringReader in = new StringReader(ttmlFragment);
        mParser.setInput(in);
    }

    private void extractAttribute(XmlPullParser parser, int i, StringBuilder out) {
        out.append(" ");
        out.append(parser.getAttributeName(i));
        out.append("=\"");
        out.append(parser.getAttributeValue(i));
        out.append("\"");
    }

    private void parseTtml() throws XmlPullParserException, IOException {
        LinkedList<TtmlNode> nodeStack = new LinkedList<TtmlNode>();
        int depthInUnsupportedTag = 0;
        boolean active = true;
        while (!isEndOfDoc()) {
            int eventType = mParser.getEventType();
            TtmlNode parent = nodeStack.peekLast();
            if (active) {
                if (eventType == XmlPullParser.START_TAG) {
                    if (!isSupportedTag(mParser.getName())) {
                        Log.w(TAG, "Unsupported tag " + mParser.getName() + " is ignored.");
                        depthInUnsupportedTag++;
                        active = false;
                    } else {
                        TtmlNode node = parseNode(parent);
                        nodeStack.addLast(node);
                        if (parent != null) {
                            parent.mChildren.add(node);
                        }
                    }
                } else if (eventType == XmlPullParser.TEXT) {
                    String text = TtmlUtils.applyDefaultSpacePolicy(mParser.getText());
                    if (!TextUtils.isEmpty(text)) {
                        parent.mChildren.add(new TtmlNode(
                                TtmlUtils.PCDATA, "", text, 0, TtmlUtils.INVALID_TIMESTAMP,
                                parent, mCurrentRunId));

                    }
                } else if (eventType == XmlPullParser.END_TAG) {
                    if (mParser.getName().equals(TtmlUtils.TAG_P)) {
                        mListener.onTtmlNodeParsed(nodeStack.getLast());
                    } else if (mParser.getName().equals(TtmlUtils.TAG_TT)) {
                        mListener.onRootNodeParsed(nodeStack.getLast());
                    }
                    nodeStack.removeLast();
                }
            } else {
                if (eventType == XmlPullParser.START_TAG) {
                    depthInUnsupportedTag++;
                } else if (eventType == XmlPullParser.END_TAG) {
                    depthInUnsupportedTag--;
                    if (depthInUnsupportedTag == 0) {
                        active = true;
                    }
                }
            }
            mParser.next();
        }
    }

    private TtmlNode parseNode(TtmlNode parent) throws XmlPullParserException, IOException {
        int eventType = mParser.getEventType();
        if (!(eventType == XmlPullParser.START_TAG)) {
            return null;
        }
        StringBuilder attrStr = new StringBuilder();
        long start = 0;
        long end = TtmlUtils.INVALID_TIMESTAMP;
        long dur = 0;
        for (int i = 0; i < mParser.getAttributeCount(); ++i) {
            String attr = mParser.getAttributeName(i);
            String value = mParser.getAttributeValue(i);
            // TODO: check if it's safe to ignore the namespace of attributes as follows.
            attr = attr.replaceFirst("^.*:", "");
            if (attr.equals(TtmlUtils.ATTR_BEGIN)) {
                start = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE,
                        DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE);
            } else if (attr.equals(TtmlUtils.ATTR_END)) {
                end = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
                        DEFAULT_TICKRATE);
            } else if (attr.equals(TtmlUtils.ATTR_DURATION)) {
                dur = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
                        DEFAULT_TICKRATE);
            } else {
                extractAttribute(mParser, i, attrStr);
            }
        }
        if (parent != null) {
            start += parent.mStartTimeMs;
            if (end != TtmlUtils.INVALID_TIMESTAMP) {
                end += parent.mStartTimeMs;
            }
        }
        if (dur > 0) {
            if (end != TtmlUtils.INVALID_TIMESTAMP) {
                Log.e(TAG, "'dur' and 'end' attributes are defined at the same time." +
                        "'end' value is ignored.");
            }
            end = start + dur;
        }
        if (parent != null) {
            // If the end time remains unspecified, then the end point is
            // interpreted as the end point of the external time interval.
            if (end == TtmlUtils.INVALID_TIMESTAMP &&
                    parent.mEndTimeMs != TtmlUtils.INVALID_TIMESTAMP &&
                    end > parent.mEndTimeMs) {
                end = parent.mEndTimeMs;
            }
        }
        TtmlNode node = new TtmlNode(mParser.getName(), attrStr.toString(), null, start, end,
                parent, mCurrentRunId);
        return node;
    }

    private boolean isEndOfDoc() throws XmlPullParserException {
        return (mParser.getEventType() == XmlPullParser.END_DOCUMENT);
    }

    private static boolean isSupportedTag(String tag) {
        if (tag.equals(TtmlUtils.TAG_TT) || tag.equals(TtmlUtils.TAG_HEAD) ||
                tag.equals(TtmlUtils.TAG_BODY) || tag.equals(TtmlUtils.TAG_DIV) ||
                tag.equals(TtmlUtils.TAG_P) || tag.equals(TtmlUtils.TAG_SPAN) ||
                tag.equals(TtmlUtils.TAG_BR) || tag.equals(TtmlUtils.TAG_STYLE) ||
                tag.equals(TtmlUtils.TAG_STYLING) || tag.equals(TtmlUtils.TAG_LAYOUT) ||
                tag.equals(TtmlUtils.TAG_REGION) || tag.equals(TtmlUtils.TAG_METADATA) ||
                tag.equals(TtmlUtils.TAG_SMPTE_IMAGE) || tag.equals(TtmlUtils.TAG_SMPTE_DATA) ||
                tag.equals(TtmlUtils.TAG_SMPTE_INFORMATION)) {
            return true;
        }
        return false;
    }
}

/** @hide */
interface TtmlNodeListener {
    void onTtmlNodeParsed(TtmlNode node);
    void onRootNodeParsed(TtmlNode node);
}

/** @hide */
class TtmlTrack extends SubtitleTrack implements TtmlNodeListener {
    private static final String TAG = "TtmlTrack";

    private final TtmlParser mParser = new TtmlParser(this);
    private final TtmlRenderingWidget mRenderingWidget;
    private String mParsingData;
    private Long mCurrentRunID;

    private final LinkedList<TtmlNode> mTtmlNodes;
    private final TreeSet<Long> mTimeEvents;
    private TtmlNode mRootNode;

    TtmlTrack(TtmlRenderingWidget renderingWidget, MediaFormat format) {
        super(format);

        mTtmlNodes = new LinkedList<TtmlNode>();
        mTimeEvents = new TreeSet<Long>();
        mRenderingWidget = renderingWidget;
        mParsingData = "";
    }

    @Override
    public TtmlRenderingWidget getRenderingWidget() {
        return mRenderingWidget;
    }

    @Override
    public void onData(byte[] data, boolean eos, long runID) {
        try {
            // TODO: handle UTF-8 conversion properly
            String str = new String(data, "UTF-8");

            // implement intermixing restriction for TTML.
            synchronized(mParser) {
                if (mCurrentRunID != null && runID != mCurrentRunID) {
                    throw new IllegalStateException(
                            "Run #" + mCurrentRunID +
                            " in progress.  Cannot process run #" + runID);
                }
                mCurrentRunID = runID;
                mParsingData += str;
                if (eos) {
                    try {
                        mParser.parse(mParsingData, mCurrentRunID);
                    } catch (XmlPullParserException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    finishedRun(runID);
                    mParsingData = "";
                    mCurrentRunID = null;
                }
            }
        } catch (java.io.UnsupportedEncodingException e) {
            Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
        }
    }

    @Override
    public void onTtmlNodeParsed(TtmlNode node) {
        mTtmlNodes.addLast(node);
        addTimeEvents(node);
    }

    @Override
    public void onRootNodeParsed(TtmlNode node) {
        mRootNode = node;
        TtmlCue cue = null;
        while ((cue = getNextResult()) != null) {
            addCue(cue);
        }
        mRootNode = null;
        mTtmlNodes.clear();
        mTimeEvents.clear();
    }

    @Override
    public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
        if (!mVisible) {
            // don't keep the state if we are not visible
            return;
        }

        if (DEBUG && mTimeProvider != null) {
            try {
                Log.d(TAG, "at " +
                        (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
                        " ms the active cues are:");
            } catch (IllegalStateException e) {
                Log.d(TAG, "at (illegal state) the active cues are:");
            }
        }

        mRenderingWidget.setActiveCues(activeCues);
    }

    /**
     * Returns a {@link TtmlCue} in the presentation time order.
     * {@code null} is returned if there is no more timed text to show.
     */
    public TtmlCue getNextResult() {
        while (mTimeEvents.size() >= 2) {
            long start = mTimeEvents.pollFirst();
            long end = mTimeEvents.first();
            List<TtmlNode> activeCues = getActiveNodes(start, end);
            if (!activeCues.isEmpty()) {
                return new TtmlCue(start, end,
                        TtmlUtils.applySpacePolicy(TtmlUtils.extractText(
                                mRootNode, start, end), false),
                        TtmlUtils.extractTtmlFragment(mRootNode, start, end));
            }
        }
        return null;
    }

    private void addTimeEvents(TtmlNode node) {
        mTimeEvents.add(node.mStartTimeMs);
        mTimeEvents.add(node.mEndTimeMs);
        for (int i = 0; i < node.mChildren.size(); ++i) {
            addTimeEvents(node.mChildren.get(i));
        }
    }

    private List<TtmlNode> getActiveNodes(long startTimeUs, long endTimeUs) {
        List<TtmlNode> activeNodes = new ArrayList<TtmlNode>();
        for (int i = 0; i < mTtmlNodes.size(); ++i) {
            TtmlNode node = mTtmlNodes.get(i);
            if (node.isActive(startTimeUs, endTimeUs)) {
                activeNodes.add(node);
            }
        }
        return activeNodes;
    }
}

/**
 * Widget capable of rendering TTML captions.
 *
 * @hide
 */
class TtmlRenderingWidget extends LinearLayout implements SubtitleTrack.RenderingWidget {

    /** Callback for rendering changes. */
    private OnChangedListener mListener;
    private final TextView mTextView;

    public TtmlRenderingWidget(Context context) {
        this(context, null);
    }

    public TtmlRenderingWidget(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        // Cannot render text over video when layer type is hardware.
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        CaptioningManager captionManager = (CaptioningManager) context.getSystemService(
                Context.CAPTIONING_SERVICE);
        mTextView = new TextView(context);
        mTextView.setTextColor(captionManager.getUserStyle().foregroundColor);
        addView(mTextView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
    }

    @Override
    public void setOnChangedListener(OnChangedListener listener) {
        mListener = listener;
    }

    @Override
    public void setSize(int width, int height) {
        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

        measure(widthSpec, heightSpec);
        layout(0, 0, width, height);
    }

    @Override
    public void setVisible(boolean visible) {
        if (visible) {
            setVisibility(View.VISIBLE);
        } else {
            setVisibility(View.GONE);
        }
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }

    public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
        final int count = activeCues.size();
        String subtitleText = "";
        for (int i = 0; i < count; i++) {
            TtmlCue cue = (TtmlCue) activeCues.get(i);
            subtitleText += cue.mText + "\n";
        }
        mTextView.setText(subtitleText);

        if (mListener != null) {
            mListener.onChanged(this);
        }
    }
}
