/***************************************************************************
                          chatmessageview.h -  description
                             -------------------
    begin                : Sat Nov 8 2005
    copyright            : (C) 2005 by Diederik van der Boor
    email                : "vdboor" --at-- "codingdomain.com"
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 CHATMESSAGEVIEW_H
#define CHATMESSAGEVIEW_H

#include "account.h"

#include <KHTMLPart>
#include <KParts/BrowserExtension>
#include <KAction>

class ChatMessage;
class ChatMessageStyle;
class CurrentAccount;
class QStringList;



/**
 * This class is used to display chat messages.
 * A KHTMLPart is used for this because unlike QTextBrowser, KHTML has support for CSS.
 *
 * @author Diederik van der Boor
 * @ingroup Chat
 */
class ChatMessageView : public KHTMLPart
{
  Q_OBJECT

  public:  // public methods

    // The constructor
                         ChatMessageView( QWidget *parentWidget = 0, QObject *parent = 0 );
    // The destructor
    virtual             ~ChatMessageView();
    // Add new XML content to the view
    void                 addXml( QString xmlString );
    // Return the chat history in a specified format
    QString              getHistory( Account::ChatExportFormat format, bool append, QString &appendPoint );
    // Return a pointer to the message style parser
    ChatMessageStyle    *getStyle() const;
    // Return a tag to use to compare styles and their options
    QString              getStyleTag() const;
    // Whether or not there are any messages
    bool                 hasHistory() const;
    // Whether or not the message area is empty
    bool                 isEmpty() const;
    // Delete an emoticon from the chat.
    void                 removeCustomEmoticon( const QString &shorctut );
    // Update a custom emoticon placeholder with the emoticon
    void                 updateCustomEmoticon( const QString &code, const QString &replacement, const QString &handle );
    // Replace the entire contents with a new chat in XML
    void                 setXml( const QString &newXmlBody );
    // Retrieve the KMenu for the context menu.
    KMenu*               popupMenu();

  public slots:
    // Finds the links to add a custom emoticon, and remove them because we've already added that emoticon
    void                 addedEmoticon( QString shortcut );
    // Delete the viewed contents, and optionally the saved message history, too
    void                 clearView( bool clearHistory = false );
    /**
     * Scroll forward or backward within the chat browser.
     *
     * The parameter controls the amount and direction of the scrolling operation.
     * A forward argument set to true moves the chat viewport down, a false one goes back in
     * the chat history. If argument fast is true, the movement goes twice as far than with
     * the same argument set to false.
     * @param forward   Whether to scroll forward or backward in the chat history
     * @param fast      Whether to scroll at normal speed or faster
     */
    void                 scrollChat( bool forward, bool fast );
    // Force scrolling to the bottom of the chat browser
    void                 scrollChatToBottom();
    // Scroll to the bottom of the chat browser if needed
    void                 scrollChatToBottomGently();
    // Add the given message to the message browser.
    void                 showMessage( const ChatMessage &message );
    // Replace an application's accept/reject/cancel links with another text
    void                 updateApplicationMessage( const QString &messageId, const QString &newMessage );
    // Update the chat style
    void                 updateChatStyle();

  private:  // Private methods
    // Add the given html to the chat browser and scroll to the end
    void                 addHtmlMessage( const QString &text );
    // Generate a new HTML chat log
    QString              rebuildHistory( bool fullHistory );
    // Replace the last message with a new contents.
    void                 replaceLastMessage( const QString &text );
    // Replace the entire contents with new HTML code
    void                 setHtml( const QString &newHtmlBody );
    // Create the context menu actions. Should only get called once.
    void                 createPopupMenuActions();

  private slots: // Private slots
    void                 slotCopyChatText();
    void                 slotFindChatText();
    void                 slotSelectAllChatText();

  private:  // private properties
    // Message which was last deleted by a Clear Chat action
    ChatMessage         *chatClearingMark_;
    // The chat contents; every user, contact or kmess message is contained here
    QList<ChatMessage*>  chatMessages_;
    // The XSL transformation handler
    ChatMessageStyle    *chatStyle_;
    // A pointer to the instance of the current account
    CurrentAccount      *currentAccount_;
    // Whether or not the chat message area is empty
    bool                 isEmpty_;
    // The last messages sent by the same contact. This is used to combine them
    QList<ChatMessage*>  lastContactMessages_;
    // The last message id, for replaceLastMessage()
    int                  lastMessageId_;
    // The list of custom emoticons which haven't been received yet
    QStringList          pendingEmoticonTags_;
    // The KActions associated with the context menu
    KAction*             copyAction_;
    KAction*             selectAllAction_;
    KAction*             findAction_;

  signals:
    // Signal that there's an application command
    void                 appCommand(QString cookie, QString contact, QString method);
    // Signal a click on an URL
    void                 openUrlRequest( const KUrl &url );
};

#endif

