// ----------------------------------------------------------------------------
// Create the playback utility object
// ----------------------------------------------------------------------------
//
EXPORT_C void CMPXAlbumArtUtility::ExtractAlbumArtL(const CMPXMedia& aMedia,
                                            MMPXAlbumArtUtilityObserver& aObs,
                                            const TSize& aSize, 
                                            TDisplayMode aDisplayMode /*= EColor64K*/)
    {
    MPX_FUNC_EX( "CMPXAlbumArtUtility::ExtractAlbumArtL" );

    if ( iCurrentOp != EIdle )
        {
        User::Leave( KErrNotReady );
        }

    if ( aMedia.IsSupported( KMPXMediaMusicAlbumArtFileName ) )
        {
        if ( aMedia.ValueText( KMPXMediaMusicAlbumArtFileName ).Length() == 0)
            {
            User::Leave( KErrNotFound );
            }
        }

    if ( aMedia.IsSupported( KMPXMediaGeneralUri ) &&
         aMedia.IsSupported( KMPXMediaMusicAlbumArtFileName ))
        {
        if ( aMedia.ValueText( KMPXMediaGeneralUri ).CompareF( 
             aMedia.ValueText( KMPXMediaMusicAlbumArtFileName ) ) == 0 )
            { // embedded album art            
            iObs = &aObs;
            delete iAlbumArt;
            iAlbumArt = NULL;
            iAlbumArt = iImageUtil->ExtractL( aMedia.ValueText( KMPXMediaMusicAlbumArtFileName ) );
            if ( iAlbumArt )
                {
                iCurrentOp = EExtractAlbumArtL;
                iObs->ExtractAlbumArtStarted();
                SetActive();
                iImageUtil->Decode( iStatus, *iAlbumArt, *iBitmap, aSize, aDisplayMode );                
                }
            else
                {
                User::Leave( KErrUnderflow );
                }            
            }
        else
            {
            iCurrentOp = EExtractAlbumArtL;
            // TO-DO: if we save externalize bitmap, we only need to internalize bitmap here.
            iObs->ExtractAlbumArtStarted();
            SetActive();
            iImageUtil->Decode( iStatus, aMedia.ValueText( 
                KMPXMediaMusicAlbumArtFileName ), *iBitmap, aSize, aDisplayMode );
            }    
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    }
// ----------------------------------------------------------------------------------------------------------
// Find the items matching the media specifications
// ----------------------------------------------------------------------------------------------------------
//
void CTestCollectionPlugin::FindAllL(const CMPXMedia& aCriteria, const TArray<TMPXAttribute>& aAttrs)
{
    LOG1(_L("CTestCollectionPlugin::FindAllL"));
    const TDesC& title = aCriteria.ValueText( KMPXMediaGeneralTitle );
    if(title == _L("CollectionPluginTest0128") ||
            title == _L("CollectionPluginTest0129") )
    {
        // Return exact copy
        CMPXMedia* media = CMPXMedia::NewL();
        (*media) = aCriteria;
        CleanupStack::PushL( media );
        media->SetTObjectValueL<TInt>(KMPXMediaGeneralSize, aAttrs.Count());
        iObs->HandleFindAll(media, KErrNone);
        CleanupStack::PopAndDestroy( media );
    }
    else if(title == _L("CollectionPluginTest0130") )
    {
        // Return error
        CMPXMedia* media = CMPXMedia::NewL();
        (*media) = aCriteria;
        CleanupStack::PushL( media );
        media->SetTObjectValueL<TInt>(KMPXMediaGeneralSize, aAttrs.Count());
        iObs->HandleFindAll(media, KErrArgument);
        CleanupStack::PopAndDestroy( media );
    }
    else
    {
        User::Panic(_L("CTestCollectionPlugin::FindAllL panic"), 1); // magic number
    }
}
// ----------------------------------------------------------------------------------------------------------
// Adds an item (song or playlist) to the collection
// ----------------------------------------------------------------------------------------------------------
//
void CTestCollectionPlugin::AddL (const CMPXMedia& aMedia)
{
    LOG1(_L("CTestCollectionPlugin::AddL"));
    CMPXMessage* message = CMPXMessage::NewL();
    CleanupStack::PushL( message );

    const TDesC& title = aMedia.ValueText( KMPXMediaGeneralTitle );

    if(title == _L("CollectionPluginTest0078") )
    {
        FillItemChangeMessageL(*message, 78, EMPXItemInserted, EMPXOther);
    }
    else if(title == _L("CollectionPluginTest0079"))
    {
        FillItemChangeMessageL(*message, 79, EMPXItemInserted, EMPXSong);
    }
    else if(title == _L("CollectionPluginTest0080"))
    {
        FillItemChangeMessageL(*message, 80, EMPXItemInserted, EMPXPlaylist);
    }
    else
    {
        User::Panic(_L("CTestCollectionPlugin::AddL panic"), 1); // magic number
    }
    iObs->HandleMessage( *message );
    CleanupStack::PopAndDestroy( message );
}
// ----------------------------------------------------------------------------
// Adds an item to the collection
// ----------------------------------------------------------------------------
//
void CGlxMediaListsTestCollectionPlugin::AddL(const CMPXMedia& aNewMedia)
    {
    TInt error = KErrNotSupported;
    TInt idAdded = iItemAddedId;

    TMPXGeneralCategory category
            = *aNewMedia.Value<TMPXGeneralCategory>(KMPXMediaGeneralCategory);

    if ( EMPXAlbum == category )
        {
        const TDesC& title = aNewMedia.ValueText(KMPXMediaGeneralTitle);

	InsertItemL(KNullDesC, title, _iItemDBHackAlbums);
        error = KErrNone;
        }
    else if ( EMPXImage == category )
	{
	InsertItemL(_L("c:\\newitem1.jpg"), _L("newitem"), _iItemDBHackContent, TTime(_L("20061105:092527.")), 125371, _L("E:"));
	error = KErrNone;
	}

    if ( iObs )
        {
        if ( KErrNone != error )
            {
            User::Leave(error);
            }
        else
            {
		CMPXMessage* message = CMPXMessage::NewL();
		CleanupStack::PushL(message);

		message->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, KMPXMessageIdItemChanged);
		message->SetTObjectValueL<TUid>(KMPXMessageCollectionId, TUid::Uid(KGlxMediaListsTestCollectionImplementationUid));
		message->SetTObjectValueL<TMPXChangeEventType>(KMPXMessageChangeEventType, EMPXItemInserted);
		message->SetTObjectValueL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory, category);
		message->SetTObjectValueL<TMPXItemId>(KMPXMessageMediaGeneralId, TMPXItemId(idAdded));

		iObs->HandleMessage(*message);

		CleanupStack::PopAndDestroy(message);

/*		    TMPXCollectionChangeEvent event = {TUid::Uid(KGlxMediaListsTestCollectionImplementationUid), idAdded, EMcItemInserted};
		    RArray<TMPXCollectionChangeEvent> events;
		    CleanupClosePushL(events);
		    events.AppendL(event);
		    iObs->HandleChange(events.Array());
		    CleanupStack::PopAndDestroy(&events);
*/          }
        }
    }
