/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2010-2011 Oleg Linkin
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#ifndef PLUGINS_AZOTH_PLUGINS_ACETAMIDE_CHANNELHANDLER_H
#define PLUGINS_AZOTH_PLUGINS_ACETAMIDE_CHANNELHANDLER_H

#include <QObject>
#include <QHash>
#include <interfaces/azoth/imessage.h>
#include "localtypes.h"
#include "channelparticipantentry.h"

namespace LeechCraft
{
namespace Azoth
{
namespace Acetamide
{
	class ChannelCLEntry;
	class IrcMessage;
	class IrcServerHandler;
	class ChannelsManager;

	class ChannelHandler : public QObject
	{
		Q_OBJECT

		std::shared_ptr<ChannelCLEntry> ChannelCLEntry_;
		ChannelsManager *CM_;

		QString ChannelID_;
		QString Subject_;

		ChannelOptions ChannelOptions_;

		bool IsRosterReceived_;

		QHash<QString, ChannelParticipantEntry_ptr> Nick2Entry_;

		ChannelModes ChannelMode_;
		QString Url_;
	public:
		ChannelHandler (const ChannelOptions& options, ChannelsManager *manager);
		QString GetChannelID () const;
		ChannelCLEntry* GetCLEntry () const;

		ChannelsManager* GetChannelsManager () const;

		QString GetParentID () const;

		ChannelOptions GetChannelOptions () const;
		QList<QObject*> GetParticipants () const;

		ChannelParticipantEntry_ptr GetSelf ();
		ChannelParticipantEntry_ptr GetParticipantEntry (const QString&, bool announce = true);

		bool IsUserExists (const QString&) const;

		IrcMessage* CreateMessage (IMessage::MessageType,
				const QString&, const QString&);

		void ChangeNickname (const QString& oldNick, const QString& newNick);

		bool IsRosterReceived () const;
		void SetRosterReceived (bool);

		void HandleServiceMessage (const QString&, IMessage::MessageType,
				IMessage::MessageSubType,
				ChannelParticipantEntry_ptr entry = ChannelParticipantEntry_ptr ());

		void SendPublicMessage (const QString&);
		void HandleIncomingMessage (const QString& nick, const QString& msg);
		void SetChannelUser (const QString& nick,
				const QString& user = QString (), const QString& host = QString ());

		void MakeJoinMessage (const QString&);
		void MakeLeaveMessage (const QString&, const QString&);
		void MakeKickMessage (const QString&, const QString&,
				const QString&);
		void MakePermsChangedMessage (const QString&,
				ChannelRole, bool);

		void SetMUCSubject (const QString&);
		QString GetMUCSubject () const;
		void SetTopic (const QString& topic);

		void Leave (const QString&);
		void CloseChannel ();

		void LeaveParticipant (const QString&, const QString&);

		void KickParticipant (const QString&, const QString&,
				const QString&);

		void SetRole (ChannelParticipantEntry*, const ChannelRole&, const QString&);
		void ManageWithParticipant (ChannelParticipantEntry*, const ChannelManagment&);

		void RequestBanList ();
		void RequestExceptList ();
		void RequestInviteList ();
		void AddBanListItem (QString);
		void RemoveBanListItem (QString);
		void AddExceptListItem (QString);
		void RemoveExceptListItem (QString);
		void AddInviteListItem (QString);
		void RemoveInviteListItem (QString);
		void SetBanListItem (const QString&, const QString&,
				const QDateTime&);
		void SetExceptListItem (const QString&, const QString&,
				const QDateTime&);
		void SetInviteListItem (const QString&, const QString&,
				const QDateTime&);
		ChannelModes GetChannelModes () const;
		void SetInviteMode (bool);
		void SetModerateMode (bool);
		void SetBlockOutsideMessagesMode (bool);
		void SetPrivateMode (bool);
		void SetSecretMode (bool);
		void SetServerReOpMode (bool);
		void SetOnlyOpTopicChangeMode (bool);
		void SetUserLimit (bool, int limit = 0);
		void SetChannelKey (bool, const QString& key = QString ());
		void SetNewChannelModes (const ChannelModes&);

		void UpdateEntry (const WhoMessage& message);

		void SetUrl (const QString& url);
	private:
		bool RemoveUserFromChannel (const QString&);
		ChannelParticipantEntry_ptr CreateParticipantEntry (const QString&, bool announce = true);
		void RemoveThis ();
	public slots:
		void handleWhoIs (const QString& nick);
		void handleWhoWas (const QString& nick);
		void handleWho (const QString& nick);
		void handleCTCPRequest (const QStringList& cmd);
	signals:
		void updateChanModes (const ChannelModes&);
	};
};
};
};

#endif // PLUGINS_AZOTH_PLUGINS_ACETAMIDE_CHANNELHANDLER_H
