/*
 * Copyright (C) 2011 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.graphics.Rect;
import android.os.Parcel;
import android.util.Log;
import java.util.HashMap;
import java.util.Set;
import java.util.List;
import java.util.ArrayList;

/**
 * Class to hold the timed text's metadata, including:
 * <ul>
 * <li> The characters for rendering</li>
 * <li> The rendering position for the timed text</li>
 * </ul>
 *
 * <p> To render the timed text, applications need to do the following:
 *
 * <ul>
 * <li> Implement the {@link MediaPlayer.OnTimedTextListener} interface</li>
 * <li> Register the {@link MediaPlayer.OnTimedTextListener} callback on a MediaPlayer object that is used for playback</li>
 * <li> When a onTimedText callback is received, do the following:
 * <ul>
 * <li> call {@link #getText} to get the characters for rendering</li>
 * <li> call {@link #getBounds} to get the text rendering area/region</li>
 * </ul>
 * </li>
 * </ul>
 *
 * @see android.media.MediaPlayer
 */
public final class TimedText
{
    private static final int FIRST_PUBLIC_KEY                 = 1;

    // These keys must be in sync with the keys in TextDescription.h
    private static final int KEY_DISPLAY_FLAGS                 = 1; // int
    private static final int KEY_STYLE_FLAGS                   = 2; // int
    private static final int KEY_BACKGROUND_COLOR_RGBA         = 3; // int
    private static final int KEY_HIGHLIGHT_COLOR_RGBA          = 4; // int
    private static final int KEY_SCROLL_DELAY                  = 5; // int
    private static final int KEY_WRAP_TEXT                     = 6; // int
    private static final int KEY_START_TIME                    = 7; // int
    private static final int KEY_STRUCT_BLINKING_TEXT_LIST     = 8; // List<CharPos>
    private static final int KEY_STRUCT_FONT_LIST              = 9; // List<Font>
    private static final int KEY_STRUCT_HIGHLIGHT_LIST         = 10; // List<CharPos>
    private static final int KEY_STRUCT_HYPER_TEXT_LIST        = 11; // List<HyperText>
    private static final int KEY_STRUCT_KARAOKE_LIST           = 12; // List<Karaoke>
    private static final int KEY_STRUCT_STYLE_LIST             = 13; // List<Style>
    private static final int KEY_STRUCT_TEXT_POS               = 14; // TextPos
    private static final int KEY_STRUCT_JUSTIFICATION          = 15; // Justification
    private static final int KEY_STRUCT_TEXT                   = 16; // Text

    private static final int LAST_PUBLIC_KEY                  = 16;

    private static final int FIRST_PRIVATE_KEY                = 101;

    // The following keys are used between TimedText.java and
    // TextDescription.cpp in order to parce the Parcel.
    private static final int KEY_GLOBAL_SETTING               = 101;
    private static final int KEY_LOCAL_SETTING                = 102;
    private static final int KEY_START_CHAR                   = 103;
    private static final int KEY_END_CHAR                     = 104;
    private static final int KEY_FONT_ID                      = 105;
    private static final int KEY_FONT_SIZE                    = 106;
    private static final int KEY_TEXT_COLOR_RGBA              = 107;

    private static final int LAST_PRIVATE_KEY                 = 107;

    private static final String TAG = "TimedText";

    private final HashMap<Integer, Object> mKeyObjectMap =
            new HashMap<Integer, Object>();

    private int mDisplayFlags = -1;
    private int mBackgroundColorRGBA = -1;
    private int mHighlightColorRGBA = -1;
    private int mScrollDelay = -1;
    private int mWrapText = -1;

    private List<CharPos> mBlinkingPosList = null;
    private List<CharPos> mHighlightPosList = null;
    private List<Karaoke> mKaraokeList = null;
    private List<Font> mFontList = null;
    private List<Style> mStyleList = null;
    private List<HyperText> mHyperTextList = null;

    private Rect mTextBounds = null;
    private String mTextChars = null;

    private Justification mJustification;

