// --------------------------------------------------------------------------
// CUPnPPlayListFiller::DoFillObjectL
// Fills a ingle object to a playlist
// --------------------------------------------------------------------------
//
void CUPnPPlayListFiller::DoFillObjectL(  CMPXMediaArray& aPlaylist,
    const CUpnpObject& aObject, TInt /*aIndex*/ )
    {
    // Create new media object for track
    CMPXMedia* media = CMPXMedia::NewL();
    CleanupStack::PushL( media );
    // Set type
    media->SetTObjectValueL<TMPXGeneralType>( 
        KMPXMediaGeneralType, EMPXItem );
    // Set gategory
    media->SetTObjectValueL<TMPXGeneralCategory>( 
        KMPXMediaGeneralCategory, EMPXSong );
    // URI
    if( UPnPItemUtility::BelongsToClass( aObject , KClassAudio ) )
        {
        ConvertToURI( *iDeviceUid, aObject, iTempBuf );
        }
    else // item is non audio set uri to KUPnPPrefix
    	{
    	iTempBuf.Copy( KUPnPPrefix );
    	}
    
    media->SetTextValueL( 
        KMPXMediaGeneralUri, iTempBuf );
    // Title
    HBufC16* buf = 
        EscapeUtils::ConvertToUnicodeFromUtf8L( aObject.Title() );
    CleanupStack::PushL( buf );
    media->SetTextValueL( 
        KMPXMediaGeneralTitle, *buf );
    CleanupStack::PopAndDestroy( buf );
    // Add track to the object list
    aPlaylist.AppendL( media );
    CleanupStack::Pop( media );
    }
// ----------------------------------------------------------------------------
// Navigates to the given path
// ----------------------------------------------------------------------------
//
void CGlxMediaListsTestCollectionPlugin::OpenL(const CMPXCollectionPath& aPath,
                   const TArray<TMPXAttribute>& /*aAttrs*/,
                   CMPXFilter* /*aFilter*/)
    {
    RArray<TInt> supportedIds;
    CleanupClosePushL(supportedIds);
    supportedIds.AppendL(KMPXMediaIdContainer);
    supportedIds.AppendL(KMPXMediaIdGeneral);
    iOpenEntries = CMPXMedia::NewL(supportedIds.Array());

    CMPXMediaArray* array = CMPXMediaArray::NewL();
    CleanupStack::PushL(array);

 	if ( aPath.Levels() == 1 ) 
 		{
 		TInt count = _iItemDBHackAlbums.Count();
 		for ( TInt i = 0; i < count; i++ )
 			{
 			AppendL(_iItemDBHackAlbums[i]->iId, *_iItemDBHackAlbums[i]->iTitle, *array, EMPXGroup, EMPXAlbum);
 			}
 		}
 	else if ( aPath.Levels() == 2 ) 
 		{
 		TInt count = _iItemDBHackContent.Count();
 		for ( TInt i = 0; i < count; i++ )
 			{
 			AppendL(_iItemDBHackContent[i]->iId, *_iItemDBHackContent[i]->iTitle, *array, EMPXItem, EMPXImage);
 			}

		StartEvents();
 		}
 	else 
 		{
 		__DEBUG_ONLY(Panic(EGlxPanicDebugUnexpectedError));
 		}
    
    iOpenEntries->SetCObjectValueL(KMPXMediaArrayContents, array);
    iOpenEntries->SetTObjectValueL(KMPXMediaArrayCount, array->Count());

    CleanupStack::PopAndDestroy(array);    

	//iObs->HandleOpen(*iOpenEntries, KErrNone);
	
    AsyncNotifyL(iOpenEntries, KErrNone, CGlxAsyncNotifier::EOpen);
        
    CleanupStack::PopAndDestroy(&supportedIds);        
    }
void CGlxCollectionPluginAlbums::HandleCpiAttributeResponseL(CMPXMedia* aResponse, TArray<TMPXAttribute> aCpiAttributes, TArray<TGlxMediaId> aMediaIds)
    {
    TRACER("CGlxCollectionPluginAlbums::HandleCpiAttributeResponseL");
    const TInt mediaIdCount = aMediaIds.Count();
    
    switch (mediaIdCount)
        {
    case 0:
        User::Leave(KErrNotSupported);
        break;
    case 1:
        HandleCpiAttributeResponseL(aResponse, aCpiAttributes, aMediaIds[0]);
        break;
    default:
            {
            // We have an array of CMPXMedia items
            
            if (TGlxMediaId(KGlxCollectionRootId) == aMediaIds[0])
                {
                User::Leave(KErrNotSupported);
                }
                
            CMPXMediaArray* mediaArray = aResponse->ValueCObjectL<CMPXMediaArray>(KMPXMediaArrayContents);
            CleanupStack::PushL(mediaArray);

            const TInt arrayCount = mediaArray->Count();
            
            // Sanity check
            if (arrayCount != mediaIdCount)
                {
                User::Leave(KErrArgument);
                }
            
            for (TInt index = 0; index < arrayCount; index++)
                {
                HandleCpiAttributeResponseL((*mediaArray)[index], aCpiAttributes, aMediaIds[index]);
                }

            aResponse->SetCObjectValueL(KMPXMediaArrayContents, mediaArray);
            CleanupStack::PopAndDestroy(mediaArray);
            }
        break;
        }
    }