// ----------------------------------------------------------------------------------------------------------
// Remove an item from the collection database using the given media properties
// ----------------------------------------------------------------------------------------------------------
//
void CTestCollectionPlugin::RemoveL (const CMPXMedia& aMedia)
{
    LOG1(_L("CTestCollectionPlugin::RemoveL"));
    const TDesC& title = aMedia.ValueText( KMPXMediaGeneralTitle );

    // a list of change event messages a result of the item being removed
    CMPXMessageArray* itemChangedMessages = CMPXMessageArray::NewL();
    CleanupStack::PushL(itemChangedMessages);

    if(title == _L("CollectionPluginTest0099") )
    {
        CMPXMessage* message = CMPXMessage::NewL();
        CleanupStack::PushL(message);
        FillItemChangeMessageL(*message, 99, EMPXItemDeleted, EMPXSong);
        itemChangedMessages->AppendL( *message );
        CleanupStack::PopAndDestroy(message);
    }
    else if(title == _L("CollectionPluginTest0100") )
    {
        CMPXMessage* message = CMPXMessage::NewL();
        CleanupStack::PushL(message);
        FillItemChangeMessageL(*message, 100, EMPXItemDeleted, EMPXSong);
        itemChangedMessages->AppendL( *message );
        CleanupStack::PopAndDestroy(message);
        message = NULL;
        message = CMPXMessage::NewL();
        CleanupStack::PushL(message);
        FillItemChangeMessageL(*message, 100, EMPXItemDeleted, EMPXSong);
        itemChangedMessages->AppendL( *message );
        CleanupStack::PopAndDestroy(message);
    }
    else
    {
        User::Panic(_L("CTestCollectionPlugin::RemoveL panic"), 1); // magic number
    }

    CMPXMessage* message = CMPXMessage::NewL();
    CleanupStack::PushL(message);

    message->SetTObjectValueL<TMPXMessageId>(
        TMPXAttribute(KMPXMessageContentIdGeneral, EMPXMessageGeneralId), KMPXMessageIdItemChanged);
    message->SetCObjectValueL(
        TMPXAttribute(KMPXMessageIdContainer, EMPXMessageArrayContents), itemChangedMessages);
    message->SetTObjectValueL(
        TMPXAttribute(KMPXMessageIdContainer, EMPXMessageArrayCount), itemChangedMessages->Count());

    iObs->HandleMessage( *message );
    CleanupStack::PopAndDestroy(2, itemChangedMessages);    // message, itemChangedMessages
}
/*!
 Stub function.
*/
void MMPXCollectionUiHelper::RenameL( const CMPXMedia& aMedia,
                              MMPXCHelperObserver* aObserver )
{
    Q_UNUSED(aObserver);
    iValidRename = EFalse;
    TMPXGeneralType mediaType =
            aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);

    TMPXGeneralCategory mediaCategory =
            aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
    
    if ( mediaType == EMPXItem && mediaCategory == EMPXPlaylist ){
        iValidRename = ETrue;
    }
    iPlaylistId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
    const TDesC& title = aMedia.ValueText(KMPXMediaGeneralTitle);
    iRenameTitle = QString::fromUtf16(title.Ptr(), title.Length());
}
// ----------------------------------------------------------------------------------------------------------
// Filter out media in aMediaArray which match aFilter
// ----------------------------------------------------------------------------------------------------------
//
void CTestCollectionPlugin::FilterMediaArray(CMPXMediaArray& aMediaArray, CMPXFilter* aFilter)
{
    if(aFilter )
    {
        TArray<TMPXAttribute> filterAttr = aFilter->Attributes();
        TInt arrCnt = aMediaArray.Count();
        for(TInt i = arrCnt-1; i >= 0; i--) // Remove from the back
        {
            CMPXMedia* media = aMediaArray[i];
            for(TInt ii = 0; ii < filterAttr.Count(); ii++)
            {
                TMPXAttribute attr = filterAttr[ii];
                if( media->IsSupported( attr ) )
                {
                    TBool match = EFalse;
                    if(attr == KMPXMediaGeneralId)
                    {
                        TInt filterId = *aFilter->Value<TInt>( attr );
                        TInt mediaId = *media->Value<TInt>( attr );
                        if(filterId == mediaId)
                            match = ETrue;
                    }
                    else if(attr == KMPXMediaGeneralTitle || attr == KMPXMediaGeneralUri)
                    {
                        const TDesC& filterText = aFilter->ValueText( attr );
                        const TDesC& mediaText = media->ValueText( attr );
                        if(filterText == mediaText)
                            match = ETrue;
                    }
                    if( match )
                    {
                        aMediaArray.Remove( i );
                        break;
                    }
                }
            }
        }
    }
}
// ---------------------------------------------------------------------------
// From MMPXPlaybackCallback
// Handle media
// ---------------------------------------------------------------------------
//
void CAiPlayerPluginEngine::HandleMediaL( const CMPXMedia& aMedia, 
        TInt aError )
    {
    //MPX_DEBUG1("CAiPlayerPluginEngine::HandleMediaL");
    if ( KErrNone == aError )
        {
        delete iUri;
        iUri = NULL;
        if (aMedia.IsSupported(KMPXMediaGeneralUri))
            {
            TParsePtrC filePath(aMedia.ValueText(KMPXMediaGeneralUri) );
            iUri = filePath.FullName().AllocL();
            }
        
		delete iTitle;
		iTitle = NULL;
        if ( aMedia.IsSupported( KMPXMediaGeneralTitle ) )
            {
            iTitle = ( aMedia.ValueText( KMPXMediaGeneralTitle ) ).AllocL();
            }
        else if ( aMedia.IsSupported( KMPXMediaGeneralUri ) )
            {
            TParsePtrC filePath( aMedia.ValueText( KMPXMediaGeneralUri ) );
            iTitle = (filePath.Name()).AllocL();
            }
		delete iArtist;
		iArtist = NULL;
		iArtist = ( aMedia.ValueText( KMPXMediaMusicArtist ) ).AllocL();
		
		iObserver->TrackInfoChanged( *iTitle, *iArtist );
        
		if (!iSkipping)
            {
            if (iExtractingAlbumArt)
                {
                //iAlbumArtUtil->CancelRequest();
                iExtractingAlbumArt=EFalse;
                }
            /*
            if ( aMedia.IsSupported( KMPXMediaMusicAlbumArtFileName ) )
                {
                delete iMedia;
                iMedia=NULL;
                iMedia = CMPXMedia::NewL( aMedia );
             
                TRAPD(err,iAlbumArtUtil->ExtractAlbumArtL(
                        *iMedia,
                        *this,
                        TSize(70,70)));
                
                if (err != KErrNone)
                    {
                    iObserver->AlbumArtChanged(NULL);
                    }
                }
            else
                {
                iObserver->AlbumArtChanged(NULL);
                }
                */
            }
		else
		    {
		    iObserver->AlbumArtChanged(NULL);
		    }
        }
    }
