#ifndef RS_NOTIFY_GUI_INTERFACE_H
#define RS_NOTIFY_GUI_INTERFACE_H

/*
 * libretroshare/src/rsiface: rsnotify.h
 *
 * RetroShare C++ Interface.
 *
 * Copyright 2007-2008 by Robert Fernie.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License Version 2 as published by the Free Software Foundation.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 *
 * Please report all bugs and problems to "retroshare@lunamutt.com".
 *
 */


#include <map>
#include <list>
#include <iostream>
#include <string>
#include <stdint.h>

#include "rsturtle.h"
#include "rsgxsifacetypes.h"

class ChatId;
class ChatMessage;
class RsGxsChanges;

class RsNotify;
extern RsNotify   *rsNotify;

const uint32_t RS_SYS_ERROR 	= 0x0001;
const uint32_t RS_SYS_WARNING 	= 0x0002;
const uint32_t RS_SYS_INFO 	    = 0x0004;

const uint32_t RS_POPUP_MSG             = 0x0001;
const uint32_t RS_POPUP_CHAT            = 0x0002;
//const uint32_t RS_POPUP_CALL          = 0x0004;
const uint32_t RS_POPUP_CONNECT         = 0x0008;
const uint32_t RS_SYSTRAY_GROUP_MSG     = 0x0010;
const uint32_t RS_POPUP_DOWNLOAD        = 0x0020;
const uint32_t RS_POPUP_GROUPCHAT       = 0x0040;
const uint32_t RS_POPUP_CHATLOBBY       = 0x0080;
const uint32_t RS_POPUP_CONNECT_ATTEMPT = 0x0100;
const uint32_t RS_POPUP_ENCRYPTED_MSG   = 0x0200;

/* CHAT flags are here - so they are in the same place as 
 * other Notify flags... not used by libretroshare though
 */
const uint32_t RS_CHAT_OPEN          = 0x0001;
//const uint32_t free                = 0x0002;
const uint32_t RS_CHAT_FOCUS         = 0x0004;
const uint32_t RS_CHAT_TABBED_WINDOW = 0x0008;
const uint32_t RS_CHAT_BLINK         = 0x0010;

const uint32_t RS_FEED_TYPE_PEER     = 0x0010;
const uint32_t RS_FEED_TYPE_CHANNEL  = 0x0020;
const uint32_t RS_FEED_TYPE_FORUM    = 0x0040;
//const uint32_t RS_FEED_TYPE_BLOG     = 0x0080;
const uint32_t RS_FEED_TYPE_CHAT     = 0x0100;
const uint32_t RS_FEED_TYPE_MSG      = 0x0200;
const uint32_t RS_FEED_TYPE_FILES    = 0x0400;
const uint32_t RS_FEED_TYPE_SECURITY = 0x0800;
const uint32_t RS_FEED_TYPE_POSTED   = 0x1000;

const uint32_t RS_FEED_ITEM_PEER_CONNECT	    = RS_FEED_TYPE_PEER  | 0x0001;
const uint32_t RS_FEED_ITEM_PEER_DISCONNECT	 = RS_FEED_TYPE_PEER  | 0x0002;
const uint32_t RS_FEED_ITEM_PEER_HELLO		    = RS_FEED_TYPE_PEER  | 0x0003;
const uint32_t RS_FEED_ITEM_PEER_NEW		    = RS_FEED_TYPE_PEER  | 0x0004;

const uint32_t RS_FEED_ITEM_SEC_CONNECT_ATTEMPT	    = RS_FEED_TYPE_SECURITY  | 0x0001;
const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED	       = RS_FEED_TYPE_SECURITY  | 0x0002;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_IN	       = RS_FEED_TYPE_SECURITY  | 0x0003;
const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_OUT	       = RS_FEED_TYPE_SECURITY  | 0x0004;
const uint32_t RS_FEED_ITEM_SEC_WRONG_SIGNATURE     = RS_FEED_TYPE_SECURITY  | 0x0005;
const uint32_t RS_FEED_ITEM_SEC_BAD_CERTIFICATE     = RS_FEED_TYPE_SECURITY  | 0x0006;
const uint32_t RS_FEED_ITEM_SEC_INTERNAL_ERROR      = RS_FEED_TYPE_SECURITY  | 0x0007;
const uint32_t RS_FEED_ITEM_SEC_MISSING_CERTIFICATE = RS_FEED_TYPE_SECURITY  | 0x0008;
const uint32_t RS_FEED_ITEM_SEC_IP_BLACKLISTED      = RS_FEED_TYPE_SECURITY  | 0x0010;

