/*
 * 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.content.Context;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
import android.widget.LinearLayout;

import com.android.internal.widget.SubtitleView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

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

    private WebVttRenderingWidget mRenderingWidget;

    public WebVttRenderer(Context context) {
        mContext = context;
    }

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

    @Override
    public SubtitleTrack createTrack(MediaFormat format) {
        if (mRenderingWidget == null) {
            mRenderingWidget = new WebVttRenderingWidget(mContext);
        }

        return new WebVttTrack(mRenderingWidget, format);
    }
}

/** @hide */
class TextTrackCueSpan {
    long mTimestampMs;
    boolean mEnabled;
    String mText;
    TextTrackCueSpan(String text, long timestamp) {
        mTimestampMs = timestamp;
        mText = text;
        // spans with timestamp will be enabled by Cue.onTime
        mEnabled = (mTimestampMs < 0);
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof TextTrackCueSpan)) {
            return false;
        }
        TextTrackCueSpan span = (TextTrackCueSpan) o;
        return mTimestampMs == span.mTimestampMs &&
                mText.equals(span.mText);
    }
}

/**
 * @hide
 *
 * Extract all text without style, but with timestamp spans.
 */
class UnstyledTextExtractor implements Tokenizer.OnTokenListener {
    StringBuilder mLine = new StringBuilder();
    Vector<TextTrackCueSpan[]> mLines = new Vector<TextTrackCueSpan[]>();
    Vector<TextTrackCueSpan> mCurrentLine = new Vector<TextTrackCueSpan>();
    long mLastTimestamp;

    UnstyledTextExtractor() {
        init();
    }

    private void init() {
        mLine.delete(0, mLine.length());
        mLines.clear();
        mCurrentLine.clear();
        mLastTimestamp = -1;
    }

    @Override
    public void onData(String s) {
        mLine.append(s);
    }

    @Override
    public void onStart(String tag, String[] classes, String annotation) { }

    @Override
    public void onEnd(String tag) { }

