///////////////////////////////////////////////////////////////////////////////
//
//  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 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 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 string& meaning, const 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