// ----------------------------------------------------------------------------------------------------------
// 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;
                    }
                }
            }
        }
    }
}
// ============================ LOCAL FUNCTIONS ==============================
// ----------------------------------------------------------------------------
// Add an item to the media array
// ----------------------------------------------------------------------------
//
LOCAL_C void AppendL(const TGlxMediaId& aId, const TDesC& aTitle,
        CMPXMediaArray& aArray, TMPXGeneralType aType,TMPXGeneralCategory aCat)
    {
    RArray<TInt> supportedIds;
    CleanupClosePushL(supportedIds);
    supportedIds.AppendL(KMPXMediaIdGeneral);
    CMPXMedia* entry=CMPXMedia::NewL(supportedIds.Array());
    CleanupStack::PushL(entry);
    entry->SetTObjectValueL(KMPXMediaGeneralId, aId);
    entry->SetTextValueL(KMPXMediaGeneralTitle, aTitle);
    entry->SetTObjectValueL(KMPXMediaGeneralType, aType);
    entry->SetTObjectValueL(KMPXMediaGeneralCategory, aCat);
    aArray.AppendL(entry);
    CleanupStack::Pop(entry);
    CleanupStack::PopAndDestroy(&supportedIds);
    }
// ----------------------------------------------------------------------------
// Append an item into the media array
// ----------------------------------------------------------------------------
//
void MPXDbUtil::AppendMediaL(
    CMPXMediaArray& aArray,
    const TDesC& aTitle,
    TMPXGeneralType aType,
    TMPXGeneralCategory aCat,
    TMPXPodcastType aPodcastType,
    TMPXPodcastCategory aPodcastCat,
    TMPXItemId aId,
    TInt aNonPermissibleActions)
    {
    MPX_FUNC("MPXDbUtil::AppendMediaL");

    RArray<TInt> supportedIds;
    CleanupClosePushL (supportedIds);
    supportedIds.AppendL (KMPXMediaIdGeneral);
    supportedIds.AppendL (KMPXMediaIdPodcast);
    CMPXMedia* entry = CMPXMedia::NewL(supportedIds.Array());
    CleanupStack::PushL (entry);
    entry->SetTextValueL (KMPXMediaGeneralTitle, aTitle);
    entry->SetTObjectValueL(KMPXMediaPodcastType, aPodcastType);
    entry->SetTObjectValueL(KMPXMediaPodcastCategoryGroup, aPodcastCat);
    entry->SetTObjectValueL(KMPXMediaGeneralId, aId);
    entry->SetTObjectValueL(KMPXMediaGeneralType, aType);
    entry->SetTObjectValueL(KMPXMediaGeneralCategory, aCat);

    // temp fix: Beryl BEGIN
    if ( aNonPermissibleActions != 0 )
        {
        // set non-permissible actions
        entry->SetTObjectValueL(KMPXMediaGeneralNonPermissibleActions,
            static_cast<TMPXGeneralNonPermissibleActions>(aNonPermissibleActions));
        }
    // temp fix: Beryl END
    aArray.AppendL (entry);
    CleanupStack::Pop (entry);
    CleanupStack::PopAndDestroy (&supportedIds);
    }
