/* -*- C++ -*-
   This file implements the tab to edit the addresses.

   the KDE addressbook

   $ Author: Mirko Boehm $
   $ Copyright: (C) 1996-2000, Mirko Boehm $
   $ Contact: mirko@kde.org
         http://www.kde.org $
   $ License: GPL with the following explicit clarification:
         This code may be linked against any version of the Qt toolkit
         from Troll Tech, Norway. $

   $Revision: 1.20 $	
*/

#include "look_edit_tabaddresses.h"
#include "kab_deliverylabelwidget.h"
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpopupmenu.h>
#include <qlabel.h>
#include <qframe.h>
#include <qiconset.h>
#include <qstring.h>
#include <qtoolbutton.h>
#include <qmultilineedit.h>
#include <qtooltip.h>
#include <kmessagebox.h>
#include <kiconloader.h>
#include <kdialogbase.h>
#include <klocale.h>
#include <qconfigDB.h>
#include <kdebug.h>
#include <kapp.h>
#include <knotifyclient.h>
#include "dialog_insinuation.h"

#define KEY_ADDRESSTYPES "AddressTypes"

TabAddresses::TabAddresses(KabAPI* api, QWidget *parent)
  : TabBasic(api, parent),
    currentItem(0),
    modified(false)
{
  QStringList types;
  Section *section;
  KeyValueMap *keys;
  QHBoxLayout *layout;
  unsigned int count;
  // -----
  layout=new QHBoxLayout(this);
  layout->setAutoAdd(true);
  base=new TabAddressesBase(this);
  connect(base->newAddress, SIGNAL(clicked()), SLOT(addAddress()));
  connect(base->delAddress, SIGNAL(clicked()), SLOT(deleteAddress()));
  connect(base->selector, SIGNAL(activated(int)), this, SLOT(highlighted(int)));
  connect(base->headline, SIGNAL(textChanged(const QString&)),
	  SLOT(headlineChanged(const QString&)));
  connect(base->position, SIGNAL(textChanged(const QString&)),
	   this, SLOT(addressChanged(const QString &)) );
  connect(base->orgdata, SIGNAL(clicked()), SLOT(insinuation()));
  connect(base->street, SIGNAL(textChanged(const QString&)),
	   this, SLOT(addressChanged(const QString &)) );
  connect(base->city, SIGNAL(textChanged(const QString&)),
	   this, SLOT(addressChanged(const QString &)) );
  connect(base->state, SIGNAL(textChanged(const QString&)),
	   this, SLOT(addressChanged(const QString &)) );
  connect(base->zip, SIGNAL(textChanged(const QString&)),
	   this, SLOT(addressChanged(const QString &)) );
  connect(base->country, SIGNAL(textChanged(const QString&)),
	  SLOT(addressChanged(const QString &)) );
  connect(base->deliverylabel, SIGNAL(clicked()), SLOT(deliveryLabel()));
  // ----- create the "choices of address types" menu:
  popupAddresses=new QPopupMenu;
  section=api->addressbook()->configurationSection();
  if(section==0)
    {
      kdDebug() << "TabAddresses ctor: configuration section not available."
		<< endl;
    } else {
      keys=section->getKeys();
      if(keys->get(KEY_ADDRESSTYPES, types))
	{ // WORK_TO_DO: reload menu when configuration changed
	  for(count=0; count<types.count(); ++count)
	    {
	      popupAddresses->insertItem(*types.at(count), count);
	    }
	} else {
	  kdDebug() << "TabAddresses ctor: address types not configured."
		    << endl;
	}
    }
}

void TabAddresses::storeContents(AddressBook::Entry& entry)
{
  if(modified) storeChanges();
  entry.addresses=addresses;
}

void TabAddresses::setContents(const AddressBook::Entry& entry)
{
  currentItem=0;
  addresses=entry.addresses;
  fillSelector();
  fillFields();
}

void TabAddresses::fillSelector()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  // -----
  base->selector->clear();
  for(pos=addresses.begin(); pos!=addresses.end(); ++pos)
    {
      base->selector->insertItem((*pos).headline);
    }
  base->headline->setFocus();
}

std::list<AddressBook::Entry::Address>::iterator TabAddresses::currentAddress()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  int index=currentItem;
  // ----- find the current address:
  if(addresses.size()==0)
    {
      return addresses.end();
    } else {
      if((unsigned int)currentItem>=addresses.size() || currentItem<0)
	{
	  return addresses.end();
	} else {
	  index=currentItem;
	  pos=addresses.begin();
	  advance(pos, index);
	  return pos;
	}
    }
}

