///////////////////////////////////////////////////////////////////////////////
//
//  The contents of this file are subject to the Mozilla Public License
//  Version 1.1 (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.mozilla.org/MPL/
//
//  Software distributed under the License is distributed on an "AS IS"
//  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//  License for the specific language governing rights and limitations
//  under the License.
// 
//  The Original Code is MP4v2.
// 
//  The Initial Developer of the Original Code is Kona Blend.
//  Portions created by Kona Blend are Copyright (C) 2008.
//  All Rights Reserved.
//
//  Contributors:
//      Kona Blend, kona8lend@@gmail.com
//
///////////////////////////////////////////////////////////////////////////////

#include "impl.h"

namespace mp4v2 { namespace impl { namespace itmf { namespace {

///////////////////////////////////////////////////////////////////////////////

void
__dataInit( MP4ItmfData& data )
{
    data.typeSetIdentifier = 0;
    data.typeCode          = MP4_ITMF_BT_IMPLICIT;
    data.locale            = 0;
    data.value             = NULL;
    data.valueSize         = 0;
}

void
__dataClear( MP4ItmfData& data )
{
    if( data.value )
        free( data.value );
    __dataInit( data );
}

///////////////////////////////////////////////////////////////////////////////

void
__dataListInit( MP4ItmfDataList& list )
{
    list.elements = NULL;
    list.size     = 0;
}

void
__dataListClear( MP4ItmfDataList& list )
{
    if( list.elements ) {
        for( uint32_t i = 0; i < list.size; i++ )
            __dataClear( list.elements[i] );
        free( list.elements );
    }

    __dataListInit( list );
}

void
__dataListResize( MP4ItmfDataList& list, uint32_t size )
{
    __dataListClear( list );

    list.elements = (MP4ItmfData*)malloc( sizeof( MP4ItmfData ) * size );
    list.size     = size;

    for( uint32_t i = 0; i < size; i++ )
        __dataInit( list.elements[i] );
}

///////////////////////////////////////////////////////////////////////////////

void
__itemInit( MP4ItmfItem& item )
{
    item.__handle = NULL;
    item.code     = NULL;
    item.mean     = NULL;
    item.name     = NULL;

    __dataListInit( item.dataList );
}

void
__itemClear( MP4ItmfItem& item )
{
    if( item.code )
        free( item.code );
    if( item.mean )
        free( item.mean );
    if( item.name )
        free( item.name );

    __dataListClear( item.dataList );
    __itemInit( item );
}

///////////////////////////////////////////////////////////////////////////////

void
__itemListInit( MP4ItmfItemList& list )
{
    list.elements = NULL;
    list.size     = 0;
}

void
__itemListClear( MP4ItmfItemList& list )
{
    if( list.elements ) {
        for( uint32_t i = 0; i < list.size; i++ )
            __itemClear( list.elements[i] );
        free( list.elements );
    }

    __itemListInit( list );
}

void
__itemListResize( MP4ItmfItemList& list, uint32_t size )
{
    __itemListClear( list );
    if( !size )
        return;

    list.elements = (MP4ItmfItem*)malloc( sizeof( MP4ItmfItem ) * size );
    list.size     = size;

    for( uint32_t i = 0; i < size; i++ )
        __itemInit( list.elements[i] );
}

MP4ItmfItemList*
__itemListAlloc()
{
    MP4ItmfItemList& list = *(MP4ItmfItemList*)malloc( sizeof( MP4ItmfItemList ));
    __itemListInit( list );
    return &list;
}

///////////////////////////////////////////////////////////////////////////////

static bool
__itemAtomToModel( MP4ItemAtom& item_atom, MP4ItmfItem& model )
{
    __itemClear( model );
    model.__handle = &item_atom;
    model.code     = strdup( item_atom.GetType() );

    // handle special meaning atom
    if( ATOMID( item_atom.GetType() ) == ATOMID( "----" )) {
        // meaning is mandatory
        MP4MeanAtom* mean = (MP4MeanAtom*)item_atom.FindAtom( "----.mean" );
        if( !mean )
            return true;

        // copy atom UTF-8 value (not NULL-terminated) to model (NULL-terminated)
        model.mean = mean->value.GetValueStringAlloc();

        // name is optional
        MP4NameAtom* name = (MP4NameAtom*)item_atom.FindAtom( "----.name" );
        if( name ) {
            // copy atom UTF-8 value (not NULL-terminated) to model (NULL-terminated)
            model.name = name->value.GetValueStringAlloc();
        }
    }

    // pass 1: count data atoms
    const uint32_t childCount = item_atom.GetNumberOfChildAtoms();
    uint32_t dataCount = 0;
    for( uint32_t i = 0; i < childCount; i++ ) {
        if( ATOMID( item_atom.GetChildAtom( i )->GetType() ) != ATOMID( "data" ))
            continue;
        dataCount++;
    }

    // one or more data atoms is mandatory
    if( dataCount < 1 )
        return true;

    __dataListResize( model.dataList, dataCount );

    // pass 2: populate data model
    for( uint32_t i = 0, idata = 0; i < childCount; i++ ) {
        MP4Atom* atom = item_atom.GetChildAtom( i );
        if( ATOMID( atom->GetType() ) != ATOMID( "data" ))
            continue;

        MP4DataAtom& data_atom = *(MP4DataAtom*)atom;
        MP4ItmfData& data_model = model.dataList.elements[idata];

        data_model.typeSetIdentifier = data_atom.typeSetIdentifier.GetValue();
        data_model.typeCode          = (MP4ItmfBasicType)data_atom.typeCode.GetValue();
        data_model.locale            = data_atom.locale.GetValue();

        data_atom.metadata.GetValue( &data_model.value, &data_model.valueSize );
        idata++;
    }

    return false;
}

///////////////////////////////////////////////////////////////////////////////

static bool
__itemModelToAtom( const MP4ItmfItem& model, MP4ItemAtom& atom )
{
    if( ATOMID( atom.GetType() ) == ATOMID( "----" )) {
        ASSERT( model.mean ); // mandatory
        MP4MeanAtom& meanAtom = *(MP4MeanAtom*)MP4Atom::CreateAtom( atom.GetFile(), &atom, "mean" );
        atom.AddChildAtom( &meanAtom );
        meanAtom.value.SetValue( (const uint8_t*)model.mean, (uint32_t)strlen( model.mean ));

        if( model.name ) {
            MP4NameAtom& nameAtom = *(MP4NameAtom*)MP4Atom::CreateAtom( atom.GetFile(), &atom, "name" );
            atom.AddChildAtom( &nameAtom );
            nameAtom.value.SetValue( (const uint8_t*)model.name, (uint32_t)strlen( model.name ));
        }
    }

    for( uint32_t i = 0; i < model.dataList.size; i++ ) {
        MP4ItmfData& dataModel = model.dataList.elements[i];
        MP4DataAtom& dataAtom = *(MP4DataAtom*)MP4Atom::CreateAtom( atom.GetFile(), &atom, "data" );
        atom.AddChildAtom( &dataAtom );

        dataAtom.typeSetIdentifier.SetValue( dataModel.typeSetIdentifier );
        dataAtom.typeCode.SetValue( (itmf::BasicType)dataModel.typeCode );
        dataAtom.locale.SetValue( dataModel.locale );
        dataAtom.metadata.SetValue( dataModel.value, dataModel.valueSize );
    }

    return true;
}

///////////////////////////////////////////////////////////////////////////////

} // namespace anonymous

///////////////////////////////////////////////////////////////////////////////

MP4ItmfItem*
genericItemAlloc( const std::string& code, uint32_t numData )
{
    MP4ItmfItem* item = (MP4ItmfItem*)malloc( sizeof( MP4ItmfItem ));
    if( !item )
        return NULL;

    __itemInit( *item );
    item->code = strdup( code.c_str() );

    // always create array size of 1
    __dataListResize( item->dataList, numData );

    return item;
}

///////////////////////////////////////////////////////////////////////////////

void
genericItemFree( MP4ItmfItem* item )
{
    if( !item )
        return;

    __itemClear( *item );
    free( item );
}

///////////////////////////////////////////////////////////////////////////////

void
genericItemListFree( MP4ItmfItemList* list )
{
    if( !list )
        return;

    __itemListClear( *list );
    free( list );
}

///////////////////////////////////////////////////////////////////////////////

MP4ItmfItemList*
genericGetItems( MP4File& file )
{
    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst )
        return __itemListAlloc();