// ---------------------------------------------------------------------------
// rename a media object
// ---------------------------------------------------------------------------
//
void CMPXCollectionHelperImp::RenameL( const TDesC& aOldUri,
                                       const TDesC& aNewUri,
                                       TMPXGeneralCategory aItemCat )
    {
    MPX_FUNC("CMPXCollectionHelperImp::RenameL");
    MPX_DEBUG3("aOldUri = %S, aNewUri = %S", &aOldUri, &aNewUri);

    if (aItemCat != EMPXSong && aItemCat != EMPXPlaylist && aItemCat != EMPXAbstractAlbum)
        {
        User::Leave(KErrArgument);
        }

    // find the media using the old URI
    RArray<TMPXAttribute> attributes;
    CleanupClosePushL( attributes );
    attributes.AppendL(KMPXMediaGeneralId);
    attributes.AppendL(KMPXMediaMusicAlbumArtFileName);

    CMPXMedia* media = GetL(aOldUri, attributes.Array(), aItemCat);
    CleanupStack::PopAndDestroy(&attributes);
    CleanupStack::PushL(media);

    const TDesC& fileName(media->ValueText(KMPXMediaMusicAlbumArtFileName));
    
    // the songs have embedded albumart.
    if(fileName.CompareF(aOldUri) == 0)
        {
        // change the Art filename to the new Uri
        media->SetTextValueL(KMPXMediaMusicAlbumArtFileName, aNewUri);
        
        // Rename the thumbnail
        TRAPD(err, RenameThumbnailL(aOldUri, aNewUri));
        if(KErrNone != err)
            {
            MPX_DEBUG2("Thumbnail renames failed. Err: %d", err);
            }
        }

    // change file path to the new file path
    media->SetTextValueL(KMPXMediaGeneralUri, aNewUri);

    // ask harvester to rename the file if any of the following is true:
    // 1) renaming a song
    // 2) renaming a playlist scanned through file system.
    //
    //    There are 3 types of playlists. The ones created from the device
    //    are virtual playlists which have file extension .vir. There are
    //    no physical playlist files associated with them; hence not
    //    registered with harvester. For virtual playlists, IsPlaylistL
    //    will return EFalse because there is not a playlist plugin that
    //    deals with .vir playlist files.
    //
    //    The ones synced from PC through MTP have file extension .pla.
    //    There are 0-byte .pla files associated with them but they
    //    are not registered with harvester either. IsPlaylistL will also
    //    return EFalse because there is not a playlist plugin that deals
    //    with .pla.
    //
    //    The 3rd type of playlists is .m3u on the file system. They are
    //    added to the collection through file scan and registered with
    //    harvester. IsPlaylistL will return ETrue.
    if (aItemCat == EMPXSong || iHvsUtility->IsPlaylistL(aOldUri))
        {
        const TUid& collection =
             media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId);
        iHvsUtility->RenameFileL( aOldUri, aNewUri, collection.iUid );
        }

    // Update collection via CMPXCommand
    //
    CMPXCommand* cmd = CMPXCommand::NewL();
    CleanupStack::PushL( cmd );
    cmd->SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdCollectionSet );
    TUid colId (media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId) );
    cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, colId.iUid );
    cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue );
    cmd->SetCObjectValueL( KMPXCommandColSetMedia, media );
    iCollectionUtil->Collection().CommandL( *cmd );
    CleanupStack::PopAndDestroy( cmd );

    CleanupStack::PopAndDestroy(media);
    }