    @Override
    public void onTimeStamp(long timestampMs) {
        // finish any prior span
        if (mLine.length() > 0 && timestampMs != mLastTimestamp) {
            mCurrentLine.add(
                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
            mLine.delete(0, mLine.length());
        }
        mLastTimestamp = timestampMs;
    }

    @Override
    public void onLineEnd() {
        // finish any pending span
        if (mLine.length() > 0) {
            mCurrentLine.add(
                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
            mLine.delete(0, mLine.length());
        }

        TextTrackCueSpan[] spans = new TextTrackCueSpan[mCurrentLine.size()];
        mCurrentLine.toArray(spans);
        mCurrentLine.clear();
        mLines.add(spans);
    }

    public TextTrackCueSpan[][] getText() {
        // for politeness, finish last cue-line if it ends abruptly
        if (mLine.length() > 0 || mCurrentLine.size() > 0) {
            onLineEnd();
        }
        TextTrackCueSpan[][] lines = new TextTrackCueSpan[mLines.size()][];
        mLines.toArray(lines);
        init();
        return lines;
    }
}

/**
 * @hide
 *
 * Tokenizer tokenizes the WebVTT Cue Text into tags and data
 */
class Tokenizer {
    private static final String TAG = "Tokenizer";
    private TokenizerPhase mPhase;
    private TokenizerPhase mDataTokenizer;
    private TokenizerPhase mTagTokenizer;

    private OnTokenListener mListener;
    private String mLine;
    private int mHandledLen;

    interface TokenizerPhase {
        TokenizerPhase start();
        void tokenize();
    }

    class DataTokenizer implements TokenizerPhase {
        // includes both WebVTT data && escape state
        private StringBuilder mData;

        public TokenizerPhase start() {
            mData = new StringBuilder();
            return this;
        }

        private boolean replaceEscape(String escape, String replacement, int pos) {
            if (mLine.startsWith(escape, pos)) {
                mData.append(mLine.substring(mHandledLen, pos));
                mData.append(replacement);
                mHandledLen = pos + escape.length();
                pos = mHandledLen - 1;
                return true;
            }
            return false;
        }

        @Override
        public void tokenize() {
            int end = mLine.length();
            for (int pos = mHandledLen; pos < mLine.length(); pos++) {
                if (mLine.charAt(pos) == '&') {
                    if (replaceEscape("&amp;", "&", pos) ||
                            replaceEscape("&lt;", "<", pos) ||
                            replaceEscape("&gt;", ">", pos) ||
                            replaceEscape("&lrm;", "\u200e", pos) ||
                            replaceEscape("&rlm;", "\u200f", pos) ||
                            replaceEscape("&nbsp;", "\u00a0", pos)) {
                        continue;
                    }
                } else if (mLine.charAt(pos) == '<') {
                    end = pos;
                    mPhase = mTagTokenizer.start();
                    break;
                }
            }
            mData.append(mLine.substring(mHandledLen, end));
            // yield mData
            mListener.onData(mData.toString());
            mData.delete(0, mData.length());
            mHandledLen = end;
        }
    }

    class TagTokenizer implements TokenizerPhase {
        private boolean mAtAnnotation;
        private String mName, mAnnotation;

        public TokenizerPhase start() {
            mName = mAnnotation = "";
            mAtAnnotation = false;
            return this;
        }

        @Override
        public void tokenize() {
            if (!mAtAnnotation)
                mHandledLen++;
            if (mHandledLen < mLine.length()) {
                String[] parts;
                /**
                 * Collect annotations and end-tags to closing >.  Collect tag
                 * name to closing bracket or next white-space.
                 */
                if (mAtAnnotation || mLine.charAt(mHandledLen) == '/') {
                    parts = mLine.substring(mHandledLen).split(">");
                } else {
                    parts = mLine.substring(mHandledLen).split("[\t\f >]");
                }
                String part = mLine.substring(
                            mHandledLen, mHandledLen + parts[0].length());
                mHandledLen += parts[0].length();

                if (mAtAnnotation) {
                    mAnnotation += " " + part;
                } else {
                    mName = part;
                }
            }

            mAtAnnotation = true;

            if (mHandledLen < mLine.length() && mLine.charAt(mHandledLen) == '>') {
                yield_tag();
                mPhase = mDataTokenizer.start();
                mHandledLen++;
            }
        }

        private void yield_tag() {
            if (mName.startsWith("/")) {
                mListener.onEnd(mName.substring(1));
            } else if (mName.length() > 0 && Character.isDigit(mName.charAt(0))) {
                // timestamp
                try {
                    long timestampMs = WebVttParser.parseTimestampMs(mName);
                    mListener.onTimeStamp(timestampMs);
                } catch (NumberFormatException e) {
                    Log.d(TAG, "invalid timestamp tag: <" + mName + ">");
                }
            } else {
                mAnnotation = mAnnotation.replaceAll("\\s+", " ");
                if (mAnnotation.startsWith(" ")) {
                    mAnnotation = mAnnotation.substring(1);
                }
                if (mAnnotation.endsWith(" ")) {
                    mAnnotation = mAnnotation.substring(0, mAnnotation.length() - 1);
                }

                String[] classes = null;
                int dotAt = mName.indexOf('.');
                if (dotAt >= 0) {
                    classes = mName.substring(dotAt + 1).split("\\.");
                    mName = mName.substring(0, dotAt);
                }
                mListener.onStart(mName, classes, mAnnotation);
            }
        }
    }

    Tokenizer(OnTokenListener listener) {
        mDataTokenizer = new DataTokenizer();
        mTagTokenizer = new TagTokenizer();
        reset();
        mListener = listener;
    }

    void reset() {
        mPhase = mDataTokenizer.start();
    }

    void tokenize(String s) {
        mHandledLen = 0;
        mLine = s;
        while (mHandledLen < mLine.length()) {
            mPhase.tokenize();
        }
        /* we are finished with a line unless we are in the middle of a tag */
        if (!(mPhase instanceof TagTokenizer)) {
            // yield END-OF-LINE
            mListener.onLineEnd();
        }
    }

    interface OnTokenListener {
        void onData(String s);
        void onStart(String tag, String[] classes, String annotation);
        void onEnd(String tag);
        void onTimeStamp(long timestampMs);
        void onLineEnd();
    }
}

/** @hide */
class TextTrackRegion {
    final static int SCROLL_VALUE_NONE      = 300;
    final static int SCROLL_VALUE_SCROLL_UP = 301;

    String mId;
    float mWidth;
    int mLines;
    float mAnchorPointX, mAnchorPointY;
    float mViewportAnchorPointX, mViewportAnchorPointY;
    int mScrollValue;

    TextTrackRegion() {
        mId = "";
        mWidth = 100;
        mLines = 3;
        mAnchorPointX = mViewportAnchorPointX = 0.f;
        mAnchorPointY = mViewportAnchorPointY = 100.f;
        mScrollValue = SCROLL_VALUE_NONE;
    }

    public String toString() {
        StringBuilder res = new StringBuilder(" {id:\"").append(mId)
            .append("\", width:").append(mWidth)
            .append(", lines:").append(mLines)
            .append(", anchorPoint:(").append(mAnchorPointX)
            .append(", ").append(mAnchorPointY)
            .append("), viewportAnchorPoints:").append(mViewportAnchorPointX)
            .append(", ").append(mViewportAnchorPointY)
            .append("), scrollValue:")
            .append(mScrollValue == SCROLL_VALUE_NONE ? "none" :
                    mScrollValue == SCROLL_VALUE_SCROLL_UP ? "scroll_up" :
                    "INVALID")
            .append("}");
        return res.toString();
    }
}

/** @hide */
class TextTrackCue extends SubtitleTrack.Cue {
    final static int WRITING_DIRECTION_HORIZONTAL  = 100;
    final static int WRITING_DIRECTION_VERTICAL_RL = 101;
    final static int WRITING_DIRECTION_VERTICAL_LR = 102;

    final static int ALIGNMENT_MIDDLE = 200;
    final static int ALIGNMENT_START  = 201;
    final static int ALIGNMENT_END    = 202;
    final static int ALIGNMENT_LEFT   = 203;
    final static int ALIGNMENT_RIGHT  = 204;
    private static final String TAG = "TTCue";

    String  mId;
    boolean mPauseOnExit;
    int     mWritingDirection;
    String  mRegionId;
    boolean mSnapToLines;
    Integer mLinePosition;  // null means AUTO
    boolean mAutoLinePosition;
    int     mTextPosition;
    int     mSize;
    int     mAlignment;
    // Vector<String> mText;
    String[] mStrings;
    TextTrackCueSpan[][] mLines;
    TextTrackRegion mRegion;

    TextTrackCue() {
        mId = "";
        mPauseOnExit = false;
        mWritingDirection = WRITING_DIRECTION_HORIZONTAL;
        mRegionId = "";
        mSnapToLines = true;
        mLinePosition = null /* AUTO */;
        mTextPosition = 50;
        mSize = 100;
        mAlignment = ALIGNMENT_MIDDLE;
        mLines = null;
        mRegion = null;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof TextTrackCue)) {
            return false;
        }
        if (this == o) {
            return true;
        }

        try {
            TextTrackCue cue = (TextTrackCue) o;
            boolean res = mId.equals(cue.mId) &&
                    mPauseOnExit == cue.mPauseOnExit &&
                    mWritingDirection == cue.mWritingDirection &&
                    mRegionId.equals(cue.mRegionId) &&
                    mSnapToLines == cue.mSnapToLines &&
                    mAutoLinePosition == cue.mAutoLinePosition &&
                    (mAutoLinePosition || mLinePosition == cue.mLinePosition) &&
                    mTextPosition == cue.mTextPosition &&
                    mSize == cue.mSize &&
                    mAlignment == cue.mAlignment &&
                    mLines.length == cue.mLines.length;
            if (res == true) {
                for (int line = 0; line < mLines.length; line++) {
                    if (!Arrays.equals(mLines[line], cue.mLines[line])) {
                        return false;
                    }
                }
            }
            return res;
        } catch(IncompatibleClassChangeError e) {
            return false;
        }
    }

    public StringBuilder appendStringsToBuilder(StringBuilder builder) {
        if (mStrings == null) {
            builder.append("null");
        } else {
            builder.append("[");
            boolean first = true;
            for (String s: mStrings) {
                if (!first) {
                    builder.append(", ");
                }
                if (s == null) {
                    builder.append("null");
                } else {
                    builder.append("\"");
                    builder.append(s);
                    builder.append("\"");
                }
                first = false;
            }
            builder.append("]");
        }
        return builder;
    }

