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

/* MetadataExtraction implementation */

#include "sles_allinclusive.h"


static SLresult IMetadataExtraction_GetItemCount(SLMetadataExtractionItf self, SLuint32 *pItemCount)
{
    SL_ENTER_INTERFACE

    if (NULL == pItemCount) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            result = android_audioPlayer_metadata_getItemCount((CAudioPlayer *)thiz->mThis,
                    pItemCount);
        } else {
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_GetKeySize(SLMetadataExtractionItf self,
    SLuint32 index, SLuint32 *pKeySize)
{
    SL_ENTER_INTERFACE

    if (NULL == pKeySize) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            result = android_audioPlayer_metadata_getKeySize((CAudioPlayer *)thiz->mThis,
                    index, pKeySize);
        } else {
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_GetKey(SLMetadataExtractionItf self,
    SLuint32 index, SLuint32 keySize, SLMetadataInfo *pKey)
{
    SL_ENTER_INTERFACE

    if (NULL == pKey) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            result = android_audioPlayer_metadata_getKey((CAudioPlayer *)thiz->mThis,
                    index, keySize, pKey);
        } else {
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_GetValueSize(SLMetadataExtractionItf self,
    SLuint32 index, SLuint32 *pValueSize)
{
    SL_ENTER_INTERFACE

    if (NULL == pValueSize) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            result = android_audioPlayer_metadata_getValueSize((CAudioPlayer *)thiz->mThis,
                    index, pValueSize);
        } else {
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_GetValue(SLMetadataExtractionItf self,
    SLuint32 index, SLuint32 valueSize, SLMetadataInfo *pValue)
{
    SL_ENTER_INTERFACE

    if (NULL == pValue) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        if (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) {
            result = android_audioPlayer_metadata_getValue((CAudioPlayer *)thiz->mThis,
                    index, valueSize, pValue);
        } else {
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_AddKeyFilter(SLMetadataExtractionItf self,
    SLuint32 keySize, const void *pKey, SLuint32 keyEncoding,
    const SLchar *pValueLangCountry, SLuint32 valueEncoding, SLuint8 filterMask)
{
    SL_ENTER_INTERFACE

    if (NULL == pKey || NULL == pValueLangCountry || (filterMask & ~(SL_METADATA_FILTER_KEY |
        SL_METADATA_FILTER_KEY | SL_METADATA_FILTER_KEY))) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IMetadataExtraction *thiz = (IMetadataExtraction *) self;
        interface_lock_exclusive(thiz);
        thiz->mKeySize = keySize;
        thiz->mKey = pKey;
        thiz->mKeyEncoding = keyEncoding;
        thiz->mValueLangCountry = pValueLangCountry; // should make a local copy
        thiz->mValueEncoding = valueEncoding;
        thiz->mFilterMask = filterMask;
        interface_unlock_exclusive(thiz);
        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}


static SLresult IMetadataExtraction_ClearKeyFilter(SLMetadataExtractionItf self)
{
    SL_ENTER_INTERFACE

    IMetadataExtraction *thiz = (IMetadataExtraction *) self;
    thiz->mKeyFilter = 0;
    result = SL_RESULT_SUCCESS;

    SL_LEAVE_INTERFACE
}


static const struct SLMetadataExtractionItf_ IMetadataExtraction_Itf = {
    IMetadataExtraction_GetItemCount,
    IMetadataExtraction_GetKeySize,
    IMetadataExtraction_GetKey,
    IMetadataExtraction_GetValueSize,
    IMetadataExtraction_GetValue,
    IMetadataExtraction_AddKeyFilter,
    IMetadataExtraction_ClearKeyFilter
};

void IMetadataExtraction_init(void *self)
{
    IMetadataExtraction *thiz = (IMetadataExtraction *) self;
    thiz->mItf = &IMetadataExtraction_Itf;
    thiz->mKeySize = 0;
    thiz->mKey = NULL;
    thiz->mKeyEncoding = 0 /*TBD*/;
    thiz->mValueLangCountry = 0 /*TBD*/;
    thiz->mValueEncoding = 0 /*TBD*/;
    thiz->mFilterMask = 0 /*TBD*/;
    thiz->mKeyFilter = 0;
}