// ---------------------------------------------------------------------------
// From MMPXPlaybackCallback
// Handle media
// ---------------------------------------------------------------------------
//
void CAiPlayerPluginEngine::HandleMediaL( const CMPXMedia& aMedia, 
        TInt aError )
    {
    if ( KErrNone == aError )
        {
        delete iUri;
        iUri = NULL;
        if (aMedia.IsSupported(KMPXMediaGeneralUri))
            {
            TParsePtrC filePath(aMedia.ValueText(KMPXMediaGeneralUri) );
            iUri = filePath.FullName().AllocL();
            }
        
		delete iTitle;
		iTitle = NULL;
        if ( aMedia.IsSupported( KMPXMediaGeneralTitle ) )
            {
            iTitle = ( aMedia.ValueText( KMPXMediaGeneralTitle ) ).AllocL();
            }
        else if ( aMedia.IsSupported( KMPXMediaGeneralDuration))
        {
            RDebug::Print(_L("duration found"));
            TInt val=aMedia.ValueTObjectL<TInt>( KMPXMediaGeneralDuration );
            RDebug::Print(_L("val %d"),val);
            iDuration=val/KMPXOneSecInMilliSecs;
        }
        else if ( aMedia.IsSupported( KMPXMediaGeneralUri ) )
            {
            TParsePtrC filePath( aMedia.ValueText( KMPXMediaGeneralUri ) );
            iTitle = (filePath.Name()).AllocL();
            }
		delete iArtist;
		iArtist = NULL;
		if ( aMedia.IsSupported( KMPXMediaMusicArtist ) )
		    {
		    iArtist = ( aMedia.ValueText( KMPXMediaMusicArtist ) ).AllocL();
		    }

		iObserver->TrackInfoChanged(iTitle ? *iTitle : KNullDesC(), iArtist ? *iArtist : KNullDesC());

		if (!iSkipping)
            {
            if (iExtractingAlbumArt)
                {
                if (iAlbumArtUtil){iAlbumArtUtil->CancelRequest();}
                iExtractingAlbumArt=EFalse;
                }
            
            if ( aMedia.IsSupported( KMPXMediaMusicAlbumArtFileName ) )
                {
                delete iMedia;
                iMedia=NULL;
                iMedia = CMPXMedia::NewL( aMedia );
                TRAPD(err,iAlbumArtUtil->ExtractAlbumArtL(
                        *iMedia,
                        *this,
                        KAlbumArtSize,
                        EFalse));
                
                if (err != KErrNone)
                    {
                    iObserver->AlbumArtChanged(NULL);
                    }
                }
            else
                {
                iObserver->AlbumArtChanged(NULL);
                }

            }
		else
		    {
		    iObserver->AlbumArtChanged(NULL);
		    }
        }
    }