    const uint32_t itemCount = ilst->GetNumberOfChildAtoms();
    if( itemCount < 1 )
        return __itemListAlloc();

    MP4ItmfItemList& list = *__itemListAlloc();
    __itemListResize( list, itemCount );

    for( uint32_t i = 0; i < list.size; i++ )
        __itemAtomToModel( *(MP4ItemAtom*)ilst->GetChildAtom( i ), list.elements[i] );

    return &list;
}

///////////////////////////////////////////////////////////////////////////////

MP4ItmfItemList*
genericGetItemsByCode( MP4File& file, const std::string& code )
{
    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst )
        return __itemListAlloc();

    // pass 1: filter by code and populate indexList
    const uint32_t childCount = ilst->GetNumberOfChildAtoms();
    std::vector<uint32_t> indexList;
    for( uint32_t i = 0; i < childCount; i++ ) {
        if( ATOMID( ilst->GetChildAtom( i )->GetType() ) != ATOMID( code.c_str() ))
            continue;
        indexList.push_back( i );
    }

    if( indexList.size() < 1 )
        return __itemListAlloc();

    MP4ItmfItemList& list = *__itemListAlloc();
    __itemListResize( list, (uint32_t)indexList.size() );

    // pass 2: process each atom
    const std::vector<uint32_t>::size_type max = indexList.size();
    for( std::vector<uint32_t>::size_type i = 0; i < max; i++ ) {
        uint32_t& aidx = indexList[i];
        __itemAtomToModel( *(MP4ItemAtom*)ilst->GetChildAtom( aidx ), list.elements[i] );
    }

