/**
 * 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.
 */

#ifndef PurchasableItemBase_H
#define PurchasableItemBase_H

#include <QObject>
#include <iapclient.h>
#include <QVariant>
#include <QImage>

class DeclarativePurchaseListModel;

/*!
  \class PurchasableItemBase abstract class
  \brief Represents billable product in memory, handles billing operations
*/
class PurchasableItemBase : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QImage image READ stateIcon)// NOTIFY imageChanged)

public:
    /*!
      Constructor
      accepts product list model, the product Ovi Store product id and unlocked icon URL
    */
    explicit PurchasableItemBase(DeclarativePurchaseListModel &model,
                                 const QString &productID,
                                 const QString &productUrl);

    /*!
      Destructor
    */
    virtual ~PurchasableItemBase();

signals:

public slots:

protected slots:
    /*!
      In-Application Purchase specific slots

      Slots matching the signals of the In-Application Purchase API, allowing
      the application to receive callbacks
    */
    void productDataReceived(int requestId, QString status, IAPClient::ProductDataHash productData);
    void purchaseCompleted(int requestId, QString status, QString purchaseTicket);
    void purchaseFlowFinished(int requestId);
    void restorationCompleted(int requestId, QString status, QString purchaseTicket);
    void restorationFlowFinished(int requestId);

public:
    /*!
      Checks whether product metadata has been downloaded from Ovi Store
    */
    bool isMetaDataKnown() const;

    /*!
      Checks whether product operation is on going
    */
    bool isBusy();

    /*!
      Checks whether product has been unlocked
    */
    bool isActivated() const;

    /*!
      Purchase request
    */
    void purchase();

    /*!
      Product restore request
    */
    void restore();

    //command codes for fetching data in QAbstractListModel::data() interface to QML side
    enum Roles {
        ProductIdRole = Qt::UserRole+1,
        DataReqResultRole,          // IAP client request return code
        TitleRole,                  // product title
        ShortDescriptionRole,       // product short description
        LongDescriptionRole,        // product long descrtiption
        PriceRole,                  // product price
        DrmProtectionRole,          // check if the product DRM protected

        IsMetadataKnown,            // check if the product data has been fetched from OVI Store
        IsBusy,                     // check if the product operation is on-going
        IsActivated                 // check if the product unlocked (bought)
    };

    /*!
      Returns the product current state icon. Can be 'locked', 'unlocked', 'busy'
    */
    virtual QImage& stateIcon() const;


    /*!
      Returns product data via QAbstractListModel::data() 'role' interface
    */
    virtual QVariant metadata(int role) const;

    /*!
      Sets product data via QAbstractListModel::data() 'role' interface
    */
    bool setMetadata(const QVariant &value, int role);

    /*!
      * checks whether the product is included to a given 'list' parameter
      */
    bool isIncluded(IAPClient::ProductDataList &list);

protected:
    /*!
      Calls IAP client to fetch metadata
    */
    void fetchMetadata();

    /*!
      Sets product state to 'busy'
    */
    bool setBusy();

    /*!
      Sets product state to 'unlocked'
    */
    virtual void setUnlocked(QString *purchaseTicket) = 0;

    /*!
      Checks whether the product has been unlocked
    */
    virtual bool isPurchased() = 0;

    /*!
    * these methods below related to purchase ticket
    * are only for IAP in test mode
    * normally we don't need to operate or keep tickets
    * because purchase verification is done :
    * 1) transparently by system for DRM protected items
    * 2) and by third party server for non-protected items via ticket verification API
    *
    * Tickets are transient data that can be requested any time from OVI Store for a certain
    * product id.
    *
    * if it is decided that keeping tickets in the application private directory
    * does not bring vulnerability issue this functionality may remain
    **/
    void saveTicket(QString *purchaseTicket);
    bool readTicket();

private:
    // utility functions
    QString getTicketDir();
    QString getTicketUri();

protected:
    //data
    IAPClient::ProductData          m_productMetadata;
    DeclarativePurchaseListModel    *m_model;       //product list model, does not own
    int                             m_requestId;    //current request id to IAP client
    bool                            m_isBusy;       //product busy flag
    QString                         m_productUrl;   //product unlocked resource URL
    bool                            m_isKnown;      //product data obtained from Ovi Store flag

    QImage                          *m_unlocked_icon; //product unlocked icon URL
    QImage                          *m_buy_icon;
    QImage                          *m_notready_icon;
};

#endif // PurchasableItemBase_H