    /**
     * Helper class to hold the start char offset and end char offset
     * for Blinking Text or Highlight Text. endChar is the end offset
     * of the text (startChar + number of characters to be highlighted
     * or blinked). The member variables in this class are read-only.
     * {@hide}
     */
    public static final class CharPos {
        /**
         * The offset of the start character
         */
        public final int startChar;

        /**
         * The offset of the end character
         */
        public final int endChar;

        /**
         * Constuctor
         * @param startChar the offset of the start character.
         * @param endChar the offset of the end character.
         */
        public CharPos(int startChar, int endChar) {
            this.startChar = startChar;
            this.endChar = endChar;
        }
    }

    /**
     * Helper class to hold the justification for text display in the text box.
     * The member variables in this class are read-only.
     * {@hide}
     */
    public static final class Justification {
        /**
         * horizontal justification  0: left, 1: centered, -1: right
         */
        public final int horizontalJustification;

        /**
         * vertical justification  0: top, 1: centered, -1: bottom
         */
        public final int verticalJustification;

        /**
         * Constructor
         * @param horizontal the horizontal justification of the text.
         * @param vertical the vertical justification of the text.
         */
        public Justification(int horizontal, int vertical) {
            this.horizontalJustification = horizontal;
            this.verticalJustification = vertical;
        }
    }

    /**
     * Helper class to hold the style information to display the text.
     * The member variables in this class are read-only.
     * {@hide}
     */
    public static final class Style {
        /**
         * The offset of the start character which applys this style
         */
        public final int startChar;

        /**
         * The offset of the end character which applys this style
         */
        public final int endChar;

        /**
         * ID of the font. This ID will be used to choose the font
         * to be used from the font list.
         */
        public final int fontID;

        /**
         * True if the characters should be bold
         */
        public final boolean isBold;

        /**
         * True if the characters should be italic
         */
        public final boolean isItalic;

        /**
         * True if the characters should be underlined
         */
        public final boolean isUnderlined;

        /**
         * The size of the font
         */
        public final int fontSize;

        /**
         * To specify the RGBA color: 8 bits each of red, green, blue,
         * and an alpha(transparency) value
         */
        public final int colorRGBA;

        /**
         * Constructor
         * @param startChar the offset of the start character which applys this style
         * @param endChar the offset of the end character which applys this style
         * @param fontId the ID of the font.
         * @param isBold whether the characters should be bold.
         * @param isItalic whether the characters should be italic.
         * @param isUnderlined whether the characters should be underlined.
         * @param fontSize the size of the font.
         * @param colorRGBA red, green, blue, and alpha value for color.
         */
        public Style(int startChar, int endChar, int fontId,
                     boolean isBold, boolean isItalic, boolean isUnderlined,
                     int fontSize, int colorRGBA) {
            this.startChar = startChar;
            this.endChar = endChar;
            this.fontID = fontId;
            this.isBold = isBold;
            this.isItalic = isItalic;
            this.isUnderlined = isUnderlined;
            this.fontSize = fontSize;
            this.colorRGBA = colorRGBA;
        }
    }

    /**
     * Helper class to hold the font ID and name.
     * The member variables in this class are read-only.
     * {@hide}
     */
    public static final class Font {
        /**
         * The font ID
         */
        public final int ID;

        /**
         * The font name
         */
        public final String name;

        /**
         * Constructor
         * @param id the font ID.
         * @param name the font name.
         */
        public Font(int id, String name) {
            this.ID = id;
            this.name = name;
        }
    }

    /**
     * Helper class to hold the karaoke information.
     * The member variables in this class are read-only.
     * {@hide}
     */
    public static final class Karaoke {
        /**
         * The start time (in milliseconds) to highlight the characters
         * specified by startChar and endChar.
         */
        public final int startTimeMs;

        /**
         * The end time (in milliseconds) to highlight the characters
         * specified by startChar and endChar.
         */
        public final int endTimeMs;

        /**
         * The offset of the start character to be highlighted
         */
        public final int startChar;

        /**
         * The offset of the end character to be highlighted
         */
        public final int endChar;

