/****************************************************************
 *  RetroShare is distributed under the following license:
 *
 *  Copyright (C) 2007, RetroShare Team
 *
 *  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.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 *  Boston, MA  02110-1301, USA.
 ****************************************************************/

#ifndef _MESSAGECOMPOSER_H
#define _MESSAGECOMPOSER_H

#include <QMainWindow>
#include <retroshare/rstypes.h>
#include <retroshare/rsmsgs.h>
#include <retroshare/rspeers.h>
#include "ui_MessageComposer.h"

#include "gui/msgs/MessageInterface.h"

class QAction;
class RsIdentityDetails;
class QComboBox;
class QFontComboBox;
class QTextEdit;
class QTextCharFormat;
class RSTreeWidgetItemCompareRole;
class RsGxsChannelGroup;
class RsGxsForumGroup;

class MessageComposer : public QMainWindow 
{
    Q_OBJECT

public:
    enum enumType { TO, CC, BCC };
    enum enumMessageType { NORMAL, REPLY, FORWARD };
    enum destinationType { PEER_TYPE_SSL, PEER_TYPE_GROUP, PEER_TYPE_GXS };

public:
    /** Default Constructor */

    MessageComposer(QWidget *parent = 0, Qt::WindowFlags flags = 0);
    ~MessageComposer();

    static void msgFriend(const RsPeerId &id);
    // send msg to all locations
    static void msgFriend(const RsPgpId &id);
    static void msgGxsIdentity(const RsGxsId& gxs_id) ;
    static void msgGroup(const std::string& group_id) ;

    static QString recommendMessage();
    static void recommendFriend(const std::set <RsPeerId> &sslIds, const RsPeerId &to = RsPeerId(), const QString &msg = "", bool autoSend = false);
    static void sendConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &sslName);
    static void sendInvite(const RsGxsId &to = RsGxsId(), const QString &msg = "", bool autoSend = true);
#ifdef UNUSED_CODE
    static void sendChannelPublishKey(RsGxsChannelGroup &group);
    static void sendForumPublishKey(RsGxsForumGroup &group);
#endif

    static MessageComposer *newMsg(const std::string &msgId = "");
    static MessageComposer *replyMsg(const std::string &msgId, bool all);
    static MessageComposer *forwardMsg(const std::string &msgId);

    /* worker fns */
    void  setFileList(const std::list<DirDetails>&);
    void  setFileList(const std::list<FileInfo>&);
    void  addFile(const FileInfo &fileInfo);
    void  setTitleText(const QString &title, enumMessageType type = NORMAL);
    void  setQuotedMsg(const QString &msg, const QString &header);
    void  setMsgText(const QString &msg, bool asHtml = false);
    void  addRecipient(enumType type, const RsPeerId &id);
    void  addRecipient(enumType type, const RsGxsId &gxs_id) ;
    void  addRecipient(enumType type, const std::string& group_id) ;

public slots:
    /* actions to take.... */
    void  sendMessage();
    void  cancelMessage();
    void  addImage();
    
    void changeFormatType(int styleIndex );

protected:
    void closeEvent (QCloseEvent * event);
    bool eventFilter(QObject *obj, QEvent *ev);

private slots:
    /* toggle Contacts DockWidget */
    void contextMenuFileList(QPoint);
    void pasteRecommended();
    void on_contactsdockWidget_visibilityChanged(bool visible);
    void toggleContacts();
    void buildCompleter();
    void updatecontactsviewicons();
    void updateCells(int,int) ;

	void filterComboBoxChanged(int);

    void fileNew();
    void fileOpen();
    bool fileSave();
    bool fileSaveAs();
    void filePrint();
    void saveasDraft();

    //void filePrintPreview();
    void filePrintPdf();

    void textBold();
    void textUnderline();
    void textItalic();
    void textFamily(const QString &f);
    void textSize(const QString &p);
    void textStyle(QAction *a);
    void textColor();
    void textbackgroundColor();
    void textAlign(QAction *a);
    void smileyWidget();
    void addSmileys();

    void currentCharFormatChanged(const QTextCharFormat &format);
    void cursorPositionChanged();

    void clipboardDataChanged();

    void fileHashingStarted();
    void fileHashingFinished(QList<HashedFile> hashedFiles);

    void attachFile();

    void fontSizeIncrease();
    void fontSizeDecrease();
    void blockQuote();
    void toggleCode();
    void addPostSplitter();

    void titleChanged();

    // Add to To/Cc/Bcc address fields
    void addTo();
    void addCc();
    void addBcc();
    void addRecommend();
    void editingRecipientFinished();
    void contactDetails();

    void peerStatusChanged(const QString& peer_id, int status);
    void friendSelectionChanged();

    void tagAboutToShow();
    void tagSet(int tagId, bool set);
    void tagRemoveAll();
    
    void on_closeInfoFrameButton_clicked();
    
    static QString inviteMessage();

private:
    static QString buildReplyHeader(const MessageInfo &msgInfo);

    void processSettings(bool bLoad);

    static QString getRecipientEmailAddress(const RsGxsId& id,const RsIdentityDetails& detail) ;
    static QString getRecipientEmailAddress(const RsPeerId& id,const RsPeerDetails& detail) ;

    void addContact(enumType type);
    void setTextColor(const QColor& col) ;
    void setupFileActions();
    void setupEditActions();
    void setupViewActions();
    void setupInsertActions();
    void setupFormatActions();
    void setupContactActions();

    bool load(const QString &f);
    bool maybeSave();
    //bool image_extension( QString nametomake );
    void setCurrentFileName(const QString &fileName);

    void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
    void fontChanged(const QFont &f);
    void colorChanged(const QColor &c);
    void colorChanged2(const QColor &c);
    void alignmentChanged(Qt::Alignment a);

    bool sendMessage_internal(bool bDraftbox);

    void calculateTitle();
    void addEmptyRecipient();

    bool getRecipientFromRow(int row, enumType &type, destinationType& dest_type, std::string &id);
    void setRecipientToRow(int row, enumType type, destinationType dest_type,const std::string &id);

    void clearTagLabels();
    void showTagLabels();

    QAction *actionSave,
    *actionAlignLeft,
    *actionAlignCenter,
    *actionAlignRight,
    *actionAlignJustify,
    *actionUndo,
    *actionRedo,
    *actionCut,
    *actionCopy,
    *actionPaste,   
    *actionDisc,
    *actionCircle,
    *actionSquare,
    *actionDecimal,
    *actionLowerAlpha,
    *actionUpperAlpha,
    *actionLowerRoman,
    *actionUpperRoman;

    QAction *contactSidebarAction;
    QAction *mActionAddTo;
    QAction *mActionAddCC;
    QAction *mActionAddBCC;
    QAction *mActionAddRecommend;
    QAction *mActionContactDetails;

    QTreeView *channelstreeView;

    QString fileName;
    QString nametomake;

    QColor codeBackground;
    QTextCharFormat defaultCharFormat;

    QHash<QString, QString> autoLinkDictionary;
    QHash<QString, QString> autoLinkTitleDictionary;
    QHash<QString, int> autoLinkTargetDictionary;

    std::string m_msgParentId; // parent message id
    std::string m_sDraftMsgId; // existing message id
    enumMessageType m_msgType;
    std::list<uint32_t> m_tagIds;
    QList<QLabel*> tagLabels;

    // needed to send system flags with reply
    unsigned msgFlags;

    RSTreeWidgetItemCompareRole *m_compareRole;
    QCompleter *m_completer;

    /** Qt Designer generated object */
    Ui::MessageComposer ui;

    std::list<FileInfo> _recList ;
};

#endif