    public StringBuilder appendLinesToBuilder(StringBuilder builder) {
        if (mLines == null) {
            builder.append("null");
        } else {
            builder.append("[");
            boolean first = true;
            for (TextTrackCueSpan[] spans: mLines) {
                if (!first) {
                    builder.append(", ");
                }
                if (spans == null) {
                    builder.append("null");
                } else {
                    builder.append("\"");
                    boolean innerFirst = true;
                    long lastTimestamp = -1;
                    for (TextTrackCueSpan span: spans) {
                        if (!innerFirst) {
                            builder.append(" ");
                        }
                        if (span.mTimestampMs != lastTimestamp) {
                            builder.append("<")
                                    .append(WebVttParser.timeToString(
                                            span.mTimestampMs))
                                    .append(">");
                            lastTimestamp = span.mTimestampMs;
                        }
                        builder.append(span.mText);
                        innerFirst = false;
                    }
                    builder.append("\"");
                }
                first = false;
            }
            builder.append("]");
        }
        return builder;
    }

    public String toString() {
        StringBuilder res = new StringBuilder();

        res.append(WebVttParser.timeToString(mStartTimeMs))
                .append(" --> ").append(WebVttParser.timeToString(mEndTimeMs))
                .append(" {id:\"").append(mId)
                .append("\", pauseOnExit:").append(mPauseOnExit)
                .append(", direction:")
                .append(mWritingDirection == WRITING_DIRECTION_HORIZONTAL ? "horizontal" :
                        mWritingDirection == WRITING_DIRECTION_VERTICAL_LR ? "vertical_lr" :
                        mWritingDirection == WRITING_DIRECTION_VERTICAL_RL ? "vertical_rl" :
                        "INVALID")
                .append(", regionId:\"").append(mRegionId)
                .append("\", snapToLines:").append(mSnapToLines)
                .append(", linePosition:").append(mAutoLinePosition ? "auto" :
                                                  mLinePosition)
                .append(", textPosition:").append(mTextPosition)
                .append(", size:").append(mSize)
                .append(", alignment:")
                .append(mAlignment == ALIGNMENT_END ? "end" :
                        mAlignment == ALIGNMENT_LEFT ? "left" :
                        mAlignment == ALIGNMENT_MIDDLE ? "middle" :
                        mAlignment == ALIGNMENT_RIGHT ? "right" :
                        mAlignment == ALIGNMENT_START ? "start" : "INVALID")
                .append(", text:");
        appendStringsToBuilder(res).append("}");
        return res.toString();
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }

    @Override
    public void onTime(long timeMs) {
        for (TextTrackCueSpan[] line: mLines) {
            for (TextTrackCueSpan span: line) {
                span.mEnabled = timeMs >= span.mTimestampMs;
            }
        }
    }
}

/**
 *  Supporting July 10 2013 draft version
 *
 *  @hide
 */
class WebVttParser {
    private static final String TAG = "WebVttParser";
    private Phase mPhase;
    private TextTrackCue mCue;
    private Vector<String> mCueTexts;
    private WebVttCueListener mListener;
    private String mBuffer;

    WebVttParser(WebVttCueListener listener) {
        mPhase = mParseStart;
        mBuffer = "";   /* mBuffer contains up to 1 incomplete line */
        mListener = listener;
        mCueTexts = new Vector<String>();
    }

    /* parsePercentageString */
    public static float parseFloatPercentage(String s)
            throws NumberFormatException {
        if (!s.endsWith("%")) {
            throw new NumberFormatException("does not end in %");
        }
        s = s.substring(0, s.length() - 1);
        // parseFloat allows an exponent or a sign
        if (s.matches(".*[^0-9.].*")) {
            throw new NumberFormatException("contains an invalid character");
        }

        try {
            float value = Float.parseFloat(s);
            if (value < 0.0f || value > 100.0f) {
                throw new NumberFormatException("is out of range");
            }
            return value;
        } catch (NumberFormatException e) {
            throw new NumberFormatException("is not a number");
        }
    }

    public static int parseIntPercentage(String s) throws NumberFormatException {
        if (!s.endsWith("%")) {
            throw new NumberFormatException("does not end in %");
        }
        s = s.substring(0, s.length() - 1);
        // parseInt allows "-0" that returns 0, so check for non-digits
        if (s.matches(".*[^0-9].*")) {
            throw new NumberFormatException("contains an invalid character");
        }

        try {
            int value = Integer.parseInt(s);
            if (value < 0 || value > 100) {
                throw new NumberFormatException("is out of range");
            }
            return value;
        } catch (NumberFormatException e) {
            throw new NumberFormatException("is not a number");
        }
    }

    public static long parseTimestampMs(String s) throws NumberFormatException {
        if (!s.matches("(\\d+:)?[0-5]\\d:[0-5]\\d\\.\\d{3}")) {
            throw new NumberFormatException("has invalid format");
        }

        String[] parts = s.split("\\.", 2);
        long value = 0;
        for (String group: parts[0].split(":")) {
            value = value * 60 + Long.parseLong(group);
        }
        return value * 1000 + Long.parseLong(parts[1]);
    }

    public static String timeToString(long timeMs) {
        return String.format("%d:%02d:%02d.%03d",
                timeMs / 3600000, (timeMs / 60000) % 60,
                (timeMs / 1000) % 60, timeMs % 1000);
    }

    public void parse(String s) {
        boolean trailingCR = false;
        mBuffer = (mBuffer + s.replace("\0", "\ufffd")).replace("\r\n", "\n");

        /* keep trailing '\r' in case matching '\n' arrives in next packet */
        if (mBuffer.endsWith("\r")) {
            trailingCR = true;
            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
        }

        String[] lines = mBuffer.split("[\r\n]");
        for (int i = 0; i < lines.length - 1; i++) {
            mPhase.parse(lines[i]);
        }

        mBuffer = lines[lines.length - 1];
        if (trailingCR)
            mBuffer += "\r";
    }

    public void eos() {
        if (mBuffer.endsWith("\r")) {
            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
        }

        mPhase.parse(mBuffer);
        mBuffer = "";

        yieldCue();
        mPhase = mParseStart;
    }

    public void yieldCue() {
        if (mCue != null && mCueTexts.size() > 0) {
            mCue.mStrings = new String[mCueTexts.size()];
            mCueTexts.toArray(mCue.mStrings);
            mCueTexts.clear();
            mListener.onCueParsed(mCue);
        }
        mCue = null;
    }

    interface Phase {
        void parse(String line);
    }

    final private Phase mSkipRest = new Phase() {
        @Override
        public void parse(String line) { }
    };

