/***************************************************************************
                          invitedialog.cpp -  description
                             -------------------
    begin                : Wed Oct 31 2008
    copyright            : (C) 2008 by Antonio Nastasi
    email                : sifcenter@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 "invitedialog.h"

#include "contactentry.h"
#include "../currentaccount.h"
#include "../kmessdebug.h"
#include "../contact/contact.h"
#include "../model/contactlist.h"
#include "../utils/kmessconfig.h"



// Constructor
InviteDialog::InviteDialog( const QStringList &usersAlreadyInChat, QStringList &usersToInvite, QWidget *parent )
: KDialog( parent )
, Ui::InviteDialog()
{
   // Set up the interface and the dialog
  setObjectName( "Invite" );
  QWidget *mainWidget = new QWidget( this );
  setupUi( mainWidget );
  setMainWidget( mainWidget );
  setWindowModality( Qt::ApplicationModal );
  setCaption( i18nc("Caption of a dialog box", "Invite Contacts") );
  setButtons( Ok | Cancel );
  setDefaultButton( Ok );
  restoreDialogSize( KMessConfig::instance()->getGlobalConfig( "InviteDialog" ) );

  // Setup the layouts
  contactsLayout_ = static_cast<QVBoxLayout*>( contactsArea_->layout() );
  contactsLayout_->addStretch();
  invitedLayout_ = static_cast<QVBoxLayout*>( invitedArea_->layout() );
  invitedLayout_->addStretch();

  // Set buttons
  addButton_   ->setIcon( KIcon( "go-next" ) );
  removeButton_->setIcon( KIcon( "go-previous" ) );
  connect(    addButton_, SIGNAL( clicked() ), this, SLOT(    addContact() ) );
  connect( removeButton_, SIGNAL( clicked() ), this, SLOT( removeContact() ) );

  // Set the other contact button
  otherButton_->setIcon( KIcon( "contact-new" ) );
  connect( otherButton_, SIGNAL(       clicked() ), this, SLOT( addOtherContactEntry() ) );
  connect(   otherEdit_, SIGNAL( returnPressed() ), this, SLOT( addOtherContactEntry() ) );

  // Search widgets
  searchIcon_->setPixmap( KIconLoader::global()->loadIcon( "edit-find-user", KIconLoader::Small ) );
  connect( searchEdit_, SIGNAL( textChanged(QString) ), this, SLOT( searchTextChanged() ) );

  // Calls update interface
  updateInterface( usersAlreadyInChat );

  // Show the dialog modally
  int result = exec();

  // Set the result stringlist if the user has pressed the Ok button
  if( result == QDialog::Accepted )
  {
    usersToInvite = usersToInvite_;
  }
  else
  {
    usersToInvite = QStringList();
  }

  kmDebug() << "Users to invite: " << usersToInvite;

  // Schedule the dialog for deletion
  deleteLater();
}



// Destructor
InviteDialog::~InviteDialog()
{
  kmDebug() << "DESTROYED";

  // Save the dialog size and position
  KConfigGroup group = KMessConfig::instance()->getGlobalConfig( "InviteDialog" );
  saveDialogSize( group );

  // Delete all widgets
  qDeleteAll( contactEntryList_ );
}


// Add contact to invite list
void InviteDialog::addContact()
{
  ContactEntry *contactEntry;
  foreach( contactEntry, contactEntryList_ )
  {
    if( ! contactEntry->isSelected() )
    {
      continue;
    }

    // Remove entry from contact list and add to invited contact list
    contactsLayout_->removeWidget( contactEntry );
    invitedLayout_->insertWidget( 0, contactEntry );
    usersToInvite_.append( contactEntry->getHandle() );

    invitedContacts_.append( contactEntry );
    contactEntryList_.removeAll( contactEntry );
    contactEntry->click();
  }
}



// The other contact insert button was pressed
void InviteDialog::addOtherContactEntry()
{
  // Grep the text and clean the QLineEdit
  const QString handle( otherEdit_->text() );
  otherEdit_->setText( "" );

  // Check if the handle is empty or if the users to invite list contains already it
  // or if account isn't valid email
  if( handle.isEmpty() || usersToInvite_.contains( handle )
      || ! Account::isValidEmail( handle ) )
  {
    return;
  }

  ContactEntry *contactEntry;

  // Check if the handle is of one contact we have already in contact list
  // We need to check only the contact list ( no invited list ) beacuse we check already
  // for it in usersToInvite_
  foreach( contactEntry, contactEntryList_ )
  {
    if( contactEntry->getHandle() == handle )
    {
      // Remove entry from contact list and add to invited contact list
      contactsLayout_->removeWidget( contactEntry );
      invitedLayout_->insertWidget( 0, contactEntry );
      usersToInvite_.append( contactEntry->getHandle() );
      invitedContacts_.append( contactEntry );
      contactEntryList_.removeAll( contactEntry );
      return;
    }
  }

  // Insert in the invited contact
  contactEntry = new ContactEntry( handle );
  connect( contactEntry, SIGNAL( clicked() ), this, SLOT( contactClicked() ) );

  invitedContacts_.append( contactEntry );
  invitedLayout_->insertWidget( 0, contactEntry );
}



// One contact entry was pressed
void InviteDialog::contactClicked()
{
  // Grep the pointer of widget clicked and select/deselect it
  ContactEntry *contactEntry = static_cast<ContactEntry*>( sender() );
  if( contactEntry != 0 )
  {
    kmDebug() << contactEntry->isSelected();
    contactEntry->click();
  }
}



// Remove contact from invite list
void InviteDialog::removeContact()
{
  ContactEntry *contactEntry;
  foreach( contactEntry, invitedContacts_)
  {
    if( ! contactEntry->isSelected() )
    {
      continue;
    }

    // Remove entry from invited contact list and add to contact list
    invitedLayout_->removeWidget( contactEntry );
    contactsLayout_->insertWidget( 0, contactEntry );
    usersToInvite_.removeAll( contactEntry->getHandle() );
    contactEntryList_.append( contactEntry );
    invitedContacts_.removeAll( contactEntry );

    // Deselect the entry
    contactEntry->click();
  }
}



// The search text was changed
void InviteDialog::searchTextChanged()
{
  const QString text( searchEdit_->text().toLower() );
  ContactEntry *contactEntry;

  foreach( contactEntry, contactEntryList_ )
  {
    if( contactEntry->getHandle()             .toLower().contains( text )
    ||  contactEntry->getCleanedFriendlyName().toLower().contains( text ) )
    {
      contactEntry->show();
      continue;
    }

    contactEntry->click( true );
    contactEntry->hide();
  }
}



// Update the interface with the contact entries
void InviteDialog::updateInterface( const QStringList &usersAlreadyInChat, bool onlyOnline )
{
  const Contact *contact;
  ContactEntry *contactEntry;
  const CurrentAccount *currentAccount = CurrentAccount::instance();
  QHashIterator<QString,Contact*> it( currentAccount->getContactList()->getContactList() );

  // Interate to add each contact
  const QString& currentHandle = currentAccount->getHandle();
  while ( it.hasNext() )
  {
    contact = it.next().value();
    const QString& handle = contact->getHandle();

    // If the current user is already in multi-chat, jump to next
    if(  usersAlreadyInChat.contains( handle ) )
    {
      continue;
    }

    // don't show ourselves in the invite list.
    if ( handle == currentHandle )
    {
      continue;
    }

    // skip non-messenger contacts.
    if ( ! contact->isMessengerUser() )
    {
      continue;
    }

    // Check if the contact is online or if we want also the offline contacts
    if( contact->isOnline() || ! onlyOnline )
    {
      contactEntry = new ContactEntry( contact );
      contactEntryList_.append( contactEntry );
      contactsLayout_->insertWidget( 0, contactEntry );
      connect( contactEntry, SIGNAL( clicked() ), this, SLOT( contactClicked() ) );
    }
  }
}


#include "invitedialog.moc"