const uint32_t RS_FEED_ITEM_CHANNEL_NEW      = RS_FEED_TYPE_CHANNEL  | 0x0001;
//const uint32_t RS_FEED_ITEM_CHANNEL_UPDATE   = RS_FEED_TYPE_CHANNEL  | 0x0002;
const uint32_t RS_FEED_ITEM_CHANNEL_MSG      = RS_FEED_TYPE_CHANNEL  | 0x0003;
const uint32_t RS_FEED_ITEM_CHANNEL_PUBLISHKEY = RS_FEED_TYPE_CHANNEL  | 0x0004;

const uint32_t RS_FEED_ITEM_FORUM_NEW        = RS_FEED_TYPE_FORUM | 0x0001;
//const uint32_t RS_FEED_ITEM_FORUM_UPDATE     = RS_FEED_TYPE_FORUM | 0x0002;
const uint32_t RS_FEED_ITEM_FORUM_MSG        = RS_FEED_TYPE_FORUM | 0x0003;
const uint32_t RS_FEED_ITEM_FORUM_PUBLISHKEY = RS_FEED_TYPE_FORUM | 0x0004;

//const uint32_t RS_FEED_ITEM_BLOG_NEW         = RS_FEED_TYPE_BLOG  | 0x0001;
//const uint32_t RS_FEED_ITEM_BLOG_UPDATE      = RS_FEED_TYPE_BLOG  | 0x0002;
//const uint32_t RS_FEED_ITEM_BLOG_MSG         = RS_FEED_TYPE_BLOG  | 0x0003;

const uint32_t RS_FEED_ITEM_POSTED_NEW       = RS_FEED_TYPE_POSTED  | 0x0001;
//const uint32_t RS_FEED_ITEM_POSTED_UPDATE    = RS_FEED_TYPE_POSTED  | 0x0002;
const uint32_t RS_FEED_ITEM_POSTED_MSG       = RS_FEED_TYPE_POSTED  | 0x0003;

const uint32_t RS_FEED_ITEM_CHAT_NEW		 = RS_FEED_TYPE_CHAT  | 0x0001;
const uint32_t RS_FEED_ITEM_MESSAGE		 = RS_FEED_TYPE_MSG   | 0x0001;
const uint32_t RS_FEED_ITEM_FILES_NEW		 = RS_FEED_TYPE_FILES | 0x0001;

const uint32_t RS_MESSAGE_CONNECT_ATTEMPT    = 0x0001;

const int NOTIFY_LIST_NEIGHBOURS             = 1;
const int NOTIFY_LIST_FRIENDS                = 2;
const int NOTIFY_LIST_SEARCHLIST             = 4;
const int NOTIFY_LIST_MESSAGELIST            = 5;
const int NOTIFY_LIST_CHANNELLIST            = 6;
const int NOTIFY_LIST_TRANSFERLIST           = 7;
const int NOTIFY_LIST_CONFIG                 = 8;
const int NOTIFY_LIST_DIRLIST_LOCAL          = 9;
const int NOTIFY_LIST_DIRLIST_FRIENDS        = 10;
const int NOTIFY_LIST_FORUMLIST_LOCKED       = 11; // use connect with Qt::QueuedConnection
const int NOTIFY_LIST_MESSAGE_TAGS           = 12;
const int NOTIFY_LIST_PUBLIC_CHAT            = 13;
const int NOTIFY_LIST_PRIVATE_INCOMING_CHAT  = 14;
const int NOTIFY_LIST_PRIVATE_OUTGOING_CHAT  = 15;
const int NOTIFY_LIST_GROUPLIST              = 16;
const int NOTIFY_LIST_CHANNELLIST_LOCKED     = 17; // use connect with Qt::QueuedConnection
const int NOTIFY_LIST_CHAT_LOBBY_INVITATION  = 18;
const int NOTIFY_LIST_CHAT_LOBBY_LIST        = 19;

const int NOTIFY_TYPE_SAME   = 0x01;
const int NOTIFY_TYPE_MOD    = 0x02; /* general purpose, check all */
const int NOTIFY_TYPE_ADD    = 0x04; /* flagged additions */
const int NOTIFY_TYPE_DEL    = 0x08; /* flagged deletions */

const uint32_t NOTIFY_HASHTYPE_EXAMINING_FILES = 1; /* Examining shared files */
const uint32_t NOTIFY_HASHTYPE_FINISH          = 2; /* Finish */
const uint32_t NOTIFY_HASHTYPE_HASH_FILE       = 3; /* Hashing file */
const uint32_t NOTIFY_HASHTYPE_SAVE_FILE_INDEX = 4; /* Hashing file */