void TabAddresses::fillFields()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  QLineEdit **lineedits[]= 
  {
    &(base->street), &(base->zip), &(base->city), &(base->state), 
    &(base->country), &(base->position), &(base->headline)
  };
  int Size=sizeof(lineedits)/sizeof(lineedits[0]);
  int count;
  // ----- find the current address:
  pos=currentAddress();
  // ----- fill the fields:
  if(pos==addresses.end())
    {
      for(count=0; count<Size; ++count)
	{
	  (*lineedits[count])->setEnabled(false);
	  (*lineedits[count])->setText("");
	}
      base->orgdata->setEnabled(false);
      base->deliverylabel->setEnabled(false);
    } else {
      QString *strings[]=
      {
	  &(*pos).address, &(*pos).zip, &(*pos).town,
	  &(*pos).state, &(*pos).country, &(*pos).position,
	  &(*pos).headline
      };
      for(count=0; count<Size; ++count)
	{
	  (*lineedits[count])->setEnabled(true);
	  (*lineedits[count])->setText(*strings[count]);
	}
      base->orgdata->setEnabled(true);
      base->deliverylabel->setEnabled(true);
    }
}

void TabAddresses::storeChanges()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  QLineEdit **lineedits[]= 
  {
    &(base->street), &(base->zip), &(base->city), &(base->state), 
    &(base->country), &(base->position), &(base->headline)
  };
  int Size=sizeof(lineedits)/sizeof(lineedits[0]);
  int count;
  // ----- find the current address:
  pos=currentAddress();
  // ----- store the fields:
  if(pos!=addresses.end())
    {
      QString *strings[]=
      {
	  &(*pos).address, &(*pos).zip, &(*pos).town,
	    &(*pos).state, &(*pos).country, &(*pos).position, &(*pos).headline
      };
      for(count=0; count<Size; ++count)
	{
	  *strings[count]=(*lineedits[count])->text();
	}
    }
}

void TabAddresses::addAddress()
{
  int index;
  AddressBook::Entry::Address address;
  // -----
  if(modified) storeChanges();
  if(popupAddresses->count()>0)
    {
      index=popupAddresses->exec
 	(base->newAddress->mapToGlobal
	 (QPoint(0, base->newAddress->height())));
      if(index>=0)
	{
	  address.headline=popupAddresses->text(index);
	} else {
	  return;
	}
    } else {
      KMessageBox::information
	(this,
	 i18n("<qt>Did you know that you may predefine types of addresses?<br>"
	      "See <b>Edit->Configure this file</b>.</qt>"),
	 i18n("A note"),
	 "kab_note_address_types");
    }
  addresses.push_back(address);
  fillSelector();
  base->selector->setCurrentItem(base->selector->count()-1);
  currentItem=base->selector->currentItem();
  fillFields();
  addressChanged();
}

void TabAddresses::deleteAddress()
{
  int index;
  std::list<AddressBook::Entry::Address>::iterator pos;
  // -----
  if(addresses.size()==0)
    {
      KNotifyClient::beep();
      return;
    }
  if(KMessageBox::questionYesNo
     (this, i18n("Really delete this address?"),
      i18n("Question"))==KMessageBox::Yes)
    {
      index=base->selector->currentItem();
      if(index<0)
	{
	  KNotifyClient::beep();
	  return;
	}
      base->selector->removeItem(index);
      pos=addresses.begin();
      advance(pos, index);
      addresses.erase(pos);
      fillSelector();
      if(base->selector->count()>0)
	{
	  base->selector->setCurrentItem(QMAX(base->selector->count()-1, index));
	}
      fillFields();
    } else {
      KNotifyClient::beep();
    }
}

void TabAddresses::highlighted(int index)
{
  kdDebug() << "TabAddresses::highlighted: " << index << " (was " << currentItem << ")." << endl;
  if(modified)
    {
      storeChanges();
      modified=false;
    }
  currentItem=base->selector->currentItem();
  fillFields();
  base->headline->setText(base->selector->currentText());
  base->headline->setFocus();
  // modified=false; // after selection, changed has been signaled!
}

void TabAddresses::addressChanged()
{
  modified=true;
  emit(changed());
}

void TabAddresses::headlineChanged(const QString &text)
{
  modified=true;
  emit(changed());
  base->selector->changeItem(text, currentItem);
  base->selector->update();
}

void TabAddresses::addressChanged(const QString &)
{
  addressChanged();
}

void TabAddresses::insinuation()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  KDialogBase dialog
    (this, "InsinuationDialog", true, i18n("Insinuation"),
     KDialogBase::Ok|KDialogBase::Cancel,
     KDialogBase::Ok, true);
  InsinuationDialog in(&dialog);
  pos=addresses.begin();
  advance(pos, currentItem);
  in.setFields(*pos);
  dialog.setMainWidget(&in);
  if(dialog.exec())
    {
      in.getFields(*pos);
      emit(changed());
    } else {
    }
}

void TabAddresses::deliveryLabel()
{
  std::list<AddressBook::Entry::Address>::iterator pos;
  KDialogBase dialog
    (this, "DeliveryLabelDialog", true, i18n("Delivery label"),
     KDialogBase::Ok|KDialogBase::Cancel,
     KDialogBase::Ok, true);
  DeliveryLabelWidget widget(&dialog);
  // ----
  pos=addresses.begin();
  advance(pos, currentItem);
  widget.mleDelivLabel->setText((*pos).deliveryLabel);
  dialog.setMainWidget(&widget);
  if(dialog.exec())
    {
      (*pos).deliveryLabel=widget.mleDelivLabel->text();;
      emit(changed());
    } else {
    }
}
	
#include "look_edit_tabaddresses.moc"
