WlmContact::WlmContact (Kopete::Account * _account,
                        const QString & uniqueName,
                        const QString & contactSerial,
                        Kopete::MetaContact * parent):
Kopete::Contact (_account, uniqueName, parent)
{
    kDebug (14210) << k_funcinfo << " uniqueName: " << uniqueName;
    m_msgManager = 0L;
    m_account = qobject_cast<WlmAccount*>(account());
    setFileCapable (true);
    setOnlineStatus (WlmProtocol::protocol ()->wlmOffline);
    m_contactSerial = contactSerial;
    m_disabled = false;
    m_dontShowEmoticons = false;

    if ( metaContact() )
        m_currentGroup = metaContact()->groups().first();

    m_actionBlockContact = new KToggleAction(KIcon("wlm_blocked"), i18n("Block Contact"), this );
    QObject::connect( m_actionBlockContact, SIGNAL(triggered(bool)), this, SLOT(blockContact(bool)) );

    m_actionShowProfile = new KAction(i18n("Show Profile"), this);
    QObject::connect(m_actionShowProfile, SIGNAL(triggered(bool)), this, SLOT(slotShowProfile()));

    m_actionUpdateDisplayPicture = new KAction(i18n("Update Photo"), this);
    QObject::connect(m_actionUpdateDisplayPicture, SIGNAL(triggered(bool)), this, SLOT(slotUpdateDisplayPicture()));

    m_actionDontShowEmoticons = new KToggleAction (KIcon ("wlm_fakefriend"), 
           i18n ("&Block custom emoticons"), this);
    QObject::connect (m_actionDontShowEmoticons, SIGNAL(triggered(bool)), this, SLOT(slotDontShowEmoticons(bool)));
}
void Contact::slotAddContact()
{
	if( metaContact() )
	{
		metaContact()->setTemporary( false );
		ContactList::self()->addMetaContact( metaContact() );
	}
}
void WlmContact::setDisabled(bool disabled, bool updateServer)
{
    WlmAccount* acc = qobject_cast<WlmAccount*>(account());
    if(!acc)
        return;

    if(disabled)
    {
        // already disabled
        if(isDisabled())
            return;

        m_disabled = true;

        if(!metaContact())
            return;

        metaContact()->setTemporary(m_disabled);

        setOnlineStatus(WlmProtocol::protocol()->wlmOffline);

        if(updateServer && account ()->isConnected ())
            acc->server ()->mainConnection->disableContactOnAddressBook( m_contactSerial.toLatin1().constData(), contactId ().toLatin1().constData() );
    }
    else
    {
        // already enabled
        if(!isDisabled())
            return;

        m_disabled = false;

        if(!metaContact())
            return;

        metaContact()->setTemporary(m_disabled);
        setOnlineStatus(WlmProtocol::protocol()->wlmOffline);

        if(updateServer && account ()->isConnected ())
            acc->server()->mainConnection->enableContactOnAddressBook(m_contactSerial.toLatin1().constData(), contactId().toLatin1().constData());
    }
}
KMenu* Contact::popupMenu()
{
	KMenu *menu = new KMenu();

	QString titleText;
	const QString nick = nickName();
	if( nick == contactId() )
		titleText = QString::fromLatin1( "%1 (%2)" ).arg( contactId(), onlineStatus().description() );
	else
		titleText = QString::fromLatin1( "%1 <%2> (%3)" ).arg( nick, contactId(), onlineStatus().description() );
	menu->addTitle( titleText );

	if( metaContact() && metaContact()->isTemporary() && contactId() != account()->myself()->contactId() )
	{
		KAction *actionAddContact = new KAction( KIcon("list-add-user"), i18n( "&Add to Your Contact List" ), menu );
		connect( actionAddContact, SIGNAL(triggered(bool)), this, SLOT(slotAddContact()) );

		menu->addAction(actionAddContact);
		menu->addSeparator();
	}
void IRCUserContact::userOnline()
{
	mInfo.online = true;
	updateStatus();
	if (this != ircAccount()->mySelf() && !metaContact()->isTemporary() && ircAccount()->isConnected())
	{
		mOnlineTimer->start( 45000, true );
		ircAccount()->setCurrentCommandSource(0);
		kircEngine()->whois(m_nickName);
	}

	removeProperty( m_protocol->propLastSeen );
}
void IRCUserContact::slotUserOffline()
{
	mInfo.online = false;
	mInfo.away   = false;

	updateStatus();

	if( !metaContact()->isTemporary() )
		kircEngine()->writeMessage( QString::fromLatin1("WHOWAS %1").arg(m_nickName) );

	removeProperty( m_protocol->propUserInfo );
	removeProperty( m_protocol->propServer );
	removeProperty( m_protocol->propChannels );
}
void IRCUserContact::newWhoIsServer(const QString &servername, const QString &serverinfo)
{
	mInfo.serverName = servername;
	if( metaContact()->isTemporary() || onlineStatus().status() == Kopete::OnlineStatus::Online
		|| onlineStatus().status() == Kopete::OnlineStatus::Away )
		mInfo.serverInfo = serverinfo;
	else
	{
		//kdDebug(14120)<< "Setting last online: " << serverinfo << endl;

		// Try to convert first, since server can return depending if
		// user is online or not:
		// 
		//   312 mynick othernick localhost.localdomain :FooNet Server
		//   312 mynick othernick localhost.localdomain :Thu Jun 16 21:00:36 2005

		QDateTime lastSeen = QDateTime::fromString( serverinfo );
		if( lastSeen.isValid() )
			setProperty( m_protocol->propLastSeen, lastSeen );
	}
}
IRCUserContact::IRCUserContact(IRCContactManager *contactManager, const QString &nickname, Kopete::MetaContact *m )
	: IRCContact(contactManager, nickname, m ),
	actionCtcpMenu(0L)
{
	setFileCapable(true);

	mOnlineTimer = new QTimer( this );

	QObject::connect(mOnlineTimer, SIGNAL(timeout()), this, SLOT( slotUserOffline() ) );

	QObject::connect(kircEngine(), SIGNAL(incomingChannelModeChange(const QString&, const QString&, const QString&)),
		this, SLOT(slotIncomingModeChange(const QString&,const QString&, const QString&)));

	mInfo.isOperator = false;
	mInfo.isIdentified = false;
	mInfo.idle = 0;
	mInfo.hops = 0;
	mInfo.away = false;
	mInfo.online = metaContact()->isTemporary();

	updateStatus();
}
void WlmContact::sync(unsigned int flags)
{
    if (!account ()->isConnected ())
        return;
    /* 
     * If the contact has changed groups, then we update the server.
     */
    if( !metaContact() )
        return;

    // Don't add the contact if it's myself.
    if(contactId() == account()->accountId())
        return;

    if ( (flags & Kopete::Contact::MovedBetweenGroup) == Kopete::Contact::MovedBetweenGroup )
    {
        Kopete::Group* newGroup = metaContact()->groups().first();
        WlmAccount* acc = qobject_cast<WlmAccount*>(account());
        if(!acc)
            return;

        // if this contact is not in the contact list, add it
        if(!acc->isOnServerSideList(contactId()))
        {
            acc->createContact(contactId(), metaContact());
            m_currentGroup = newGroup;
            return;
        }

        if(isDisabled())
        {
            // enable this contact and update on server side
            setDisabled(false,true);
        }

        if(newGroup == m_currentGroup)
            return;

        if(newGroup == Kopete::Group::topLevel())
        {
            acc->server ()->mainConnection->removeFromGroup (
                acc->groupToGroupId().value(m_currentGroup->displayName()).toLatin1().constData(),
                m_contactSerial.toLatin1().constData ());
            m_currentGroup = newGroup;
            return;
        }

        // if the group don't exist on server side, we create it
        if(!acc->groupToGroupId().contains(newGroup->displayName()))
        {
            acc->server ()->mainConnection->addGroup(newGroup->displayName().toUtf8().constData());
                return;
        }

        // if we have both groups on server side, just move this contact
        if(acc->groupToGroupId().contains(newGroup->displayName())
            && acc->groupToGroupId().contains(m_currentGroup->displayName()))
        {
            acc->server ()->mainConnection->removeFromGroup (
                acc->groupToGroupId().value(m_currentGroup->displayName()).toLatin1().constData(),
                m_contactSerial.toLatin1().constData ());
            acc->server ()->mainConnection->addToGroup (
                acc->groupToGroupId().value(newGroup->displayName()).toLatin1().constData(),
                m_contactSerial.toLatin1().constData ());
            m_currentGroup = newGroup;
            return;
        }
        if(m_currentGroup == Kopete::Group::topLevel() &&
                acc->groupToGroupId().contains(newGroup->displayName()))
        {
            acc->server ()->mainConnection->addToGroup (
                acc->groupToGroupId().value(newGroup->displayName()).toLatin1().constData(),
                m_contactSerial.toLatin1().constData ());
            m_currentGroup = newGroup;
            return;
        }
    }
}