        /**
         * Constructor
         * @param startTimeMs the start time (in milliseconds) to highlight
         * the characters between startChar and endChar.
         * @param endTimeMs the end time (in milliseconds) to highlight
         * the characters between startChar and endChar.
         * @param startChar the offset of the start character to be highlighted.
         * @param endChar the offset of the end character to be highlighted.
         */
        public Karaoke(int startTimeMs, int endTimeMs, int startChar, int endChar) {
            this.startTimeMs = startTimeMs;
            this.endTimeMs = endTimeMs;
            this.startChar = startChar;
            this.endChar = endChar;
        }
    }

    /**
     * Helper class to hold the hyper text information.
     * The member variables in this class are read-only.
     * {@hide}
     */
    public static final class HyperText {
        /**
         * The offset of the start character
         */
        public final int startChar;

        /**
         * The offset of the end character
         */
        public final int endChar;

        /**
         * The linked-to URL
         */
        public final String URL;

        /**
         * The "alt" string for user display
         */
        public final String altString;


        /**
         * Constructor
         * @param startChar the offset of the start character.
         * @param endChar the offset of the end character.
         * @param url the linked-to URL.
         * @param alt the "alt" string for display.
         */
        public HyperText(int startChar, int endChar, String url, String alt) {
            this.startChar = startChar;
            this.endChar = endChar;
            this.URL = url;
            this.altString = alt;
        }
    }

    /**
     * @param obj the byte array which contains the timed text.
     * @throws IllegalArgumentExcept if parseParcel() fails.
     * {@hide}
     */
    public TimedText(Parcel parcel) {
        if (!parseParcel(parcel)) {
            mKeyObjectMap.clear();
            throw new IllegalArgumentException("parseParcel() fails");
        }
    }

    /**
     * Get the characters in the timed text.
     *
     * @return the characters as a String object in the TimedText. Applications
     * should stop rendering previous timed text at the current rendering region if
     * a null is returned, until the next non-null timed text is received.
     */
    public String getText() {
        return mTextChars;
    }

    /**
     * Get the rectangle area or region for rendering the timed text as specified
     * by a Rect object.
     *
     * @return the rectangle region to render the characters in the timed text.
     * If no bounds information is available (a null is returned), render the
     * timed text at the center bottom of the display.
     */
    public Rect getBounds() {
        return mTextBounds;
    }