    return &list;
}

///////////////////////////////////////////////////////////////////////////////

MP4ItmfItemList*
genericGetItemsByMeaning( MP4File& file, const std::string& meaning, const std::string& name )
{
    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst )
        return __itemListAlloc();

    // pass 1: filter by code and populate indexList
    const uint32_t childCount = ilst->GetNumberOfChildAtoms();
    std::vector<uint32_t> indexList;
    for( uint32_t i = 0; i < childCount; i++ ) {
        MP4Atom& atom = *ilst->GetChildAtom( i );
        if( ATOMID( atom.GetType() ) != ATOMID( "----" ))
            continue;

        // filter-out meaning mismatch
        MP4MeanAtom* meanAtom = (MP4MeanAtom*)atom.FindAtom( "----.mean" );
        if( !meanAtom )
            continue;
        if( meanAtom->value.CompareToString( meaning ))
            continue;

        if( !name.empty() ) {
            // filter-out name mismatch
            MP4MeanAtom* nameAtom = (MP4MeanAtom*)atom.FindAtom( "----.name" );
            if( !nameAtom )
                continue;
            if( nameAtom->value.CompareToString( name ))
                continue;
        }

        indexList.push_back( i );
    }

    if( indexList.size() < 1 )
        return __itemListAlloc();

    MP4ItmfItemList& list = *__itemListAlloc();
    __itemListResize( list, (uint32_t)indexList.size() );

    // pass 2: process each atom
    const std::vector<uint32_t>::size_type max = indexList.size();
    for( std::vector<uint32_t>::size_type i = 0; i < max; i++ ) {
        uint32_t& aidx = indexList[i];
        __itemAtomToModel( *(MP4ItemAtom*)ilst->GetChildAtom( aidx ), list.elements[i] );
    }

    return &list;
}

///////////////////////////////////////////////////////////////////////////////

bool
genericAddItem( MP4File& file, const MP4ItmfItem* item )
{
    if( !item )
        return false;

    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst ) {
        file.AddDescendantAtoms( "moov", "udta.meta.ilst" );
        ilst = file.FindAtom( "moov.udta.meta.ilst" );
        ASSERT( ilst );
    }

    MP4ItemAtom& itemAtom = *(MP4ItemAtom*)MP4Atom::CreateAtom( file, ilst, item->code );
    ilst->AddChildAtom( &itemAtom );

    return __itemModelToAtom( *item, itemAtom );
}

///////////////////////////////////////////////////////////////////////////////

bool
genericSetItem( MP4File& file, const MP4ItmfItem* item )
{
    if( !item || !item->__handle )
        return false;

    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst )
        return false;

    MP4ItemAtom* const old = static_cast<MP4ItemAtom*>(item->__handle);
    const uint32_t childCount = ilst->GetNumberOfChildAtoms();
    uint32_t fidx = std::numeric_limits<uint32_t>::max();
    for( uint32_t i = 0; i < childCount; i++ ) {
        MP4Atom* atom = ilst->GetChildAtom( i );
        if( atom == old ) {
            fidx = i;
            break;
        }
    }

    if( fidx == std::numeric_limits<uint32_t>::max() )
        return false;

    ilst->DeleteChildAtom( old );
    delete old;

    MP4ItemAtom& itemAtom = *(MP4ItemAtom*)MP4Atom::CreateAtom( file, ilst, item->code );
    ilst->InsertChildAtom( &itemAtom, fidx );

    return __itemModelToAtom( *item, itemAtom );
}

///////////////////////////////////////////////////////////////////////////////

bool
genericRemoveItem( MP4File& file, const MP4ItmfItem* item )
{
    if( !item || !item->__handle )
        return false;

    MP4Atom* ilst = file.FindAtom( "moov.udta.meta.ilst" );
    if( !ilst )
        return false;

    MP4ItemAtom* const old = static_cast<MP4ItemAtom*>(item->__handle);
    ilst->DeleteChildAtom( old );
    delete old;

    return true;
}

///////////////////////////////////////////////////////////////////////////////

}}} // namespace mp4v2::impl::itmf
