 /*
 * Copyright (C) 2012 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "TimedTextDriver"
#include <utils/Log.h>

#include <binder/IPCThreadState.h>

#include <media/IMediaHTTPService.h>
#include <media/mediaplayer.h>
#include <media/MediaPlayerInterface.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ALooper.h>
#include <media/stagefright/timedtext/TimedTextDriver.h>

#include "TextDescriptions.h"
#include "TimedTextPlayer.h"
#include "TimedTextSource.h"

namespace android {

TimedTextDriver::TimedTextDriver(
        const wp<MediaPlayerBase> &listener,
        const sp<IMediaHTTPService> &httpService)
    : mLooper(new ALooper),
      mListener(listener),
      mHTTPService(httpService),
      mState(UNINITIALIZED),
      mCurrentTrackIndex(UINT_MAX) {
    mLooper->setName("TimedTextDriver");
    mLooper->start();
    mPlayer = new TimedTextPlayer(listener);
    mLooper->registerHandler(mPlayer);
}

TimedTextDriver::~TimedTextDriver() {
    mTextSourceVector.clear();
    mTextSourceTypeVector.clear();
    mLooper->stop();
}

status_t TimedTextDriver::selectTrack_l(size_t index) {
    if (mCurrentTrackIndex == index) {
        return OK;
    }
    sp<TimedTextSource> source;
    source = mTextSourceVector.valueFor(index);
    mPlayer->setDataSource(source);
    if (mState == UNINITIALIZED) {
        mState = PREPARED;
    }
    mCurrentTrackIndex = index;
    return OK;
}

status_t TimedTextDriver::start() {
    Mutex::Autolock autoLock(mLock);
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PLAYING:
            return OK;
        case PREPARED:
            mPlayer->start();
            mState = PLAYING;
            return OK;
        case PAUSED:
            mPlayer->resume();
            mState = PLAYING;
            return OK;
        default:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::pause() {
    Mutex::Autolock autoLock(mLock);
    ALOGV("%s() is called", __FUNCTION__);
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PLAYING:
            mPlayer->pause();
            mState = PAUSED;
            return OK;
        case PREPARED:
            return INVALID_OPERATION;
        case PAUSED:
            return OK;
        default:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::selectTrack(size_t index) {
    status_t ret = OK;
    Mutex::Autolock autoLock(mLock);
    ALOGV("%s() is called", __FUNCTION__);
    switch (mState) {
        case UNINITIALIZED:
        case PREPARED:
        case PAUSED:
            ret = selectTrack_l(index);
            break;
        case PLAYING:
            mPlayer->pause();
            ret = selectTrack_l(index);
            if (ret != OK) {
                break;
            }
            mPlayer->start();
            break;
        default:
            TRESPASS();
    }
    return ret;
}

status_t TimedTextDriver::unselectTrack(size_t index) {
    Mutex::Autolock autoLock(mLock);
    ALOGV("%s() is called", __FUNCTION__);
    if (mCurrentTrackIndex != index) {
        return INVALID_OPERATION;
    }
    mCurrentTrackIndex = UINT_MAX;
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PLAYING:
            mPlayer->setDataSource(NULL);
            mState = UNINITIALIZED;
            return OK;
        case PREPARED:
        case PAUSED:
            mState = UNINITIALIZED;
            return OK;
        default:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::seekToAsync(int64_t timeUs) {
    Mutex::Autolock autoLock(mLock);
    ALOGV("%s() is called", __FUNCTION__);
    switch (mState) {
        case UNINITIALIZED:
            return INVALID_OPERATION;
        case PREPARED:
            mPlayer->seekToAsync(timeUs);
            mPlayer->pause();
            mState = PAUSED;
            return OK;
        case PAUSED:
            mPlayer->seekToAsync(timeUs);
            mPlayer->pause();
            return OK;
        case PLAYING:
            mPlayer->seekToAsync(timeUs);
            return OK;
        default:
            TRESPASS();
    }
    return UNKNOWN_ERROR;
}

status_t TimedTextDriver::addInBandTextSource(
        size_t trackIndex, const sp<MediaSource>& mediaSource) {
    sp<TimedTextSource> source =
            TimedTextSource::CreateTimedTextSource(mediaSource);
    if (source == NULL) {
        return ERROR_UNSUPPORTED;
    }
    Mutex::Autolock autoLock(mLock);
    mTextSourceVector.add(trackIndex, source);
    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_IN_BAND);
    return OK;
}

status_t TimedTextDriver::addOutOfBandTextSource(
        size_t trackIndex, const char *uri, const char *mimeType) {

    // To support local subtitle file only for now
    if (strncasecmp("file://", uri, 7)) {
        ALOGE("uri('%s') is not a file", uri);
        return ERROR_UNSUPPORTED;
    }

    sp<DataSource> dataSource =
            DataSource::CreateFromURI(mHTTPService, uri);
    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
}

status_t TimedTextDriver::addOutOfBandTextSource(
        size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) {

    if (fd < 0) {
        ALOGE("Invalid file descriptor: %d", fd);
        return ERROR_UNSUPPORTED;
    }

    sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
}

status_t TimedTextDriver::createOutOfBandTextSource(
        size_t trackIndex,
        const char *mimeType,
        const sp<DataSource>& dataSource) {

    if (dataSource == NULL) {
        return ERROR_UNSUPPORTED;
    }

    sp<TimedTextSource> source;
    if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP) == 0) {
        source = TimedTextSource::CreateTimedTextSource(
                dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT);
    }

    if (source == NULL) {
        ALOGE("Failed to create timed text source");
        return ERROR_UNSUPPORTED;
    }

    Mutex::Autolock autoLock(mLock);
    mTextSourceVector.add(trackIndex, source);
    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_OUT_OF_BAND);
    return OK;
}

size_t TimedTextDriver::countExternalTracks() const {
    size_t nTracks = 0;
    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_OUT_OF_BAND) {
            ++nTracks;
        }
    }
    return nTracks;
}

void TimedTextDriver::getExternalTrackInfo(Parcel *parcel) {
    Mutex::Autolock autoLock(mLock);
    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_IN_BAND) {
            continue;
        }

        sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat();

        // There are two fields.
        parcel->writeInt32(2);

        // track type.
        parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
        const char *lang = "und";
        if (meta != NULL) {
            meta->findCString(kKeyMediaLanguage, &lang);
        }
        parcel->writeString16(String16(lang));
    }
}

}  // namespace android
