/**
 * Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 *
 * For the applicable distribution terms see the license.txt -file, included in
 * the distribution.
 */

#include "drmfile_p.h"

#include "drmfile.h"
#include <caf/caferr.h>
#include <caf/embeddedobject.h>
#include <caf/streamableptrarray.h>
#include <caf/data.h>

#include <e32base.h>
#include <f32file.h>

#include "QDebug"

DRMFilePrivate::DRMFilePrivate() :
        CAF_file(NULL)
{

}

DRMFilePrivate::~DRMFilePrivate()
{
    close();
}

int DRMFilePrivate::open(const QString & fileName)
{
    QString symbianFileName;
    symbianFileName = fileName;
    QChar find('/');
    QChar replace('\\');
    symbianFileName.replace(find,replace,Qt::CaseInsensitive);
    TPtrC16 fileName_TextPtr(reinterpret_cast<const TUint16*>(symbianFileName.utf16()));

    TRAPD(errcode, openL(fileName_TextPtr))
    if (errcode == KErrNone)
        intentExecuted = EFalse;

    return errcode;
}

int DRMFilePrivate::read(uchar*& data, int length, int index)
{
    int result = KErrNone;
    data = NULL;

    while (true){
        if (!(index >= 0 && index < CAF_data.Count())){
            result = KErrBadHandle;
            break;
        }

        CData* dataItem = CAF_data[index];
        RBuf8 buffer;
        if (!length)
            TRAP(result, dataItem->DataSizeL(length));

        if (result != KErrNone)
            break;

        length++; //to be able use PtrZ() call

        TRAP (result, buffer.CreateL(length));
        if (result != KErrNone)
            break;

        if (!intentExecuted)
            result = dataItem->ExecuteIntent(ContentAccess::EExecute);

        if (result != KErrNone)
            break;

        intentExecuted = ETrue;
        result = dataItem->Read(buffer);
        if (result != KErrNone)
            break;

        result = length;
        uchar* ptr = const_cast<uchar*>(buffer.PtrZ()); //give up ownership from RBuf8
        data = ptr;
        break;
    }

    if (result < KErrNone)
        RDebug::Print(_L("DRMFilePrivate::read ContentAccess::CData::Read error %d"), result);

    return result;
}

void DRMFilePrivate::close()
{
    CAF_data.ResetAndDestroy();

    if (CAF_file!=NULL){
        delete CAF_file;
        CAF_file = NULL;
    }    
}

void DRMFilePrivate::openL(const TDesC& fileName)
{
    if (CAF_file)
        return;
    
    CAF_file = CContent::NewL(fileName);

    RStreamablePtrArray <CEmbeddedObject> myArray;
    CleanupClosePushL(myArray);

    // Get an array of the embedded objects within the current container in the file
    CAF_file->GetEmbeddedObjectsL(myArray);
    for (int i = 0; i < myArray.Count(); i++)
    {
        CAF_data.AppendL(CAF_file->OpenContentL(ContentAccess::EExecute, myArray[i]->UniqueId()));
    }
    CleanupStack::PopAndDestroy(&myArray);
}

int DRMFilePrivate::size(int index)
{
    if (!(index >= 0 && index < CAF_data.Count())){
        return KErrGeneral;
    }

    TInt size;
    TRAPD(errcode, CAF_data[index]->DataSizeL(size));

    return ((errcode == KErrNone) ? size : errcode);
}

const ushort* DRMFilePrivate::getStringAttr(int index, int& len, TStringAttribute attr) const
{
    if (!(index >= 0 && index < CAF_data.Count())){
        return NULL;
    }

    RBuf uri;
    uri.CreateL(KMaxFileName + 1);
    CAF_data[index]->GetStringAttribute(attr, uri);
    len = uri.Length();
    return (uri.PtrZ());
}