    final private Phase mParseStart = new Phase() { // 5-9
        @Override
        public void parse(String line) {
            if (line.startsWith("\ufeff")) {
                line = line.substring(1);
            }
            if (!line.equals("WEBVTT") &&
                    !line.startsWith("WEBVTT ") &&
                    !line.startsWith("WEBVTT\t")) {
                log_warning("Not a WEBVTT header", line);
                mPhase = mSkipRest;
            } else {
                mPhase = mParseHeader;
            }
        }
    };

    final private Phase mParseHeader = new Phase() { // 10-13
        TextTrackRegion parseRegion(String s) {
            TextTrackRegion region = new TextTrackRegion();
            for (String setting: s.split(" +")) {
                int equalAt = setting.indexOf('=');
                if (equalAt <= 0 || equalAt == setting.length() - 1) {
                    continue;
                }

                String name = setting.substring(0, equalAt);
                String value = setting.substring(equalAt + 1);
                if (name.equals("id")) {
                    region.mId = value;
                } else if (name.equals("width")) {
                    try {
                        region.mWidth = parseFloatPercentage(value);
                    } catch (NumberFormatException e) {
                        log_warning("region setting", name,
                                "has invalid value", e.getMessage(), value);
                    }
                } else if (name.equals("lines")) {
                    if (value.matches(".*[^0-9].*")) {
                        log_warning("lines", name, "contains an invalid character", value);
                    } else {
                        try {
                            region.mLines = Integer.parseInt(value);
                            assert(region.mLines >= 0); // lines contains only digits
                        } catch (NumberFormatException e) {
                            log_warning("region setting", name, "is not numeric", value);
                        }
                    }
                } else if (name.equals("regionanchor") ||
                           name.equals("viewportanchor")) {
                    int commaAt = value.indexOf(",");
                    if (commaAt < 0) {
                        log_warning("region setting", name, "contains no comma", value);
                        continue;
                    }

                    String anchorX = value.substring(0, commaAt);
                    String anchorY = value.substring(commaAt + 1);
                    float x, y;

                    try {
                        x = parseFloatPercentage(anchorX);
                    } catch (NumberFormatException e) {
                        log_warning("region setting", name,
                                "has invalid x component", e.getMessage(), anchorX);
                        continue;
                    }
                    try {
                        y = parseFloatPercentage(anchorY);
                    } catch (NumberFormatException e) {
                        log_warning("region setting", name,
                                "has invalid y component", e.getMessage(), anchorY);
                        continue;
                    }

                    if (name.charAt(0) == 'r') {
                        region.mAnchorPointX = x;
                        region.mAnchorPointY = y;
                    } else {
                        region.mViewportAnchorPointX = x;
                        region.mViewportAnchorPointY = y;
                    }
                } else if (name.equals("scroll")) {
                    if (value.equals("up")) {
                        region.mScrollValue =
                            TextTrackRegion.SCROLL_VALUE_SCROLL_UP;
                    } else {
                        log_warning("region setting", name, "has invalid value", value);
                    }
                }
            }
            return region;
        }

        @Override
        public void parse(String line)  {
            if (line.length() == 0) {
                mPhase = mParseCueId;
            } else if (line.contains("-->")) {
                mPhase = mParseCueTime;
                mPhase.parse(line);
            } else {
                int colonAt = line.indexOf(':');
                if (colonAt <= 0 || colonAt >= line.length() - 1) {
                    log_warning("meta data header has invalid format", line);
                }
                String name = line.substring(0, colonAt);
                String value = line.substring(colonAt + 1);

                if (name.equals("Region")) {
                    TextTrackRegion region = parseRegion(value);
                    mListener.onRegionParsed(region);
                }
            }
        }
    };

    final private Phase mParseCueId = new Phase() {
        @Override
        public void parse(String line) {
            if (line.length() == 0) {
                return;
            }

            assert(mCue == null);

            if (line.equals("NOTE") || line.startsWith("NOTE ")) {
                mPhase = mParseCueText;
            }

            mCue = new TextTrackCue();
            mCueTexts.clear();

            mPhase = mParseCueTime;
            if (line.contains("-->")) {
                mPhase.parse(line);
            } else {
                mCue.mId = line;
            }
        }
    };

    final private Phase mParseCueTime = new Phase() {
        @Override
        public void parse(String line) {
            int arrowAt = line.indexOf("-->");
            if (arrowAt < 0) {
                mCue = null;
                mPhase = mParseCueId;
                return;
            }

            String start = line.substring(0, arrowAt).trim();
            // convert only initial and first other white-space to space
            String rest = line.substring(arrowAt + 3)
                    .replaceFirst("^\\s+", "").replaceFirst("\\s+", " ");
            int spaceAt = rest.indexOf(' ');
            String end = spaceAt > 0 ? rest.substring(0, spaceAt) : rest;
            rest = spaceAt > 0 ? rest.substring(spaceAt + 1) : "";

            mCue.mStartTimeMs = parseTimestampMs(start);
            mCue.mEndTimeMs = parseTimestampMs(end);
            for (String setting: rest.split(" +")) {
                int colonAt = setting.indexOf(':');
                if (colonAt <= 0 || colonAt == setting.length() - 1) {
                    continue;
                }
                String name = setting.substring(0, colonAt);
                String value = setting.substring(colonAt + 1);

                if (name.equals("region")) {
                    mCue.mRegionId = value;
                } else if (name.equals("vertical")) {
                    if (value.equals("rl")) {
                        mCue.mWritingDirection =
                            TextTrackCue.WRITING_DIRECTION_VERTICAL_RL;
                    } else if (value.equals("lr")) {
                        mCue.mWritingDirection =
                            TextTrackCue.WRITING_DIRECTION_VERTICAL_LR;
                    } else {
                        log_warning("cue setting", name, "has invalid value", value);
                    }
                } else if (name.equals("line")) {
                    try {
                        /* TRICKY: we know that there are no spaces in value */
                        assert(value.indexOf(' ') < 0);
                        if (value.endsWith("%")) {
                            mCue.mSnapToLines = false;
                            mCue.mLinePosition = parseIntPercentage(value);
                        } else if (value.matches(".*[^0-9].*")) {
                            log_warning("cue setting", name,
                                    "contains an invalid character", value);
                        } else {
                            mCue.mSnapToLines = true;
                            mCue.mLinePosition = Integer.parseInt(value);
                        }
                    } catch (NumberFormatException e) {
                        log_warning("cue setting", name,
                                "is not numeric or percentage", value);
                    }
                    // TODO: add support for optional alignment value [,start|middle|end]
                } else if (name.equals("position")) {
                    try {
                        mCue.mTextPosition = parseIntPercentage(value);
                    } catch (NumberFormatException e) {
                        log_warning("cue setting", name,
                               "is not numeric or percentage", value);
                    }
                } else if (name.equals("size")) {
                    try {
                        mCue.mSize = parseIntPercentage(value);
                    } catch (NumberFormatException e) {
                        log_warning("cue setting", name,
                               "is not numeric or percentage", value);
                    }
                } else if (name.equals("align")) {
                    if (value.equals("start")) {
                        mCue.mAlignment = TextTrackCue.ALIGNMENT_START;
                    } else if (value.equals("middle")) {
                        mCue.mAlignment = TextTrackCue.ALIGNMENT_MIDDLE;
                    } else if (value.equals("end")) {
                        mCue.mAlignment = TextTrackCue.ALIGNMENT_END;
                    } else if (value.equals("left")) {
                        mCue.mAlignment = TextTrackCue.ALIGNMENT_LEFT;
                    } else if (value.equals("right")) {
                        mCue.mAlignment = TextTrackCue.ALIGNMENT_RIGHT;
                    } else {
                        log_warning("cue setting", name, "has invalid value", value);
                        continue;
                    }
                }
            }

            if (mCue.mLinePosition != null ||
                    mCue.mSize != 100 ||
                    (mCue.mWritingDirection !=
                        TextTrackCue.WRITING_DIRECTION_HORIZONTAL)) {
                mCue.mRegionId = "";
            }

            mPhase = mParseCueText;
        }
    };