// ----------------------------------------------------------------------------
// Extended properties of the current file (async)
// ----------------------------------------------------------------------------
//
void CGlxMediaListsTestCollectionPlugin::MediaL(const CMPXCollectionPath& aPath,
		const TArray<TMPXAttribute>& aAttrs,
                        const TArray<TCapability>& /*aCaps*/,
                        CMPXAttributeSpecs* /*aSpecs*/)
    {
    __ASSERT_ALWAYS(!iMedia, Panic(EGlxPanicIllegalState));

    TInt error = KErrNone;
    CItem* item = NULL;
    TInt bitmapHandle = 0;

    RArray<TInt> supportedIds;
    CleanupClosePushL(supportedIds);
    iMedia = CMPXMedia::NewL(supportedIds.Array());
    CleanupStack::PopAndDestroy(&supportedIds);

    TArray<TInt> selection = aPath.Selection();
    TInt selectionCount = selection.Count();
    if (selectionCount > 1)
        {
        CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
        CleanupStack::PushL(mediaArray);

        for (TInt count = 0; count < selectionCount; ++count)
            {
            item = ItemL(aPath, selection[count]);

            if (item)
                {
                RArray<TInt> supportedIds;
                CleanupClosePushL(supportedIds);
                CMPXMedia* media = CMPXMedia::NewL(supportedIds.Array());
                CleanupStack::PopAndDestroy(&supportedIds);

                CleanupStack::PushL(media);

                (void)PopulateMediaWithItemL(media, item, aAttrs);

                mediaArray->AppendL(*media);

                CleanupStack::PopAndDestroy(media);
                }
            else
                {
                error = KErrNotFound;
                break;
                }
            }

        PopulateMediaWithArrayL(iMedia, mediaArray);

        CleanupStack::PopAndDestroy(mediaArray);
        }
    else
        {
	item = ItemL(aPath, aPath.Index());

        if (item)
            {
            bitmapHandle = PopulateMediaWithItemL(iMedia, item, aAttrs);
            }
        else
            {
            error = KErrNotFound;
            }
        }

    if ( (KErrNone == error) && bitmapHandle )
        {
        // Get thumbnail for the item
        TGlxThumbnailRequest request;
        request.iId = item->iId;
    	request.iSizeClass = TSize(60, 45);
    	request.iPriorityMode = TGlxThumbnailRequest::EPrioritizeSpeed;
    	request.iBitmapHandle = bitmapHandle;

       	iThumbnailCreator->FetchThumbnailL(request, *this);
        }
    else
        {
        /*****************************************************
        * Old synchronous code
        ******************************************************/
        // No thumbnail requested - send response now
        //iObs->HandleMedia(*iMedia, error);
        //delete iMedia;
        //iMedia = NULL;
        
        /*****************************************************
        * New Async Code. Instantiate callback mechanism
        ******************************************************/
        
    	AsyncNotifyL(iMedia, error, CGlxAsyncNotifier::EMedia);  
        }
    }
