/*
 * 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.
 */

/* StreamInformation implementation */

#include "sles_allinclusive.h"

static XAresult IStreamInformation_QueryMediaContainerInformation( XAStreamInformationItf self,
        XAMediaContainerInformation * info /* [out] */)
{
    XA_ENTER_INTERFACE

    if (NULL == info) {
        result = XA_RESULT_PARAMETER_INVALID;
        XA_LEAVE_INTERFACE
    }

#ifdef ANDROID
    IStreamInformation *thiz = (IStreamInformation *) self;
    interface_lock_shared(thiz);
    // always storing container info at index 0, as per spec
    *info = thiz->mStreamInfoTable.itemAt(0).containerInfo;
    interface_unlock_shared(thiz);
    // even though the pointer to the media container info is returned, the values aren't set
    //  for the actual container in this version, they are simply initialized to defaults
    //  (see IStreamInformation_init)
    result = XA_RESULT_SUCCESS;
#else
    SL_LOGE("QueryMediaContainerInformation is unsupported");
    memset(info, 0, sizeof(XAMediaContainerInformation));
    result = XA_RESULT_FEATURE_UNSUPPORTED;
#endif

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_QueryStreamType( XAStreamInformationItf self,
        XAuint32 streamIndex, /* [in] */
        XAuint32 *domain)     /* [out] */
{
    XA_ENTER_INTERFACE

    if (NULL == domain) {
        result = XA_RESULT_PARAMETER_INVALID;
        XA_LEAVE_INTERFACE;
    }

#ifndef ANDROID
    *domain = XA_DOMAINTYPE_UNKNOWN;
#else
    if (0 == streamIndex) {
        // stream 0 is reserved for the container
        result = XA_RESULT_PARAMETER_INVALID;
        *domain = XA_DOMAINTYPE_UNKNOWN;
    } else {
        IStreamInformation *thiz = (IStreamInformation *) self;

        interface_lock_shared(thiz);

        XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
        // streams in the container are numbered 1..nbStreams
        if (streamIndex <= nbStreams) {
            result = XA_RESULT_SUCCESS;
            *domain = thiz->mStreamInfoTable.itemAt(streamIndex).domain;
        } else {
            SL_LOGE("Querying stream type for stream %d, only %d streams available",
                    streamIndex, nbStreams);
            result = XA_RESULT_PARAMETER_INVALID;
        }

        interface_unlock_shared(thiz);
    }
#endif

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_QueryStreamInformation( XAStreamInformationItf self,
        XAuint32 streamIndex, /* [in] */
        void * info)          /* [out] */
{
    XA_ENTER_INTERFACE

    if (NULL == info) {
        result = XA_RESULT_PARAMETER_INVALID;
    } else {

#ifndef ANDROID
        result = XA_RESULT_FEATURE_UNSUPPORTED;
#else

        IStreamInformation *thiz = (IStreamInformation *) self;

        interface_lock_shared(thiz);

        XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
        // stream 0 is the container, and other streams in the container are numbered 1..nbStreams
        if (streamIndex <= nbStreams) {
            result = XA_RESULT_SUCCESS;
            const StreamInfo& streamInfo = thiz->mStreamInfoTable.itemAt((size_t)streamIndex);

            switch (streamInfo.domain) {
            case XA_DOMAINTYPE_CONTAINER:
                *(XAMediaContainerInformation *)info = streamInfo.containerInfo;
                break;
            case XA_DOMAINTYPE_AUDIO:
                *(XAAudioStreamInformation *)info = streamInfo.audioInfo;
                break;
            case XA_DOMAINTYPE_VIDEO:
                *(XAVideoStreamInformation *)info = streamInfo.videoInfo;
                break;
            case XA_DOMAINTYPE_IMAGE:
                *(XAImageStreamInformation *)info = streamInfo.imageInfo;
                break;
            case XA_DOMAINTYPE_TIMEDTEXT:
                *(XATimedTextStreamInformation *)info = streamInfo.textInfo;
                break;
            case XA_DOMAINTYPE_MIDI:
                *(XAMIDIStreamInformation *)info = streamInfo.midiInfo;
                break;
            case XA_DOMAINTYPE_VENDOR:
                *(XAVendorStreamInformation *)info = streamInfo.vendorInfo;
                break;
            default:
                SL_LOGE("StreamInformation::QueryStreamInformation index %u has "
                        "unknown domain %u", streamIndex, streamInfo.domain);
                result = XA_RESULT_INTERNAL_ERROR;
                break;
            }

        } else {
            SL_LOGE("Querying stream type for stream %d, only %d streams available",
                    streamIndex, nbStreams);
            result = XA_RESULT_PARAMETER_INVALID;
        }

        interface_unlock_shared(thiz);
#endif

    }

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_QueryStreamName( XAStreamInformationItf self,
        XAuint32 streamIndex, /* [in] */
        XAuint16 * pNameSize, /* [in/out] */
        XAchar * pName)       /* [out] */
{
    XA_ENTER_INTERFACE

    if (NULL == pNameSize || streamIndex == 0) {
        result = XA_RESULT_PARAMETER_INVALID;
    } else {
#ifdef ANDROID
        IStreamInformation *thiz = (IStreamInformation *) self;
        interface_lock_shared(thiz);

        XAuint32 nbStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
        // streams in the container are numbered 1..nbStreams
        if (streamIndex <= nbStreams) {
            char streamName[16];        // large enough for the fixed format in next line
            snprintf(streamName, sizeof(streamName), "stream%u", streamIndex);
            size_t actualNameLength = strlen(streamName);
            if (NULL == pName) {
                // application is querying the name length in order to allocate a buffer
                result = XA_RESULT_SUCCESS;
            } else {
                SLuint16 availableNameLength = *pNameSize;
                if (actualNameLength > availableNameLength) {
                    memcpy(pName, streamName, availableNameLength);
                    result = XA_RESULT_BUFFER_INSUFFICIENT;
                } else if (actualNameLength == availableNameLength) {
                    memcpy(pName, streamName, availableNameLength);
                    result = XA_RESULT_SUCCESS;
                } else { // actualNameLength < availableNameLength
                    memcpy(pName, streamName, actualNameLength + 1);
                    result = XA_RESULT_SUCCESS;
                }
            }
            *pNameSize = actualNameLength;
        } else {
            result = XA_RESULT_PARAMETER_INVALID;
        }

        interface_unlock_shared(thiz);
#else
        SL_LOGE("unsupported XAStreamInformationItf function");
        result = XA_RESULT_FEATURE_UNSUPPORTED;
#endif
    }

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_RegisterStreamChangeCallback( XAStreamInformationItf self,
        xaStreamEventChangeCallback callback, /* [in] */
        void * pContext)                      /* [in] */
{
    XA_ENTER_INTERFACE

    IStreamInformation *thiz = (IStreamInformation *) self;

    interface_lock_exclusive(thiz);

    thiz->mCallback = callback;
    thiz->mContext = pContext;
    result = SL_RESULT_SUCCESS;

    interface_unlock_exclusive(thiz);

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_QueryActiveStreams( XAStreamInformationItf self,
        XAuint32 *numStreams,      /* [in/out] */
        XAboolean *activeStreams)  /* [out] */
{
    XA_ENTER_INTERFACE

    if (NULL == numStreams) {
        result = XA_RESULT_PARAMETER_INVALID;
        XA_LEAVE_INTERFACE;
    }

#ifdef ANDROID
    IStreamInformation *thiz = (IStreamInformation *) self;
    interface_lock_shared(thiz);

    result = XA_RESULT_SUCCESS;
    *numStreams = thiz->mStreamInfoTable.itemAt(0).containerInfo.numStreams;
    activeStreams = thiz->mActiveStreams;

    interface_unlock_shared(thiz);
#else
    result = SL_RESULT_FEATURE_UNSUPPORTED;
#endif

    XA_LEAVE_INTERFACE
}


static XAresult IStreamInformation_SetActiveStream( XAStreamInformationItf self,
        XAuint32   streamNum, /* [in] */
        XAboolean  active,    /* [in] */
        XAboolean  commitNow) /* [in] */
{
    XA_ENTER_INTERFACE

    SL_LOGE("unsupported XAStreamInformationItf function");
    result = XA_RESULT_FEATURE_UNSUPPORTED;

    XA_LEAVE_INTERFACE
}


static const struct XAStreamInformationItf_ IStreamInformation_Itf = {
    IStreamInformation_QueryMediaContainerInformation,
    IStreamInformation_QueryStreamType,
    IStreamInformation_QueryStreamInformation,
    IStreamInformation_QueryStreamName,
    IStreamInformation_RegisterStreamChangeCallback,
    IStreamInformation_QueryActiveStreams,
    IStreamInformation_SetActiveStream
};


void IStreamInformation_init(void *self)
{
    SL_LOGV("IStreamInformation_init\n");
    IStreamInformation *thiz = (IStreamInformation *) self;
    thiz->mItf = &IStreamInformation_Itf;

    thiz->mCallback = NULL;
    thiz->mContext = NULL;

    for (int i=0 ; i < NB_SUPPORTED_STREAMS ; i++) {
        thiz->mActiveStreams[i] = XA_BOOLEAN_FALSE;
    }

#ifdef ANDROID
    // placement new constructor for C++ field within C struct
    (void) new (&thiz->mStreamInfoTable) android::Vector<StreamInfo>();
    // initialize container info
    StreamInfo contInf;
    contInf.domain = XA_DOMAINTYPE_CONTAINER;
    contInf.containerInfo.containerType = XA_CONTAINERTYPE_UNSPECIFIED;
    contInf.containerInfo.mediaDuration = XA_TIME_UNKNOWN;
    // FIXME shouldn't this be 1 ?
    contInf.containerInfo.numStreams = 0;
    // always storing container info at index 0, as per spec: here, the table was still empty
    thiz->mStreamInfoTable.add(contInf);
#endif
}


void IStreamInformation_deinit(void *self) {
#ifdef ANDROID
    IStreamInformation *thiz = (IStreamInformation *) self;
    // explicit destructor
    thiz->mStreamInfoTable.~Vector<StreamInfo>();
#endif
}