class RsFeedItem
{
	public:
		RsFeedItem(uint32_t type, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, uint32_t result1)
			:mType(type), mId1(id1), mId2(id2), mId3(id3), mId4(id4), mResult1(result1) {}

		RsFeedItem() :mType(0), mResult1(0) { return; }

		uint32_t mType;
		std::string mId1, mId2, mId3, mId4;
		uint32_t mResult1;
};

// This class implements a generic notify client. To have your own components being notified by
// the Retroshare library, sub-class NotifyClient, and overload the methods you want to make use of
// (The other methods will just ignore the call), and register your ownclient into RsNotify, as:
//
//       	myNotifyClient: public NotifyClient
//       	{
//       		public:
//       			virtual void void notifyPeerHasNewAvatar(std::string peer_id) 
//       			{
//       				doMyOwnThing() ;
//       			}
//       	}
//      
//       	myNotifyClient *client = new myNotifyClient() ;
//      
//       	rsNotify->registerNotifyClient(client) ;
//
// This mechanism can be used in plugins, new services, etc.
//	

class NotifyClient ;

class RsNotify 
{
	public:
		/* registration of notifies clients */
		virtual void registerNotifyClient(NotifyClient *nc) = 0;
        /* returns true if NotifyClient was found */
        virtual bool unregisterNotifyClient(NotifyClient *nc) = 0;

		/* Pull methods for retroshare-gui                   */
		/* this should probably go into a different service. */
		 
		virtual bool NotifySysMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg) = 0;
		virtual bool NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &title, std::string &msg) = 0;
		virtual bool NotifyLogMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg) = 0;

		virtual bool GetFeedItem(RsFeedItem &item) = 0;
};

class NotifyClient
{
	public:
		NotifyClient() {}
		virtual ~NotifyClient() {}

		virtual void notifyListPreChange              (int /* list */, int /* type */) {}
		virtual void notifyListChange                 (int /* list */, int /* type */) {}
		virtual void notifyErrorMsg                   (int /* list */, int /* sev  */, std::string /* msg */) {}
        virtual void notifyChatMessage                (const ChatMessage& /* msg      */) {}
        virtual void notifyChatStatus                 (const ChatId&      /* chat_id  */, const std::string& /* status_string */) {}
		virtual void notifyChatLobbyEvent             (uint64_t           /* lobby id */, uint32_t           /* event type    */ ,const std::string& /* nickname */,const std::string& /* any string */) {}
		virtual void notifyChatLobbyTimeShift         (int                /* time_shift*/) {}
		virtual void notifyCustomState                (const std::string& /* peer_id   */, const std::string&               /* status_string */) {}
		virtual void notifyHashingInfo                (uint32_t           /* type      */, const std::string&               /* fileinfo      */) {}
		virtual void notifyTurtleSearchResult         (uint32_t           /* search_id */, const std::list<TurtleFileInfo>& /* files         */) {}
		virtual void notifyPeerHasNewAvatar           (std::string        /* peer_id   */) {}
		virtual void notifyOwnAvatarChanged           () {}
		virtual void notifyOwnStatusMessageChanged    () {}
		virtual void notifyDiskFull                   (uint32_t           /* location  */, uint32_t                         /* size limit in MB */) {}
		virtual void notifyPeerStatusChanged          (const std::string& /* peer_id   */, uint32_t                         /* status           */) {}
        virtual void notifyGxsChange                  (const RsGxsChanges& /* changes  */) {}

		/* one or more peers has changed the states */
		virtual void notifyPeerStatusChangedSummary   () {}
		virtual void notifyDiscInfoChanged            () {}
#ifdef REMOVE
		virtual void notifyForumMsgReadSatusChanged   (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) {}
		virtual void notifyChannelMsgReadSatusChanged (const std::string& /* channelId */, const std::string& /* msgId */, uint32_t /* status */) {}
#endif
		virtual bool askForDeferredSelfSignature      (const void *       /* data      */, const uint32_t     /* len   */, unsigned char * /* sign */, unsigned int * /* signlen */,int& signature_result ) { signature_result = false ;return true; }
		virtual void notifyDownloadComplete           (const std::string& /* fileHash  */) {}
		virtual void notifyDownloadCompleteCount      (uint32_t           /* count     */) {}
		virtual void notifyHistoryChanged             (uint32_t           /* msgId     */, int /* type */) {}

		virtual bool askForPassword                   (const std::string& /* key_details     */, bool               /* prev_is_bad */, std::string& /* password */ ) { return false ;}
		virtual bool askForPluginConfirmation         (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */) { return false ;}

};
#endif