    /* also used for notes */
    final private Phase mParseCueText = new Phase() {
        @Override
        public void parse(String line) {
            if (line.length() == 0) {
                yieldCue();
                mPhase = mParseCueId;
                return;
            } else if (mCue != null) {
                mCueTexts.add(line);
            }
        }
    };

    private void log_warning(
            String nameType, String name, String message,
            String subMessage, String value) {
        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
                message + " ('" + value + "' " + subMessage + ")");
    }

    private void log_warning(
            String nameType, String name, String message, String value) {
        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
                message + " ('" + value + "')");
    }

    private void log_warning(String message, String value) {
        Log.w(this.getClass().getName(), message + " ('" + value + "')");
    }
}

/** @hide */
interface WebVttCueListener {
    void onCueParsed(TextTrackCue cue);
    void onRegionParsed(TextTrackRegion region);
}

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

    private final WebVttParser mParser = new WebVttParser(this);
    private final UnstyledTextExtractor mExtractor =
        new UnstyledTextExtractor();
    private final Tokenizer mTokenizer = new Tokenizer(mExtractor);
    private final Vector<Long> mTimestamps = new Vector<Long>();
    private final WebVttRenderingWidget mRenderingWidget;

    private final Map<String, TextTrackRegion> mRegions =
        new HashMap<String, TextTrackRegion>();
    private Long mCurrentRunID;

    WebVttTrack(WebVttRenderingWidget renderingWidget, MediaFormat format) {
        super(format);

        mRenderingWidget = renderingWidget;
    }

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

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

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

    @Override
    public void onCueParsed(TextTrackCue cue) {
        synchronized (mParser) {
            // resolve region
            if (cue.mRegionId.length() != 0) {
                cue.mRegion = mRegions.get(cue.mRegionId);
            }

            if (DEBUG) Log.v(TAG, "adding cue " + cue);

            // tokenize text track string-lines into lines of spans
            mTokenizer.reset();
            for (String s: cue.mStrings) {
                mTokenizer.tokenize(s);
            }
            cue.mLines = mExtractor.getText();
            if (DEBUG) Log.v(TAG, cue.appendLinesToBuilder(
                    cue.appendStringsToBuilder(
                        new StringBuilder()).append(" simplified to: "))
                            .toString());

            // extract inner timestamps
            for (TextTrackCueSpan[] line: cue.mLines) {
                for (TextTrackCueSpan span: line) {
                    if (span.mTimestampMs > cue.mStartTimeMs &&
                            span.mTimestampMs < cue.mEndTimeMs &&
                            !mTimestamps.contains(span.mTimestampMs)) {
                        mTimestamps.add(span.mTimestampMs);
                    }
                }
            }

            if (mTimestamps.size() > 0) {
                cue.mInnerTimesMs = new long[mTimestamps.size()];
                for (int ix=0; ix < mTimestamps.size(); ++ix) {
                    cue.mInnerTimesMs[ix] = mTimestamps.get(ix);
                }
                mTimestamps.clear();
            } else {
                cue.mInnerTimesMs = null;
            }

            cue.mRunID = mCurrentRunID;
        }

        addCue(cue);
    }

    @Override
    public void onRegionParsed(TextTrackRegion region) {
        synchronized(mParser) {
            mRegions.put(region.mId, region);
        }
    }

    @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:");
            }
        }

        if (mRenderingWidget != null) {
            mRenderingWidget.setActiveCues(activeCues);
        }
    }
}

/**
 * Widget capable of rendering WebVTT captions.
 *
 * @hide
 */
class WebVttRenderingWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
    private static final boolean DEBUG = false;

    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;

    private static final int DEBUG_REGION_BACKGROUND = 0x800000FF;
    private static final int DEBUG_CUE_BACKGROUND = 0x80FF0000;

    /** WebVtt specifies line height as 5.3% of the viewport height. */
    private static final float LINE_HEIGHT_RATIO = 0.0533f;

    /** Map of active regions, used to determine enter/exit. */
    private final ArrayMap<TextTrackRegion, RegionLayout> mRegionBoxes =
            new ArrayMap<TextTrackRegion, RegionLayout>();

    /** Map of active cues, used to determine enter/exit. */
    private final ArrayMap<TextTrackCue, CueLayout> mCueBoxes =
            new ArrayMap<TextTrackCue, CueLayout>();

    /** Captioning manager, used to obtain and track caption properties. */
    private final CaptioningManager mManager;

    /** Callback for rendering changes. */
    private OnChangedListener mListener;

    /** Current caption style. */
    private CaptionStyle mCaptionStyle;

    /** Current font size, computed from font scaling factor and height. */
    private float mFontSize;

    /** Whether a caption style change listener is registered. */
    private boolean mHasChangeListener;

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

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

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

    public WebVttRenderingWidget(
            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);

        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
        mCaptionStyle = mManager.getUserStyle();
        mFontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
    }

    @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 onAttachedToWindow() {
        super.onAttachedToWindow();

        manageChangeListener();
    }

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

        manageChangeListener();
    }

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

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

        manageChangeListener();
    }

    /**
     * Manages whether this renderer is listening for caption style changes.
     */
    private void manageChangeListener() {
        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
        if (mHasChangeListener != needsListener) {
            mHasChangeListener = needsListener;

            if (needsListener) {
                mManager.addCaptioningChangeListener(mCaptioningListener);

                final CaptionStyle captionStyle = mManager.getUserStyle();
                final float fontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
                setCaptionStyle(captionStyle, fontSize);
            } else {
                mManager.removeCaptioningChangeListener(mCaptioningListener);
            }
        }
    }

    public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
        final Context context = getContext();
        final CaptionStyle captionStyle = mCaptionStyle;
        final float fontSize = mFontSize;

        prepForPrune();

        // Ensure we have all necessary cue and region boxes.
        final int count = activeCues.size();
        for (int i = 0; i < count; i++) {
            final TextTrackCue cue = (TextTrackCue) activeCues.get(i);
            final TextTrackRegion region = cue.mRegion;
            if (region != null) {
                RegionLayout regionBox = mRegionBoxes.get(region);
                if (regionBox == null) {
                    regionBox = new RegionLayout(context, region, captionStyle, fontSize);
                    mRegionBoxes.put(region, regionBox);
                    addView(regionBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                }
                regionBox.put(cue);
            } else {
                CueLayout cueBox = mCueBoxes.get(cue);
                if (cueBox == null) {
                    cueBox = new CueLayout(context, cue, captionStyle, fontSize);
                    mCueBoxes.put(cue, cueBox);
                    addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                }
                cueBox.update();
                cueBox.setOrder(i);
            }
        }

        prune();

        // Force measurement and layout.
        final int width = getWidth();
        final int height = getHeight();
        setSize(width, height);

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

    private void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
        captionStyle = DEFAULT_CAPTION_STYLE.applyStyle(captionStyle);
        mCaptionStyle = captionStyle;
        mFontSize = fontSize;

        final int cueCount = mCueBoxes.size();
        for (int i = 0; i < cueCount; i++) {
            final CueLayout cueBox = mCueBoxes.valueAt(i);
            cueBox.setCaptionStyle(captionStyle, fontSize);
        }

        final int regionCount = mRegionBoxes.size();
        for (int i = 0; i < regionCount; i++) {
            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
            regionBox.setCaptionStyle(captionStyle, fontSize);
        }
    }

    /**
     * Remove inactive cues and regions.
     */
    private void prune() {
        int regionCount = mRegionBoxes.size();
        for (int i = 0; i < regionCount; i++) {
            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
            if (regionBox.prune()) {
                removeView(regionBox);
                mRegionBoxes.removeAt(i);
                regionCount--;
                i--;
            }
        }

        int cueCount = mCueBoxes.size();
        for (int i = 0; i < cueCount; i++) {
            final CueLayout cueBox = mCueBoxes.valueAt(i);
            if (!cueBox.isActive()) {
                removeView(cueBox);
                mCueBoxes.removeAt(i);
                cueCount--;
                i--;
            }
        }
    }

    /**
     * Reset active cues and regions.
     */
    private void prepForPrune() {
        final int regionCount = mRegionBoxes.size();
        for (int i = 0; i < regionCount; i++) {
            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
            regionBox.prepForPrune();
        }

        final int cueCount = mCueBoxes.size();
        for (int i = 0; i < cueCount; i++) {
            final CueLayout cueBox = mCueBoxes.valueAt(i);
            cueBox.prepForPrune();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int regionCount = mRegionBoxes.size();
        for (int i = 0; i < regionCount; i++) {
            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
            regionBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
        }

        final int cueCount = mCueBoxes.size();
        for (int i = 0; i < cueCount; i++) {
            final CueLayout cueBox = mCueBoxes.valueAt(i);
            cueBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int viewportWidth = r - l;
        final int viewportHeight = b - t;

        setCaptionStyle(mCaptionStyle,
                mManager.getFontScale() * LINE_HEIGHT_RATIO * viewportHeight);

        final int regionCount = mRegionBoxes.size();
        for (int i = 0; i < regionCount; i++) {
            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
            layoutRegion(viewportWidth, viewportHeight, regionBox);
        }

        final int cueCount = mCueBoxes.size();
        for (int i = 0; i < cueCount; i++) {
            final CueLayout cueBox = mCueBoxes.valueAt(i);
            layoutCue(viewportWidth, viewportHeight, cueBox);
        }
    }

    /**
     * Lays out a region within the viewport. The region handles layout for
     * contained cues.
     */
    private void layoutRegion(
            int viewportWidth, int viewportHeight,
            RegionLayout regionBox) {
        final TextTrackRegion region = regionBox.getRegion();
        final int regionHeight = regionBox.getMeasuredHeight();
        final int regionWidth = regionBox.getMeasuredWidth();

        // TODO: Account for region anchor point.
        final float x = region.mViewportAnchorPointX;
        final float y = region.mViewportAnchorPointY;
        final int left = (int) (x * (viewportWidth - regionWidth) / 100);
        final int top = (int) (y * (viewportHeight - regionHeight) / 100);

        regionBox.layout(left, top, left + regionWidth, top + regionHeight);
    }

    /**
     * Lays out a cue within the viewport.
     */
    private void layoutCue(
            int viewportWidth, int viewportHeight, CueLayout cueBox) {
        final TextTrackCue cue = cueBox.getCue();
        final int direction = getLayoutDirection();
        final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);
        final boolean cueSnapToLines = cue.mSnapToLines;

        int size = 100 * cueBox.getMeasuredWidth() / viewportWidth;

        // Determine raw x-position.
        int xPosition;
        switch (absAlignment) {
            case TextTrackCue.ALIGNMENT_LEFT:
                xPosition = cue.mTextPosition;
                break;
            case TextTrackCue.ALIGNMENT_RIGHT:
                xPosition = cue.mTextPosition - size;
                break;
            case TextTrackCue.ALIGNMENT_MIDDLE:
            default:
                xPosition = cue.mTextPosition - size / 2;
                break;
        }

        // Adjust x-position for layout.
        if (direction == LAYOUT_DIRECTION_RTL) {
            xPosition = 100 - xPosition;
        }

        // If the text track cue snap-to-lines flag is set, adjust
        // x-position and size for padding. This is equivalent to placing the
        // cue within the title-safe area.
        if (cueSnapToLines) {
            final int paddingLeft = 100 * getPaddingLeft() / viewportWidth;
            final int paddingRight = 100 * getPaddingRight() / viewportWidth;
            if (xPosition < paddingLeft && xPosition + size > paddingLeft) {
                xPosition += paddingLeft;
                size -= paddingLeft;
            }
            final float rightEdge = 100 - paddingRight;
            if (xPosition < rightEdge && xPosition + size > rightEdge) {
                size -= paddingRight;
            }
        }

        // Compute absolute left position and width.
        final int left = xPosition * viewportWidth / 100;
        final int width = size * viewportWidth / 100;

        // Determine initial y-position.
        final int yPosition = calculateLinePosition(cueBox);

        // Compute absolute final top position and height.
        final int height = cueBox.getMeasuredHeight();
        final int top;
        if (yPosition < 0) {
            // TODO: This needs to use the actual height of prior boxes.
            top = viewportHeight + yPosition * height;
        } else {
            top = yPosition * (viewportHeight - height) / 100;
        }

        // Layout cue in final position.
        cueBox.layout(left, top, left + width, top + height);
    }

    /**
     * Calculates the line position for a cue.
     * <p>
     * If the resulting position is negative, it represents a bottom-aligned
     * position relative to the number of active cues. Otherwise, it represents
     * a percentage [0-100] of the viewport height.
     */
    private int calculateLinePosition(CueLayout cueBox) {
        final TextTrackCue cue = cueBox.getCue();
        final Integer linePosition = cue.mLinePosition;
        final boolean snapToLines = cue.mSnapToLines;
        final boolean autoPosition = (linePosition == null);

        if (!snapToLines && !autoPosition && (linePosition < 0 || linePosition > 100)) {
            // Invalid line position defaults to 100.
            return 100;
        } else if (!autoPosition) {
            // Use the valid, supplied line position.
            return linePosition;
        } else if (!snapToLines) {
            // Automatic, non-snapped line position defaults to 100.
            return 100;
        } else {
            // Automatic snapped line position uses active cue order.
            return -(cueBox.mOrder + 1);
        }
    }

    /**
     * Resolves cue alignment according to the specified layout direction.
     */
    private static int resolveCueAlignment(int layoutDirection, int alignment) {
        switch (alignment) {
            case TextTrackCue.ALIGNMENT_START:
                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
                        TextTrackCue.ALIGNMENT_LEFT : TextTrackCue.ALIGNMENT_RIGHT;
            case TextTrackCue.ALIGNMENT_END:
                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
                        TextTrackCue.ALIGNMENT_RIGHT : TextTrackCue.ALIGNMENT_LEFT;
        }
        return alignment;
    }

    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
        @Override
        public void onFontScaleChanged(float fontScale) {
            final float fontSize = fontScale * getHeight() * LINE_HEIGHT_RATIO;
            setCaptionStyle(mCaptionStyle, fontSize);
        }

        @Override
        public void onUserStyleChanged(CaptionStyle userStyle) {
            setCaptionStyle(userStyle, mFontSize);
        }
    };

    /**
     * A text track region represents a portion of the video viewport and
     * provides a rendering area for text track cues.
     */
    private static class RegionLayout extends LinearLayout {
        private final ArrayList<CueLayout> mRegionCueBoxes = new ArrayList<CueLayout>();
        private final TextTrackRegion mRegion;

        private CaptionStyle mCaptionStyle;
        private float mFontSize;

        public RegionLayout(Context context, TextTrackRegion region, CaptionStyle captionStyle,
                float fontSize) {
            super(context);

            mRegion = region;
            mCaptionStyle = captionStyle;
            mFontSize = fontSize;

            // TODO: Add support for vertical text
            setOrientation(VERTICAL);

            if (DEBUG) {
                setBackgroundColor(DEBUG_REGION_BACKGROUND);
            } else {
                setBackgroundColor(captionStyle.windowColor);
            }
        }

        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
            mCaptionStyle = captionStyle;
            mFontSize = fontSize;

            final int cueCount = mRegionCueBoxes.size();
            for (int i = 0; i < cueCount; i++) {
                final CueLayout cueBox = mRegionCueBoxes.get(i);
                cueBox.setCaptionStyle(captionStyle, fontSize);
            }

            setBackgroundColor(captionStyle.windowColor);
        }

        /**
         * Performs the parent's measurement responsibilities, then
         * automatically performs its own measurement.
         */
        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
            final TextTrackRegion region = mRegion;
            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
            final int width = (int) region.mWidth;

            // Determine the absolute maximum region size as the requested size.
            final int size = width * specWidth / 100;

            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
            measure(widthMeasureSpec, heightMeasureSpec);
        }

        /**
         * Prepares this region for pruning by setting all tracks as inactive.
         * <p>
         * Tracks that are added or updated using {@link #put(TextTrackCue)}
         * after this calling this method will be marked as active.
         */
        public void prepForPrune() {
            final int cueCount = mRegionCueBoxes.size();
            for (int i = 0; i < cueCount; i++) {
                final CueLayout cueBox = mRegionCueBoxes.get(i);
                cueBox.prepForPrune();
            }
        }

        /**
         * Adds a {@link TextTrackCue} to this region. If the track had already
         * been added, updates its active state.
         *
         * @param cue
         */
        public void put(TextTrackCue cue) {
            final int cueCount = mRegionCueBoxes.size();
            for (int i = 0; i < cueCount; i++) {
                final CueLayout cueBox = mRegionCueBoxes.get(i);
                if (cueBox.getCue() == cue) {
                    cueBox.update();
                    return;
                }
            }

            final CueLayout cueBox = new CueLayout(getContext(), cue, mCaptionStyle, mFontSize);
            mRegionCueBoxes.add(cueBox);
            addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

            if (getChildCount() > mRegion.mLines) {
                removeViewAt(0);
            }
        }

        /**
         * Remove all inactive tracks from this region.
         *
         * @return true if this region is empty and should be pruned
         */
        public boolean prune() {
            int cueCount = mRegionCueBoxes.size();
            for (int i = 0; i < cueCount; i++) {
                final CueLayout cueBox = mRegionCueBoxes.get(i);
                if (!cueBox.isActive()) {
                    mRegionCueBoxes.remove(i);
                    removeView(cueBox);
                    cueCount--;
                    i--;
                }
            }

            return mRegionCueBoxes.isEmpty();
        }

        /**
         * @return the region data backing this layout
         */
        public TextTrackRegion getRegion() {
            return mRegion;
        }
    }

    /**
     * A text track cue is the unit of time-sensitive data in a text track,
     * corresponding for instance for subtitles and captions to the text that
     * appears at a particular time and disappears at another time.
     * <p>
     * A single cue may contain multiple {@link SpanLayout}s, each representing a
     * single line of text.
     */
    private static class CueLayout extends LinearLayout {
        public final TextTrackCue mCue;

        private CaptionStyle mCaptionStyle;
        private float mFontSize;

        private boolean mActive;
        private int mOrder;

        public CueLayout(
                Context context, TextTrackCue cue, CaptionStyle captionStyle, float fontSize) {
            super(context);

            mCue = cue;
            mCaptionStyle = captionStyle;
            mFontSize = fontSize;

            // TODO: Add support for vertical text.
            final boolean horizontal = cue.mWritingDirection
                    == TextTrackCue.WRITING_DIRECTION_HORIZONTAL;
            setOrientation(horizontal ? VERTICAL : HORIZONTAL);

            switch (cue.mAlignment) {
                case TextTrackCue.ALIGNMENT_END:
                    setGravity(Gravity.END);
                    break;
                case TextTrackCue.ALIGNMENT_LEFT:
                    setGravity(Gravity.LEFT);
                    break;
                case TextTrackCue.ALIGNMENT_MIDDLE:
                    setGravity(horizontal
                            ? Gravity.CENTER_HORIZONTAL : Gravity.CENTER_VERTICAL);
                    break;
                case TextTrackCue.ALIGNMENT_RIGHT:
                    setGravity(Gravity.RIGHT);
                    break;
                case TextTrackCue.ALIGNMENT_START:
                    setGravity(Gravity.START);
                    break;
            }

            if (DEBUG) {
                setBackgroundColor(DEBUG_CUE_BACKGROUND);
            }

            update();
        }

        public void setCaptionStyle(CaptionStyle style, float fontSize) {
            mCaptionStyle = style;
            mFontSize = fontSize;

            final int n = getChildCount();
            for (int i = 0; i < n; i++) {
                final View child = getChildAt(i);
                if (child instanceof SpanLayout) {
                    ((SpanLayout) child).setCaptionStyle(style, fontSize);
                }
            }
        }

        public void prepForPrune() {
            mActive = false;
        }

        public void update() {
            mActive = true;

            removeAllViews();

            final int cueAlignment = resolveCueAlignment(getLayoutDirection(), mCue.mAlignment);
            final Alignment alignment;
            switch (cueAlignment) {
                case TextTrackCue.ALIGNMENT_LEFT:
                    alignment = Alignment.ALIGN_LEFT;
                    break;
                case TextTrackCue.ALIGNMENT_RIGHT:
                    alignment = Alignment.ALIGN_RIGHT;
                    break;
                case TextTrackCue.ALIGNMENT_MIDDLE:
                default:
                    alignment = Alignment.ALIGN_CENTER;
            }

            final CaptionStyle captionStyle = mCaptionStyle;
            final float fontSize = mFontSize;
            final TextTrackCueSpan[][] lines = mCue.mLines;
            final int lineCount = lines.length;
            for (int i = 0; i < lineCount; i++) {
                final SpanLayout lineBox = new SpanLayout(getContext(), lines[i]);
                lineBox.setAlignment(alignment);
                lineBox.setCaptionStyle(captionStyle, fontSize);

                addView(lineBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            }
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }

        /**
         * Performs the parent's measurement responsibilities, then
         * automatically performs its own measurement.
         */
        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
            final TextTrackCue cue = mCue;
            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
            final int direction = getLayoutDirection();
            final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);

            // Determine the maximum size of cue based on its starting position
            // and the direction in which it grows.
            final int maximumSize;
            switch (absAlignment) {
                case TextTrackCue.ALIGNMENT_LEFT:
                    maximumSize = 100 - cue.mTextPosition;
                    break;
                case TextTrackCue.ALIGNMENT_RIGHT:
                    maximumSize = cue.mTextPosition;
                    break;
                case TextTrackCue.ALIGNMENT_MIDDLE:
                    if (cue.mTextPosition <= 50) {
                        maximumSize = cue.mTextPosition * 2;
                    } else {
                        maximumSize = (100 - cue.mTextPosition) * 2;
                    }
                    break;
                default:
                    maximumSize = 0;
            }

            // Determine absolute maximum cue size as the smaller of the
            // requested size and the maximum theoretical size.
            final int size = Math.min(cue.mSize, maximumSize) * specWidth / 100;
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
            measure(widthMeasureSpec, heightMeasureSpec);
        }

        /**
         * Sets the order of this cue in the list of active cues.
         *
         * @param order the order of this cue in the list of active cues
         */
        public void setOrder(int order) {
            mOrder = order;
        }

        /**
         * @return whether this cue is marked as active
         */
        public boolean isActive() {
            return mActive;
        }

        /**
         * @return the cue data backing this layout
         */
        public TextTrackCue getCue() {
            return mCue;
        }
    }

    /**
     * A text track line represents a single line of text within a cue.
     * <p>
     * A single line may contain multiple spans, each representing a section of
     * text that may be enabled or disabled at a particular time.
     */
    private static class SpanLayout extends SubtitleView {
        private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
        private final TextTrackCueSpan[] mSpans;

        public SpanLayout(Context context, TextTrackCueSpan[] spans) {
            super(context);

            mSpans = spans;

            update();
        }

        public void update() {
            final SpannableStringBuilder builder = mBuilder;
            final TextTrackCueSpan[] spans = mSpans;

            builder.clear();
            builder.clearSpans();

            final int spanCount = spans.length;
            for (int i = 0; i < spanCount; i++) {
                final TextTrackCueSpan span = spans[i];
                if (span.mEnabled) {
                    builder.append(spans[i].mText);
                }
            }

            setText(builder);
        }

        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
            setBackgroundColor(captionStyle.backgroundColor);
            setForegroundColor(captionStyle.foregroundColor);
            setEdgeColor(captionStyle.edgeColor);
            setEdgeType(captionStyle.edgeType);
            setTypeface(captionStyle.getTypeface());
            setTextSize(fontSize);
        }
    }
}
