///////////////////////////////////////////////////////////////////////////////
//
//  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 {

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

CoverArtBox::Item::Item()
    : type     ( BT_UNDEFINED )
    , buffer   ( NULL )
    , size     ( 0 )
    , autofree ( false )
{
}

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

CoverArtBox::Item::Item( const Item& rhs )
    : type     ( BT_UNDEFINED )
    , buffer   ( NULL )
    , size     ( 0 )
    , autofree ( false )
{
    operator=( rhs );
}

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

CoverArtBox::Item::~Item()
{
    reset();
}

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

CoverArtBox::Item&
CoverArtBox::Item::operator=( const Item& rhs )
{
    type     = rhs.type;
    size     = rhs.size;
    autofree = rhs.autofree;

    if( rhs.autofree ) {
        buffer = (uint8_t*)MP4Malloc(rhs.size);
        memcpy( buffer, rhs.buffer, rhs.size );
    }
    else {
        buffer = rhs.buffer;
    }

    return *this;
}

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

void
CoverArtBox::Item::reset()
{
    if( autofree && buffer )
        MP4Free( buffer );

    type     = BT_UNDEFINED;
    buffer   = NULL;
    size     = 0;
    autofree = false;
}

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

bool
CoverArtBox::add( MP4FileHandle hFile, const Item& item )
{
    MP4File& file = *((MP4File*)hFile);

    const char* const covr_name = "moov.udta.meta.ilst.covr";
    MP4Atom* covr = file.FindAtom( covr_name );
    if( !covr ) {
        file.AddDescendantAtoms( "moov", "udta.meta.ilst.covr" );

        covr = file.FindAtom( covr_name );
        if( !covr )
            return true;
    }

    // use empty data atom if one exists
    MP4Atom* data = NULL;
    uint32_t index = 0;
    const uint32_t atomc = covr->GetNumberOfChildAtoms();
    for( uint32_t i = 0; i < atomc; i++ ) {
        MP4Atom* atom = covr->GetChildAtom( i );

        MP4BytesProperty* metadata = NULL;
        if( !atom->FindProperty( "data.metadata", (MP4Property**)&metadata ))
            continue;

        if( metadata->GetCount() )
            continue;

        data = atom;
        index = i;
        break;
    }

    // no empty atom found, create one.
    if( !data ) {
        data = MP4Atom::CreateAtom( file, covr, "data" );
        covr->AddChildAtom( data );
        data->Generate();
        index = covr->GetNumberOfChildAtoms() - 1;
    }

    return set( hFile, item, index );
}

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

bool
CoverArtBox::get( MP4FileHandle hFile, Item& item, uint32_t index )
{
    item.reset();
    MP4File& file = *((MP4File*)hFile);

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

    if( !(index < covr->GetNumberOfChildAtoms()) )
        return true;

    MP4DataAtom* data = static_cast<MP4DataAtom*>( covr->GetChildAtom( index ));
    if( !data )
        return true;

    MP4BytesProperty* metadata = NULL;
    if ( !data->FindProperty( "data.metadata", (MP4Property**)&metadata ))
        return true;

    metadata->GetValue( &item.buffer, &item.size );
    item.autofree = true;
    item.type = data->typeCode.GetValue();

    return false;
}

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

bool
CoverArtBox::list( MP4FileHandle hFile, ItemList& out )
{
    out.clear();
    MP4File& file = *((MP4File*)hFile);
    MP4ItmfItemList* itemList = genericGetItemsByCode( file, "covr" ); // alloc

    if( itemList->size ) {
        MP4ItmfDataList& dataList = itemList->elements[0].dataList;
        out.resize( dataList.size );
        for( uint32_t i = 0; i < dataList.size; i++ )
            get( hFile, out[i], i );
    }

    genericItemListFree( itemList ); // free
    return false;
}

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

bool
CoverArtBox::remove( MP4FileHandle hFile, uint32_t index )
{
    MP4File& file = *((MP4File*)hFile);

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

    // wildcard mode: delete covr and all images
    if( index == std::numeric_limits<uint32_t>::max() ) {
        covr->GetParentAtom()->DeleteChildAtom( covr );
        delete covr;
        return false;
    }

    if( !(index < covr->GetNumberOfChildAtoms()) )
        return true;

    MP4Atom* data = covr->GetChildAtom( index );
    if( !data )
        return true;

    // delete single image
    covr->DeleteChildAtom( data );
    delete data;

    // delete empty covr
    if( covr->GetNumberOfChildAtoms() == 0 ) {
        covr->GetParentAtom()->DeleteChildAtom( covr );
        delete covr;
    }

    return false;
}

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

bool
CoverArtBox::set( MP4FileHandle hFile, const Item& item, uint32_t index )
{
    MP4File& file = *((MP4File*)hFile);

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

    if( !(index < covr->GetNumberOfChildAtoms()) )
        return true;

    MP4DataAtom* data = static_cast<MP4DataAtom*>( covr->GetChildAtom( index ));
    if( !data )
        return true;

    MP4BytesProperty* metadata = NULL;
    if ( !data->FindProperty( "data.metadata", (MP4Property**)&metadata ))
        return true;

    // autodetect type if BT_UNDEFINED
    const BasicType final_type = (item.type == BT_UNDEFINED)
        ? computeBasicType( item.buffer, item.size )
        : item.type;

    // set type; note: not really flags due to b0rked atom structure
    data->typeCode.SetValue( final_type );
    metadata->SetValue( item.buffer, item.size );

    return false;
}

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

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