/** 
 * @file llnotificationhandler.h
 * @brief Here are implemented Notification Handling Classes.
 *
 * $LicenseInfo:firstyear=2003&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLNOTIFICATIONHANDLER_H
#define LL_LLNOTIFICATIONHANDLER_H

#include <boost/intrusive_ptr.hpp>

#include "llwindow.h"

#include "llnotifications.h"
#include "llchannelmanager.h"
#include "llchat.h"
#include "llinstantmessage.h"
#include "llnotificationptr.h"

class LLFloaterIMSession;

namespace LLNotificationsUI
{

/**
 * Handler of notification events.
 * This handler manages events related to toasts and chicklets. This is  base class
 * for chat and system notification handlers.
 */

// LLEventHandler is a base class that specifies a common interface for all
// notification handlers. It states, that every handler must react on the follofing
// events:
//			- deleting of a toast;
//			- initialization of a corresponding channel;
// Also every handler must have the following attributes:
//			- type of the notification that this handler is responsible to;
//			- pointer to a correspondent screen channel, in which all toasts of the handled notification's
//			  type should be displayed
// This class also provides the following signald:
//			- increment counter signal
//			- decrement counter signal
//			- update counter signal
//			- signal, that emits ID of the notification that is being processed
//
class LLEventHandler
{
public:
	virtual ~LLEventHandler() {};

protected:
	virtual void onDeleteToast(LLToast* toast) {}

	// arrange handler's channel on a screen
	// is necessary to unbind a moment of creation of a channel and a moment of positioning of it
	// it is useful when positioning depends on positions of other controls, that could not be created
	// at the moment, when a handlers creates a channel.
	virtual void initChannel()=0;

	LLHandle<LLScreenChannelBase>	mChannel;
};

// LLSysHandler and LLChatHandler are more specific base classes
// that divide all notification handlers on to groups:
//			- handlers for different system notifications (script dialogs, tips, group notices, alerts and IMs);
//			- handlers for different messaging notifications (nearby chat)
/**
 * Handler for system notifications.
 */
class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
{
public:
	LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
	virtual ~LLNotificationHandler() {};

	// base interface functions
	virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
	virtual void onChange(LLNotificationPtr p) { processNotification(p); }
	virtual void onLoad(LLNotificationPtr p) { processNotification(p, false); }
	virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}

	virtual bool processNotification(const LLNotificationPtr& notify, bool should_log = true) = 0;
};

class LLSystemNotificationHandler : public LLNotificationHandler
{
public:
	LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
	virtual ~LLSystemNotificationHandler() {};
};

class LLCommunicationNotificationHandler : public LLNotificationHandler
{
public:
	LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
	virtual ~LLCommunicationNotificationHandler() {};
};

/**
 * Handler for chat message notifications. 
 */
class LLChatHandler : public LLEventHandler
{
public:
	virtual ~LLChatHandler() {};

	virtual void processChat(const LLChat& chat_msg, const LLSD &args)=0;
};

/**
 * Handler for IM notifications.
 * It manages life time of IMs, group messages.
 */
class LLIMHandler : public LLCommunicationNotificationHandler
{
public:
	LLIMHandler();
	virtual ~LLIMHandler();
	bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel();
};

/**
 * Handler for system informational notices.
 * It manages life time of tip notices.
 */
class LLTipHandler : public LLSystemNotificationHandler
{
public:
	LLTipHandler();
	virtual ~LLTipHandler();

	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel();
};

/**
 * Handler for system informational notices.
 * It manages life time of script notices.
 */
class LLScriptHandler : public LLSystemNotificationHandler
{
public:
	LLScriptHandler();
	virtual ~LLScriptHandler();

	virtual void onDelete(LLNotificationPtr p);
	virtual void onChange(LLNotificationPtr p);
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);
	virtual void addToastWithNotification(const LLNotificationPtr& p);

protected:
	virtual void onDeleteToast(LLToast* toast);
	virtual void initChannel();
};


/**
 * Handler for group system notices.
 */
class LLGroupHandler : public LLCommunicationNotificationHandler
{
public:
	LLGroupHandler();
	virtual ~LLGroupHandler();
	
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel();
};

/**
 * Handler for alert system notices.
 */
class LLAlertHandler : public LLSystemNotificationHandler
{
public:
	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
	virtual ~LLAlertHandler();

	virtual void onChange(LLNotificationPtr p);
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel();

	bool	mIsModal;
};

class LLViewerAlertHandler  : public LLSystemNotificationHandler
{
	LOG_CLASS(LLViewerAlertHandler);
public:
	LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
	virtual ~LLViewerAlertHandler() {};

	virtual void onDelete(LLNotificationPtr p) {};
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel() {};
};

/**
 * Handler for offers notices.
 * It manages life time of offer notices.
 */
class LLOfferHandler : public LLCommunicationNotificationHandler
{
public:
	LLOfferHandler();
	virtual ~LLOfferHandler();

	virtual void onChange(LLNotificationPtr p);
	virtual void onDelete(LLNotificationPtr notification);
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel();
};

/**
 * Handler for UI hints.
 */
class LLHintHandler : public LLSystemNotificationHandler
{
public:
	LLHintHandler();
	virtual ~LLHintHandler() {}

	virtual void onAdd(LLNotificationPtr p);
	virtual void onLoad(LLNotificationPtr p);
	virtual void onDelete(LLNotificationPtr p);
	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel() {};
};

/**
 * Handler for browser notifications
 */
class LLBrowserNotification : public LLSystemNotificationHandler
{
public:
	LLBrowserNotification();
	virtual ~LLBrowserNotification() {}

	virtual bool processNotification(const LLNotificationPtr& p, bool should_log = true);

protected:
	virtual void initChannel() {};
};
	
class LLHandlerUtil
{
public:
	/**
	 * Determines whether IM floater is opened.
	 */
	static bool isIMFloaterOpened(const LLNotificationPtr& notification);

	/**
	 * Writes notification message to IM session.
	 */
	static void logToIM(const EInstantMessage& session_type,
			const std::string& session_name, const std::string& from_name,
			const std::string& message, const LLUUID& session_owner_id,
			const LLUUID& from_id);

	/**
	 * Writes notification message to IM  p2p session.
	 */
	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
	static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false);

	/**
	 * Writes group notice notification message to IM  group session.
	 */
	static void logGroupNoticeToIMGroup(const LLNotificationPtr& notification);

	/**
	 * Writes notification message to nearby chat.
	 */
	static void logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type);

	/**
	 * Spawns IM session.
	 */
	static LLUUID spawnIMSession(const std::string& name, const LLUUID& from_id);

	/**
	 * Returns name from the notification's substitution.
	 *
	 * Methods gets "NAME" or "[NAME]" from the substitution map.
	 *
	 * @param notification - Notification which substitution's name will be returned.
	 */
	static std::string getSubstitutionName(const LLNotificationPtr& notification);

	static std::string getSubstitutionOriginalName(const LLNotificationPtr& notification);

	/**
	 * Adds notification panel to the IM floater.
	 */
	static void addNotifPanelToIM(const LLNotificationPtr& notification);

	/**
	 * Updates messages of IM floater.
	 */
	static void updateIMFLoaterMesages(const LLUUID& session_id);

	/**
	 * Updates messages of visible IM floater.
	 */
	static void updateVisibleIMFLoaterMesages(const LLNotificationPtr& notification);

	/**
	 * Decrements counter of IM messages.
	 */
	static void decIMMesageCounter(const LLNotificationPtr& notification);

};

}
#endif