// ----------------------------------------------------------------------------------------------------------
// Add specify attribute to Media
// ----------------------------------------------------------------------------------------------------------
//
void CTestCollectionPlugin::AddMediaL(CMPXMediaArray& aMediaArray,
                                      const RArray<TInt> aIdArray,
                                      const TArray<TMPXAttribute>& aAttrs)
{
    TInt idCnt = aIdArray.Count();
    for(TInt i = 0; i < idCnt; i++)
    {
        CMPXMedia* media = CMPXMedia::NewL();
        CleanupStack::PushL( media );
        switch( aIdArray[i] )
        {
        case 11:
            AddAttrbuteL(*media, 11, _L("level11"), KNullDesC, aAttrs);
            break;
        case 12:
            AddAttrbuteL(*media, 12, _L("level12"), KNullDesC, aAttrs);
            break;
        case 13:
            AddAttrbuteL(*media, 13, _L("level13"), KNullDesC, aAttrs);
            break;
        case 211:
            AddAttrbuteL(*media, 211, _L("level211"), KNullDesC, aAttrs);
            break;
        case 212:
            AddAttrbuteL(*media, 212, _L("level212"), KNullDesC, aAttrs);
            break;
        case 213:
            AddAttrbuteL(*media, 213, _L("level213"), KNullDesC, aAttrs);
            break;
        case 221:
            AddAttrbuteL(*media, 221, _L("level221"), KNullDesC, aAttrs);
            break;
        case 231:
            AddAttrbuteL(*media, 231, _L("level231"), KNullDesC, aAttrs);
            break;
        case 232:
            AddAttrbuteL(*media, 232, _L("level232"), KNullDesC, aAttrs);
            break;
        case 3111:
            AddAttrbuteL(*media, 3111, _L("song3111"), _L("\\song3111.ts"), aAttrs);
            break;
        case 3121:
            AddAttrbuteL(*media, 3121, _L("song3121"), _L("\\song3121.ts"), aAttrs);
            break;
        case 3131:
            AddAttrbuteL(*media, 3131, _L("playlist3131"), _L("\\playlist3131.tp"), aAttrs);
            break;
        case 3311:
            AddAttrbuteL(*media, 3311, _L("song3311"), _L("\\song3311.ts"), aAttrs);
            break;
        case 3321:
            AddAttrbuteL(*media, 3321, _L("playlist3321"), _L("\\playlist3321.tp"), aAttrs);
            break;
        case 990:
            AddAttrbuteL(*media, 990, _L("level990"), KNullDesC, aAttrs);
            break;
        case 9901:
            AddAttrbuteL(*media, 9901, _L("song9901"), _L("\\song9901.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9901, aAttrs);
            break;
        case 9902:
            AddAttrbuteL(*media, 9902, _L("song9902"), _L("\\song9902.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9902, aAttrs);
            break;
        case 9903:
            AddAttrbuteL(*media, 9903, _L("song9903"), _L("\\song9903.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9903, aAttrs);
            break;
        case 9904:
            AddAttrbuteL(*media, 9904, _L("song9904"), _L("\\song9904.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9904, aAttrs);
            break;
        case 9905:
            AddAttrbuteL(*media, 9905, _L("song9905"), _L("\\song9905.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9905, aAttrs);
            break;
        case 9906:
            AddAttrbuteL(*media, 9906, _L("song9906"), _L("\\song9906.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9906, aAttrs);
            break;
        case 9907:
            AddAttrbuteL(*media, 9907, _L("song9907"), _L("\\song9907.ts"), aAttrs);
            AddAttributePlaybackFwTestL(*media, 9907, aAttrs);
            break;
        };
        aMediaArray.AppendL( media );
        CleanupStack::Pop( media );
    }
}
void T_CGlxCache::T_CGlxCache_MediaUpdatedLL(  )
    {
    // Create helper class
    T_CacheTestHelpers cacheTestHelper(iCGlxCache);

    // New media
    CMPXMedia* newMedia3 = CMPXMedia::NewL();
    CleanupStack::PushL(newMedia3);

    newMedia3->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, TMPXItemId(KMediaId3));

    EUNIT_PRINT(_L("Add new media"));
    iCGlxCache->MediaUpdatedL(*newMedia3);

    EUNIT_PRINT(_L("Check new media added"));
    EUNIT_ASSERT_DESC(cacheTestHelper.ItemPool().Count() == 3, "Cache doesn't contain three items");

    TInt cachedNewMedia3Index = cacheTestHelper.ItemPool().FindInOrder(TGlxMediaId(KMediaId3), T_CacheTestHelpers::MediaItemOrderByKey);
    EUNIT_ASSERT_DESC(cachedNewMedia3Index != KErrNotFound, "New media not added to cache");

    CleanupStack::PopAndDestroy(newMedia3);

    // Multiple new media
    CMPXMedia* newMultipleMedia = CMPXMedia::NewL();
    CleanupStack::PushL(newMultipleMedia);

    CMPXMediaArray* newMediaArray = CMPXMediaArray::NewL();
    CleanupStack::PushL(newMediaArray);

    CMPXMedia* newMedia4 = CMPXMedia::NewL();
    CleanupStack::PushL(newMedia4);

    newMedia4->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, TMPXItemId(KMediaId4));

    newMediaArray->AppendL(newMedia4);
    CleanupStack::Pop(newMedia4);

    CMPXMedia* newMedia5 = CMPXMedia::NewL();
    CleanupStack::PushL(newMedia5);

    newMedia5->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, TMPXItemId(KMediaId5));

    newMediaArray->AppendL(newMedia5);
    CleanupStack::Pop(newMedia5);

    newMultipleMedia->SetCObjectValueL(KMPXMediaArrayContents, newMediaArray);
    newMultipleMedia->SetTObjectValueL(KMPXMediaArrayCount, newMediaArray->Count());

    EUNIT_PRINT(_L("Add multiple new media"));
    iCGlxCache->MediaUpdatedL(*newMultipleMedia);

    CleanupStack::PopAndDestroy(newMediaArray);
    CleanupStack::PopAndDestroy(newMultipleMedia);

    EUNIT_PRINT(_L("Check multiple new media added"));
    EUNIT_ASSERT_DESC(cacheTestHelper.ItemPool().Count() == 5, "Cache doesn't contain five items");

    TInt cachedNewMedia4Index = cacheTestHelper.ItemPool().FindInOrder(TGlxMediaId(KMediaId4), T_CacheTestHelpers::MediaItemOrderByKey);
    TInt cachedNewMedia5Index = cacheTestHelper.ItemPool().FindInOrder(TGlxMediaId(KMediaId5), T_CacheTestHelpers::MediaItemOrderByKey);
    EUNIT_ASSERT_DESC((cachedNewMedia4Index != KErrNotFound) && (cachedNewMedia5Index != KErrNotFound), "Multiple new media not added to cache");
    }