/*
    This file is part of KMail.

    Copyright (c) 2005 Cornelius Schumacher <schumacher@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
    
    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
    Library General Public License for more details.
    
    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <config.h> // for TDEPIM_NEW_DISTRLISTS

#include "distributionlistdialog.h"

#include <libemailfunctions/email.h>
#include <tdeabc/resource.h>
#include <tdeabc/stdaddressbook.h>
#include <tdeabc/distributionlist.h>

#ifdef TDEPIM_NEW_DISTRLISTS
#include <libtdepim/distributionlist.h>
#endif
#include <libtdepim/kaddrbook.h>

#include <tdelistview.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <kinputdialog.h>

#include <tqlayout.h>
#include <tqlabel.h>
#include <tqlineedit.h>

class DistributionListItem : public TQCheckListItem
{
  public:
    DistributionListItem( TQListView *list )
      : TQCheckListItem( list, TQString(), CheckBox )
    {
    }

    void setAddressee( const TDEABC::Addressee &a, const TQString &email )
    {
      mIsTransient = false;
      init( a, email );
    }

    void setTransientAddressee( const TDEABC::Addressee &a, const TQString &email )
    {
      mIsTransient = true;
      init( a, email );
    }

    void init( const TDEABC::Addressee &a, const TQString &email )
    {
      mAddressee = a;
      mEmail = email;
      setText( 1, mAddressee.realName() );
      setText( 2, mEmail );
    }

    TDEABC::Addressee addressee() const
    {
      return mAddressee;
    }
    
    TQString email() const
    {
      return mEmail;
    }
    
    bool isTransient() const
    {
      return mIsTransient;
    }
    
  private:
    TDEABC::Addressee mAddressee;
    TQString mEmail;
    bool mIsTransient;
};


DistributionListDialog::DistributionListDialog( TQWidget *parent )
  : KDialogBase( Plain, i18n("Save Distribution List"), User1 | Cancel,
                 User1, parent, 0, false, false, i18n("Save List") )
{
  TQFrame *topFrame = plainPage();
  
  TQBoxLayout *topLayout = new TQVBoxLayout( topFrame );
  topLayout->setSpacing( spacingHint() );
  
  TQBoxLayout *titleLayout = new TQHBoxLayout( topLayout );
  
  TQLabel *label = new TQLabel( i18n("Name:"), topFrame );
  titleLayout->addWidget( label );
  
  mTitleEdit = new TQLineEdit( topFrame );
  titleLayout->addWidget( mTitleEdit );
  mTitleEdit->setFocus();
  
  mRecipientsList = new TDEListView( topFrame );
  mRecipientsList->addColumn( TQString() );
  mRecipientsList->addColumn( i18n("Name") );
  mRecipientsList->addColumn( i18n("Email") );
  topLayout->addWidget( mRecipientsList );
}

void DistributionListDialog::setRecipients( const Recipient::List &recipients )
{
  Recipient::List::ConstIterator it;
  for( it = recipients.begin(); it != recipients.end(); ++it ) {
    TQStringList emails = KPIM::splitEmailAddrList( (*it).email() );
    TQStringList::ConstIterator it2;
    for( it2 = emails.begin(); it2 != emails.end(); ++it2 ) {
      TQString name;
      TQString email;
      TDEABC::Addressee::parseEmailAddress( *it2, name, email );
      if ( !email.isEmpty() ) {
        DistributionListItem *item = new DistributionListItem( mRecipientsList );
        TDEABC::Addressee::List addressees =
          TDEABC::StdAddressBook::self( true )->findByEmail( email );
        if ( addressees.isEmpty() ) {
          TDEABC::Addressee a;
          a.setNameFromString( name );
          a.insertEmail( email );
          item->setTransientAddressee( a, email );
          item->setOn( true );
        } else {
          TDEABC::Addressee::List::ConstIterator it3;
          for( it3 = addressees.begin(); it3 != addressees.end(); ++it3 ) {
            item->setAddressee( *it3, email );
            if ( it3 == addressees.begin() ) item->setOn( true );
          }
        }
      }
    }
  }
}

void DistributionListDialog::slotUser1()
{
  bool isEmpty = true;

  TQListViewItem *i = mRecipientsList->firstChild();
  while( i ) {
    DistributionListItem *item = static_cast<DistributionListItem *>( i );
    if ( item->isOn() ) {
      isEmpty = false;
      break;
    }
    i = i->nextSibling();
  }

  if ( isEmpty ) {
    KMessageBox::information( this,
                              i18n("There are no recipients in your list. "
                                   "First select some recipients, "
                                   "then try again.") );
    return;
  }

#ifndef TDEPIM_NEW_DISTRLISTS
  TDEABC::DistributionListManager manager( ab );
  manager.load();
#endif

  TQString name = mTitleEdit->text();

  if ( name.isEmpty() ) {
    bool ok = false;
    name = KInputDialog::getText( i18n("New Distribution List"),
      i18n("Please enter name:"), TQString(), &ok, this );
    if ( !ok || name.isEmpty() )
      return;
  }

  TDEABC::AddressBook *ab = TDEABC::StdAddressBook::self( true );

#ifdef TDEPIM_NEW_DISTRLISTS
  if ( !KPIM::DistributionList::findByName( ab, name ).isEmpty() ) {
#else
  if ( manager.list( name ) ) {
#endif
    KMessageBox::information( this,
      i18n( "<qt>Distribution list with the given name <b>%1</b> "
        "already exists. Please select a different name.</qt>" ).arg( name ) );
    return;
  }

  TDEABC::Resource* const resource = KAddrBookExternal::selectResourceForSaving( ab );
  if ( !resource )
    return;

  // Ask for a save ticket here, we use it for inserting the recipients into the addressbook and
  // also for saving the addressbook, see https://issues.kolab.org/issue4281
  TDEABC::Ticket *ticket = ab->requestSaveTicket( resource );
  if ( !ticket ) {
    kdWarning(5006) << "Unable to get save ticket!" << endl;
    return;
  }

#ifdef TDEPIM_NEW_DISTRLISTS
  KPIM::DistributionList dlist;
  dlist.setName( name );

  i = mRecipientsList->firstChild();
  while( i ) {
    DistributionListItem *item = static_cast<DistributionListItem *>( i );
    if ( item->isOn() ) {
      kdDebug() << "  " << item->addressee().fullEmail() << endl;
      if ( item->isTransient() ) {
        resource->insertAddressee( item->addressee() );
      }
      if ( item->email() == item->addressee().preferredEmail() ) {
        dlist.insertEntry( item->addressee() );
      } else {
        dlist.insertEntry( item->addressee(), item->email() );
      }
    }
    i = i->nextSibling();
  }

  resource->insertAddressee( dlist );
#else
  TDEABC::DistributionList *dlist = new TDEABC::DistributionList( &manager, name );
  i = mRecipientsList->firstChild();
  while( i ) {
    DistributionListItem *item = static_cast<DistributionListItem *>( i );
    if ( item->isOn() ) {
      kdDebug() << "  " << item->addressee().fullEmail() << endl;
      if ( item->isTransient() ) {
        resource->insertAddressee( item->addressee() );
      }
      if ( item->email() == item->addressee().preferredEmail() ) {
        dlist->insertEntry( item->addressee() );
      } else {
        dlist->insertEntry( item->addressee(), item->email() );
      }
    }
    i = i->nextSibling();
  }
#endif

  if ( !ab->save( ticket ) ) {
    kdWarning(5006) << k_funcinfo << " Couldn't save new addresses in the distribution list just created to the address book" << endl;
    ab->releaseSaveTicket( ticket );
    return;
  }

#ifndef TDEPIM_NEW_DISTRLISTS
  manager.save();
#endif

  // Only accept when the dist list is really in the addressbook, since we can't detect if the 
  // user aborted saving in another way, since insertAddressee() lacks a return code.
#ifdef TDEPIM_NEW_DISTRLISTS
  if ( !KPIM::DistributionList::findByName( ab, name ).isEmpty() ) {
#else
  if ( manager.list( name ) ) {
#endif
    accept();
  }
}