    /*
     * Go over all the records, collecting metadata keys and fields in the
     * Parcel. These are stored in mKeyObjectMap for application to retrieve.
     * @return false if an error occurred during parsing. Otherwise, true.
     */
    private boolean parseParcel(Parcel parcel) {
        parcel.setDataPosition(0);
        if (parcel.dataAvail() == 0) {
            return false;
        }

        int type = parcel.readInt();
        if (type == KEY_LOCAL_SETTING) {
            type = parcel.readInt();
            if (type != KEY_START_TIME) {
                return false;
            }
            int mStartTimeMs = parcel.readInt();
            mKeyObjectMap.put(type, mStartTimeMs);

            type = parcel.readInt();
            if (type != KEY_STRUCT_TEXT) {
                return false;
            }

            int textLen = parcel.readInt();
            byte[] text = parcel.createByteArray();
            if (text == null || text.length == 0) {
                mTextChars = null;
            } else {
                mTextChars = new String(text);
            }

        } else if (type != KEY_GLOBAL_SETTING) {
            Log.w(TAG, "Invalid timed text key found: " + type);
            return false;
        }

        while (parcel.dataAvail() > 0) {
            int key = parcel.readInt();
            if (!isValidKey(key)) {
                Log.w(TAG, "Invalid timed text key found: " + key);
                return false;
            }

            Object object = null;

            switch (key) {
                case KEY_STRUCT_STYLE_LIST: {
                    readStyle(parcel);
                    object = mStyleList;
                    break;
                }
                case KEY_STRUCT_FONT_LIST: {
                    readFont(parcel);
                    object = mFontList;
                    break;
                }
                case KEY_STRUCT_HIGHLIGHT_LIST: {
                    readHighlight(parcel);
                    object = mHighlightPosList;
                    break;
                }
                case KEY_STRUCT_KARAOKE_LIST: {
                    readKaraoke(parcel);
                    object = mKaraokeList;
                    break;
                }
                case KEY_STRUCT_HYPER_TEXT_LIST: {
                    readHyperText(parcel);
                    object = mHyperTextList;

                    break;
                }
                case KEY_STRUCT_BLINKING_TEXT_LIST: {
                    readBlinkingText(parcel);
                    object = mBlinkingPosList;

                    break;
                }
                case KEY_WRAP_TEXT: {
                    mWrapText = parcel.readInt();
                    object = mWrapText;
                    break;
                }
                case KEY_HIGHLIGHT_COLOR_RGBA: {
                    mHighlightColorRGBA = parcel.readInt();
                    object = mHighlightColorRGBA;
                    break;
                }
                case KEY_DISPLAY_FLAGS: {
                    mDisplayFlags = parcel.readInt();
                    object = mDisplayFlags;
                    break;
                }
                case KEY_STRUCT_JUSTIFICATION: {

                    int horizontal = parcel.readInt();
                    int vertical = parcel.readInt();
                    mJustification = new Justification(horizontal, vertical);

                    object = mJustification;
                    break;
                }
                case KEY_BACKGROUND_COLOR_RGBA: {
                    mBackgroundColorRGBA = parcel.readInt();
                    object = mBackgroundColorRGBA;
                    break;
                }
                case KEY_STRUCT_TEXT_POS: {
                    int top = parcel.readInt();
                    int left = parcel.readInt();
                    int bottom = parcel.readInt();
                    int right = parcel.readInt();
                    mTextBounds = new Rect(left, top, right, bottom);

                    break;
                }
                case KEY_SCROLL_DELAY: {
                    mScrollDelay = parcel.readInt();
                    object = mScrollDelay;
                    break;
                }
                default: {
                    break;
                }
            }

            if (object != null) {
                if (mKeyObjectMap.containsKey(key)) {
                    mKeyObjectMap.remove(key);
                }
                // Previous mapping will be replaced with the new object, if there was one.
                mKeyObjectMap.put(key, object);
            }
        }

        return true;
    }

    /*
     * To parse and store the Style list.
     */
    private void readStyle(Parcel parcel) {
        boolean endOfStyle = false;
        int startChar = -1;
        int endChar = -1;
        int fontId = -1;
        boolean isBold = false;
        boolean isItalic = false;
        boolean isUnderlined = false;
        int fontSize = -1;
        int colorRGBA = -1;
        while (!endOfStyle && (parcel.dataAvail() > 0)) {
            int key = parcel.readInt();
            switch (key) {
                case KEY_START_CHAR: {
                    startChar = parcel.readInt();
                    break;
                }
                case KEY_END_CHAR: {
                    endChar = parcel.readInt();
                    break;
                }
                case KEY_FONT_ID: {
                    fontId = parcel.readInt();
                    break;
                }
                case KEY_STYLE_FLAGS: {
                    int flags = parcel.readInt();
                    // In the absence of any bits set in flags, the text
                    // is plain. Otherwise, 1: bold, 2: italic, 4: underline
                    isBold = ((flags % 2) == 1);
                    isItalic = ((flags % 4) >= 2);
                    isUnderlined = ((flags / 4) == 1);
                    break;
                }
                case KEY_FONT_SIZE: {
                    fontSize = parcel.readInt();
                    break;
                }
                case KEY_TEXT_COLOR_RGBA: {
                    colorRGBA = parcel.readInt();
                    break;
                }
                default: {
                    // End of the Style parsing. Reset the data position back
                    // to the position before the last parcel.readInt() call.
                    parcel.setDataPosition(parcel.dataPosition() - 4);
                    endOfStyle = true;
                    break;
                }
            }
        }

        Style style = new Style(startChar, endChar, fontId, isBold,
                                isItalic, isUnderlined, fontSize, colorRGBA);
        if (mStyleList == null) {
            mStyleList = new ArrayList<Style>();
        }
        mStyleList.add(style);
    }

