/***************************************************************************
                          msnobject.h  -  description
                             -------------------
    begin                : Tue Jul 15 2003
    copyright            : (C) 2003 by Mike K. Bennett
    email                : mike@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef MSNOBJECT_H
#define MSNOBJECT_H

#include <QString>



/**
 * @brief Data class for the msnobject tag.
 *
 * The MSN Object type is used by MSN Messenger to share meta-data about
 * contact pictures, emoticons and backgrounds.
 *
 * @author Mike K. Bennett
 * @ingroup Contact
 */
class MsnObject
{
  public:
    // Updated list from:  http://zoronax.spaces.live.com/blog/cns!4A0B813054895814!180.entry?_c11_blogpart_blogpart=blogview&_c=blogpart#permalink
    // It appears the official client uses a central "storage" system.
    // Some ID's are never sent as invitation
    enum MsnObjectType
    {
      INVALID           = 0, // KMess-specific
      // 1 is unused (avatar)
      EMOTICON          = 2,
      DISPLAYPIC        = 3,
      // 4 is not sent (shared file)
      BACKGROUND        = 5,
      // 6 is not sent (history)
      DELUXE_DISPLAYPIC = 7,
      WINK              = 8,
      // 9 is not sent (map file)
      VOICECLIP         = 11,
      // 12 is not sent (add-in data)
      ROAMING_OBJECT    = 13
      // 14 not seen yet (location data)
    };

  public: // Public methods
    // Legacy constructor
    MsnObject();

    /**
     * Create an MsnObject based on a string provided by the server.
     * @param object The MsnObject as a string, as provided by the server.
     */
    MsnObject(const QString &object);

    /**
     * Copy constructor.
     */
    MsnObject(const MsnObject &other);

    /**
     * Create an MsnObject based on the provided attributes.
     * Hashes will be calculated automatically.
     * @param creator Normally the user's MSN email address.
     * @param location A filename.
     * @param friendly A friendly name for the object. Note, this should
     *                 NOT be base64-encoded: we will do that for you.
     * @param type The type of object.
     * @param fileData The file this MsnObject represents. The data is
     *                 used to calculate the data hash and file size.
     * @param stamp    The base64-encoded certificate (useful for winks)
     */
    MsnObject(const QString &creator, const QString &location,
              const QString &friendly, MsnObjectType type,
              const QByteArray &fileData, const QByteArray &stamp = QByteArray() );

    // The destructor
    ~MsnObject();
    // Get the object's creator
    const QString&   getCreator() const;
    // Get the object's location
    const QString&   getLocation() const;
    // Get the object's friendly name
    const QString&   getFriendly() const;
    // Get the object's size
    int              getSize() const;
    // Get the object's type
    MsnObjectType    getType() const;
    // Get the SHA1C hash
    const QString    getContentHash() const;
    // Get the SHA1D hash
    const QString    getDataHash() const;


    /**
     * Get if this is a valid MSNObject.
     */
    bool isValid() const;


    /**
     * Verify the hash of the MSNObject.
     * Assuming we have all the fields, in the right order,
     * we calculate the SHA1 hash of the MSNObject and verify that
     * it matches what we have stored.
     */
    bool verifyObjectHash() const;


    /**
     * Verify whether the contents of an external file matches with the MsnObject data hash.
     */
    bool verifyFile( const QString &fileName ) const;


    /**
     * Generates the string representation of the MsnObject.
     * This is what we use when we actually want to send the object over
     * the wire to a remote client.
     */
    const QString objectString() const;

    /**
     * Compares this MSN object to the string version passed in.
     * This takes a shortcut by comparing the SHA1C hash, since it hashes
     * the data hash and the full MSN object. How convenient.
     * @param newObj  The MSN object returned from the server.
     */
    bool hasChanged(const QString &newObj) const;

    /// Parse an attribute from the object string
    static QString  getAttribute( const QString& attribute, const QString& object );


  private: // private methods
    /// Generate the base64-encoded sha1 hash for the file data
    const QByteArray generateDataHash( const QByteArray &fileData ) const;
    /// Generate the base64-encoded sha1 hash for this object
    const QByteArray generateObjectHash() const;
    /// Use an MSN object descriptor from the server to load data
    void             loadObject( const QString& object );


  private: // Private attributes
    // The creator of the object
    QString          creator_;
    // The object's friendly name, base64 encoded
    QString          friendly_;
    // The location of the object
    QString          location_;
    // The original msn object string.
    QString          original_;
    // The size of the object
    int              size_;
    // The type of the object
    MsnObjectType    type_;
    // The base64-encoded SHA1 hash of the MsnObject's data
    QByteArray       sha1d_;
    // The base64-encoded SHA1 hash of the MsnObject string itself
    QByteArray       sha1c_;
    // The base-64 encoded certificate useful for winks
    QByteArray       stamp_;

};

#endif
