/**
 * 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 "resourcedataprovider.h"

#include <QApplication>
#include <QDebug>
#include <QFile>

#include "declarativepurchaselistmodel.h"
#include "drmfile.h"
#include "purchasableitembase.h"

#define UNLOCKEDSTR ".unlocked"

//local function declaration
static void dump2File(const char *buff, int len, const QString &fname);

// this is product list data dictionary
// 'data' field is initialized with 'NULL' and then will be assigned real value
// when DeclarativePurchaseListModel is constructed
ResourceDataProvider::ProductDefinition ResourceDataProvider::productList[] = {

    /***********************
    "enhanced bike" recource definition below
    see the project profile : items2sell/enhanced_bike/resources
    ************************/
    {"frontWheel",
        "qml/mototrialracer/gfx/wheel.png" ,
            "drm/data/resourceid_673272/resources/wheel.png",
                "673272", 10, NULL},
    {"rearWheel",
        "qml/mototrialracer/gfx/rearWheel.png",
            "drm/data/resourceid_673272/resources/wheel.png",
                "673272",
                    10, NULL},
    {"rearFork",
        "qml/mototrialracer/gfx/rearFork.png" ,
            "drm/data/resourceid_673272/resources/rearFork.png",
                "673272",
                    0, NULL},
    {"frontFork",
        "qml/mototrialracer/gfx/susp_lower_long.png" ,
            NULL,                                   // hide the original part in "673272" item
                "673272",
                    0, NULL},
    {"bikeBody",
        "qml/mototrialracer/gfx/bikeBody.png" ,
            "drm/data/resourceid_673272/resources/bikeBody.png",
                "673272",
                    0, NULL},

    /***********************
    "helmet" resource definition below
    see the project profile : items2sell/bell_helmet/resources
    ************************/
    {"helmet",
        "qml/mototrialracer/gfx/head.png" ,
            "drm/data/resourceid_673237/resources/head.png",
                "673237",
                    0, NULL},


    /***********************
    resource that cannot be unlocked but only requested by QML side
    ************************/
    {"human",
        "qml/mototrialracer/gfx/human.png" ,
            NULL,
                NULL,
                    0, NULL}, // productID == NULL means the item is not for sale
    {"hand",
        "qml/mototrialracer/gfx/hand.png" ,
            NULL,
                NULL,
                    0, NULL},
    {"arm",
        "qml/mototrialracer/gfx/arm.png" ,
            NULL,
                NULL,
                    0, NULL},
    {"audio_motor_sound",
        ":/sounds/motor2.wav" ,
            "drm/data/resourceid_673272/resources/atv.wav",
                "673272",
                    0, NULL}
    // NOTE: insert new items here in format shown below:
    //{key, lockedURL, unlockedURL, productID, data}
};

const int ResourceDataProvider::productListSize =
                sizeof(ResourceDataProvider::productList) /
                                        sizeof(ResourceDataProvider::productList[0]);

ResourceDataProvider::ResourceDataProvider(const DeclarativePurchaseListModel &model):
    QDeclarativeImageProvider(QDeclarativeImageProvider::Image),
    m_model(&model)
{
    // fill data fields
    for (int i = 0; i < productListSize; i++){
        productList[i].data = m_model->find(productList[i].productID);
    }
}

QImage ResourceDataProvider::requestImage(const QString &url,
                                          QSize *size,
                                          const QSize& /*requestedSize*/)
{
    //NOTE: see workaround for http://bugreports.qt.nokia.com/browse/QTBUG-14900 in 'main.qml'
    int ignorelength = url.indexOf("_ignoringpart");
    QString id((ignorelength > 0) ? url.left(ignorelength) : url);

    int index = itemToIndex(id);
    if (index == KErrNotFound)
        return QImage();

    ProductDefinition def = productList[index];
    QString iconPath = QApplication::applicationDirPath() + "/";

    if (def.unlockedURL != NULL && def.data != NULL && def.data->isActivated()){
        iconPath.append(def.unlockedURL);
    }else{
        iconPath.append(def.lockedURL);
    }

    QImage image;
    decryptDRMcontentToImage(iconPath, image);

    if (size)
        *size = QSize(image.width(), image.height());

    return image;
}

QString ResourceDataProvider::requestResourceUrl(const QString &key)
{
    int index = itemToIndex(key);
    if (index == KErrNotFound)
        return QString();

    ProductDefinition def = productList[index];
    if (def.data->isActivated()){
        QString pathDRM = QApplication::applicationDirPath() + "/" + def.unlockedURL;
        QString destination = QApplication::applicationDirPath() + "/" +
                                                        def.unlockedURL + UNLOCKEDSTR;
        decryptDRMcontentToFile(pathDRM, destination);

        return QString(destination);
    }else{
        return QString(def.lockedURL);
    }
}

void ResourceDataProvider::decryptDRMcontentToImage(QString &pathDRM, QImage &destIcon)
{
    DRMFile file;
    if (!file.open(pathDRM)){
        //DRM protected file is unlocked
        uchar* buffer;
        int len = file.read(buffer);
        if (len>0){
            destIcon.loadFromData(buffer, len);
        }
    }
    file.close();
}

void ResourceDataProvider::decryptDRMcontentToFile(QString &pathDRM, const QString &destination)
{
    QFile fileRes(destination);
    if (fileRes.exists())
        return;

    DRMFile file;
    if (!file.open(pathDRM)){
        //DRM protected file is unlocked
        uchar* buffer;
        int len = file.read(buffer);
        if (len>0){
            dump2File((const char*)buffer, len, destination);
        }
    }
    file.close();
}

void dump2File(const char *buff, int len, const QString &fname)
{
    QFile file(fname);
    if (file.open(QIODevice::WriteOnly)){
        QDataStream out(&file);
        out.writeRawData(buff, len);
        file.close();
    }else{
        qDebug() << "Cannot open file for writing: ";

    }
}

bool ResourceDataProvider::isProductVisible(const QString &id)
{
    int index = itemToIndex(id);
    if (!(index != KErrNotFound && productList[index].data->isActivated()))
        return true;

    return (productList[index].unlockedURL != NULL);
}

int ResourceDataProvider::productZorder(const QString &id)
{
    int index = itemToIndex(id);
    if (!(index != KErrNotFound && productList[index].data->isActivated()))
        return 0; // default value

    return (productList[index].zOrder);
}

int ResourceDataProvider::itemToIndex(const QString &id)
{
    int index = KErrNotFound;
    for (int i = 0; i < productListSize; i++){
        if (id.compare(QLatin1String(productList[i].key)) == 0){
            index = i;
            break;
        }
    }
    return index;
}