    /*
     * To parse and store the Font list
     */
    private void readFont(Parcel parcel) {
        int entryCount = parcel.readInt();

        for (int i = 0; i < entryCount; i++) {
            int id = parcel.readInt();
            int nameLen = parcel.readInt();

            byte[] text = parcel.createByteArray();
            final String name = new String(text, 0, nameLen);

            Font font = new Font(id, name);

            if (mFontList == null) {
                mFontList = new ArrayList<Font>();
            }
            mFontList.add(font);
        }
    }

    /*
     * To parse and store the Highlight list
     */
    private void readHighlight(Parcel parcel) {
        int startChar = parcel.readInt();
        int endChar = parcel.readInt();
        CharPos pos = new CharPos(startChar, endChar);

        if (mHighlightPosList == null) {
            mHighlightPosList = new ArrayList<CharPos>();
        }
        mHighlightPosList.add(pos);
    }

    /*
     * To parse and store the Karaoke list
     */
    private void readKaraoke(Parcel parcel) {
        int entryCount = parcel.readInt();

        for (int i = 0; i < entryCount; i++) {
            int startTimeMs = parcel.readInt();
            int endTimeMs = parcel.readInt();
            int startChar = parcel.readInt();
            int endChar = parcel.readInt();
            Karaoke kara = new Karaoke(startTimeMs, endTimeMs,
                                       startChar, endChar);

            if (mKaraokeList == null) {
                mKaraokeList = new ArrayList<Karaoke>();
            }
            mKaraokeList.add(kara);
        }
    }

    /*
     * To parse and store HyperText list
     */
    private void readHyperText(Parcel parcel) {
        int startChar = parcel.readInt();
        int endChar = parcel.readInt();

        int len = parcel.readInt();
        byte[] url = parcel.createByteArray();
        final String urlString = new String(url, 0, len);

        len = parcel.readInt();
        byte[] alt = parcel.createByteArray();
        final String altString = new String(alt, 0, len);
        HyperText hyperText = new HyperText(startChar, endChar, urlString, altString);


        if (mHyperTextList == null) {
            mHyperTextList = new ArrayList<HyperText>();
        }
        mHyperTextList.add(hyperText);
    }

    /*
     * To parse and store blinking text list
     */
    private void readBlinkingText(Parcel parcel) {
        int startChar = parcel.readInt();
        int endChar = parcel.readInt();
        CharPos blinkingPos = new CharPos(startChar, endChar);

        if (mBlinkingPosList == null) {
            mBlinkingPosList = new ArrayList<CharPos>();
        }
        mBlinkingPosList.add(blinkingPos);
    }

    /*
     * To check whether the given key is valid.
     * @param key the key to be checked.
     * @return true if the key is a valid one. Otherwise, false.
     */
    private boolean isValidKey(final int key) {
        if (!((key >= FIRST_PUBLIC_KEY) && (key <= LAST_PUBLIC_KEY))
                && !((key >= FIRST_PRIVATE_KEY) && (key <= LAST_PRIVATE_KEY))) {
            return false;
        }
        return true;
    }

    /*
     * To check whether the given key is contained in this TimedText object.
     * @param key the key to be checked.
     * @return true if the key is contained in this TimedText object.
     *         Otherwise, false.
     */
    private boolean containsKey(final int key) {
        if (isValidKey(key) && mKeyObjectMap.containsKey(key)) {
            return true;
        }
        return false;
    }

    /*
     * @return a set of the keys contained in this TimedText object.
     */
    private Set keySet() {
        return mKeyObjectMap.keySet();
    }

    /*
     * To retrieve the object associated with the key. Caller must make sure
     * the key is present using the containsKey method otherwise a
     * RuntimeException will occur.
     * @param key the key used to retrieve the object.
     * @return an object. The object could be 1) an instance of Integer; 2) a
     * List of CharPos, Karaoke, Font, Style, and HyperText, or 3) an instance of
     * Justification.
     */
    private Object getObject(final int key) {
        if (containsKey(key)) {
            return mKeyObjectMap.get(key);
        } else {
            throw new IllegalArgumentException("Invalid key: " + key);
        }
    }
}
