/***************************************************************************
                          kmesssendplugin.cpp -  description
                             -------------------
    begin                : Wednesday July 09 2008
    copyright            : (C) 2008 by Ruben Vandamme
    email                : vandammeru gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/


#include "kmesssendplugin.h"
#include "kmesssendmenuitem.h"
#include "../kmessdbusdatatypes.h"
#include "../../kmessdebug.h"
#include "../../contact/msnstatus.h"

#include <kaction.h>
#include <kactionmenu.h>
#include <kgenericfactory.h>
#include <klocale.h>
#include <konq_popupmenuinformation.h>
#include <QMetaType>
#include <QtDBus>



class KMessSendPluginFactory : public KGenericFactory<KMessSendPlugin, KonqPopupMenu>
{
  public:
    KMessSendPluginFactory( const char *instanceName  = 0 )
    : KGenericFactory<KMessSendPlugin, KonqPopupMenu>( instanceName )
    {
    }



    ~KMessSendPluginFactory()
    {
    }
};



K_EXPORT_COMPONENT_FACTORY (libkmesssendplugin, KMessSendPluginFactory ("kmesssendplugin"))



// Constructor
KMessSendPlugin::KMessSendPlugin( KonqPopupMenu *popupMenu, const QStringList & /* list */ )
:KonqPopupMenuPlugin(popupMenu)
{
  KGlobal::locale()->insertCatalog("kmess");

  KMESSDBUS_REGISTER_DATATYPES
}



// Setup the menu
void KMessSendPlugin::setup( KActionCollection *actionCollection, const KonqPopupMenuInformation& popupMenuInfo, QMenu *menu )
{
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
  kmDebug() << "Setting up plugin";
#endif

  // Remember currently selected files
  KFileItemList itemList = popupMenuInfo.items();

  foreach( const KFileItem& item, itemList )
  {
    itemList_.append( item.localPath() );
  }

  // First see if KMess is running
  QDBusConnection bus = QDBusConnection::sessionBus();

  // Search for a running KMess instance
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
  kmDebug() << "Searching for KMess instances on DBus";
#endif

  const QStringList serviceNames = bus.interface()->registeredServiceNames();
  QString service;
  QStringList instances;

  foreach( service, serviceNames )
  {
    if( service.startsWith( "org.kmess.kmess" ) )
    {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
      kmDebug() << service;
#endif
      instances << service;
    }
  }

  // Quit if KMess is not running
  if( instances.isEmpty() )
  {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
    kmDebug() << "No running KMess instance found, aborting";
#endif

    return;
  }

  // Create the menu
  KActionMenu *sendMenu = new KActionMenu( KIcon("kmess"), i18n ("Send with KMess"), actionCollection );

  menu->addSeparator();
  menu->addAction( sendMenu );
  menu->addSeparator();

  KMessSendMenuItem *menuItem = 0;

  KActionMenu *subMenu = sendMenu;

  // Connect to all found KMess instances
  foreach( service, instances )
  {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
    kmDebug() << "Connecting to " + service;
#endif
    // Open the found DBus interface
    QDBusInterface  *dbusInterface = new QDBusInterface( service, "/remoteControl", "org.kmess.remoteControl", bus, this);

    QDBusReply<QList<DBusContact> > reply = dbusInterface->call("getList");

    if( !reply.isValid() )
    {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
      kmDebug() << "Invalid reply when getting contactlist: " << reply.error();
#endif
      sendMenu->setEnabled( false );
      return;
    }

    // If more than one KMess instance is running, create submenus per account
    if( instances.size() > 1 )
    {
      QDBusReply<QString> nickName = dbusInterface->call("getFriendlyName");

      if( !nickName.isValid() )
      {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
        kmDebug() << "Invalid reply when getting friendly name: " << reply.error();
#endif
        sendMenu->setEnabled( false );
        return;
      }

#ifdef KMESSDEBUG_KMESSSENDPLUGIN
      kmDebug() << "Creating submenu for account " << nickName;
#endif
      subMenu = new KActionMenu( KIcon("kmess"), nickName, actionCollection);
      sendMenu->addAction( subMenu );
    }

    QListIterator<DBusContact> i( reply );
    DBusContact contact;
    bool contactsToShow = false;

    // Add every contact
    while( i.hasNext() )
    {
      contact = i.next();

      // Don't show contact if invisible or offline
      if( contact.status == 4 || contact.status == 6 )
      {
        continue;
      }
      contactsToShow = true;

      menuItem = new KMessSendMenuItem( contact, dbusInterface, actionCollection );
      connect( menuItem, SIGNAL( triggered( bool ) ), this, SLOT( slotSendFile() ) );
      subMenu->addAction( menuItem );
    }

#ifdef KMESSDEBUG_KMESSSENDPLUGIN
    if( !contactsToShow )
    {
      kmDebug() << "No contacts to show";
    }
#endif
    subMenu->setEnabled( contactsToShow );
  }
}



// Destructor
KMessSendPlugin::~KMessSendPlugin()
{
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
  kmDebug() << "DESTROYED.";
#endif
}



// Send the selected files
void KMessSendPlugin::slotSendFile()
{
  const KMessSendMenuItem *menuItem = dynamic_cast<const KMessSendMenuItem*>( sender() );

#ifdef KMESSDEBUG_KMESSSENDPLUGIN
  kmDebug() << "Sending Files to " << menuItem->contact_.handle << " via " << menuItem->dbusInterface_;
#endif

  QStringListIterator i( itemList_ );
  QString fileName;

  while( i.hasNext() )
  {
    fileName = i.next();

#ifdef KMESSDEBUG_KMESSSENDPLUGIN
    kmDebug() << "Sending file" << fileName;
#endif

    QList<QVariant> args;
    args.append( menuItem->contact_.handle );
    args.append( fileName );

    QDBusReply<void> reply = menuItem->dbusInterface_->callWithArgumentList( QDBus::AutoDetect, "startFileTransfer", args );

    if( !reply.isValid() )
    {
#ifdef KMESSDEBUG_KMESSSENDPLUGIN
      kmDebug() << "Failed to send files:" << reply.error();
#endif
    }
  }
}



#include "kmesssendplugin.moc"
