/* -*- C++ -*-
   This file implements the business card look.

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

#include "look_businesscard.h"
#include "look_edit.h"
#include <qstringlist.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <qcombobox.h>
#include <qtooltip.h>
#include <klocale.h>
#include <kdebug.h>
#include <kglobal.h>


#define GRID 5

KABBusinessCard::KABBusinessCard(KabAPI* api, QWidget* parent, const char* name)
  : KABBasicLook(api, parent, name),
    tile(false),
    bgColor(lightGray),
    background(0),
    addressCombo(new QComboBox(this)),
    currentAddress(0)
{
  urlEmail=new KURLLabel(this);
  CHECK_PTR(urlEmail);
  urlEmail->setAutoResize(true);
  // urlEmail->setTransparentMode(true);
  urlEmail->setFloat(true);
  urlEmail->setUnderline(false);
  urlEmail->setLineWidth(0);
  urlEmail->setMidLineWidth(0);
  urlHome=new KURLLabel(this);
  CHECK_PTR(urlHome);
  urlHome->setAutoResize(true);
  // urlHome->setTransparentMode(true);
  urlHome->setFloat(true);
  urlHome->setUnderline(false);
  urlHome->setLineWidth(0);
  urlHome->setMidLineWidth(0);
  // -----
  connect(urlEmail, SIGNAL(leftClickedURL(const QString&)),
	  SLOT(mailURLClicked(const QString&)));
  connect(urlHome, SIGNAL(leftClickedURL(const QString&)),
	  SLOT(homeURLClicked(const QString&)));
  connect(addressCombo, SIGNAL(activated(int)),
	  SLOT(addressSelected(int)));
  // ----- find preferred size:
  // Since the business card look does not prefer a size it uses the
  // preferred size of the editing look to avoid flickering resizing.
  KABEditLook *editlook=new KABEditLook(api, this);
  setMinimumSize(editlook->minimumSizeHint());
  // resize(minimumSize()); // is this needed?
  delete editlook;
}

KABBusinessCard::~KABBusinessCard()
{
  if(background!=0) delete background;
}

void KABBusinessCard::resizeEvent(QResizeEvent*)
{
  // ###########################################################################
  addressCombo->setGeometry(GRID, 3*GRID+2*fontMetrics().height(),
			    width()-2*GRID, addressCombo->sizeHint().height());
  // ###########################################################################
}

void KABBusinessCard::paintEvent(QPaintEvent*)
{
  bool backgroundEnabled=false; // WORK_TO_DO: set according to users choice
  // ###########################################################################
  const int Grid=3;
  QFont original, font;
  bool useBackground=false;
  bool drawSeparator=false;
  QPixmap pm(width(), height());
  QPainter p;
  QString temp;
  int posSeparator=0, cy, addressHeight, contactHeight;
  AddressBook::Entry::Address address;
  int nameHeight, bottomHeight, noOfBottomLines=0;
  bool showName, showAddress, showBottom;
  // ----- begin painting:
  p.begin(&pm);
  // ----- decide some style rules, get fonts, get the address:
  if(background!=0)
    {
      if(!background->isNull() && backgroundEnabled==true)
	{
	  useBackground=true;
	}
    } else {
      useBackground=false;
    }
  if(current.noOfAddresses()>0)
    { // if there is none, address simply remains empty
      if(current.getAddress(currentAddress, address)!=AddressBook::NoError)
	{
	  kdDebug() << "AddressBook::paintEvent: address index "
		    << "out of range!" << endl;
	}
    }
  // ----- draw the background:
  if(useBackground)
    {
      QPixmap pm;
      pm=*background;
      p.drawTiledPixmap(0, 0, width(), height(), pm);
    } else {
      p.setPen(bgColor);
      p.setBrush(bgColor);
      p.drawRect(0, 0, width(), height());
      p.setPen(black);
    }
  // ----- now draw on the background:
  original=p.font();
  font.setFamily(original.family());
  font.setPointSize(10);
  p.setFont(font);
  // ----- calculate sizes and decide display contents:
  nameHeight=2*Grid+2*p.fontMetrics().height();
  if(!current.telephone.isEmpty()) noOfBottomLines+=1;
  if(!current.URLs.isEmpty()) noOfBottomLines+=1;
  if(!current.emails.isEmpty()) noOfBottomLines+=1;
  bottomHeight=3*Grid+noOfBottomLines*p.fontMetrics().height();
  addressHeight=height()-nameHeight-bottomHeight;
  showAddress=height()-nameHeight-bottomHeight
    >addressCombo->sizeHint().height()+4*QFontMetrics(original).height();
  showBottom=height()-nameHeight>=bottomHeight;
  showName=height()>=nameHeight;
  //   L("AddressBook::paintEvent: %sshow name,\n"
  //     "                         %sshow address,\n"
  //     "                         %sshow bottom.\n",
  //     showName ? "" : "do not ",
  //     showAddress ? "" : "do not ",
  //     showBottom ? "" : "do not ");
  // ----- now draw the contact lines and labels:
  if(showBottom)
    {
      cy=pm.height()-Grid;
      if(!current.URLs.isEmpty())
	{
	  temp=(QString)"URL: "+current.URLs.first();
	  if(current.URLs.count()>1)
	    {
	      temp+=" [..]";
	    }
	  urlHome->setFont(font);
	  urlHome->setText(temp);
	  urlHome->move(Grid, cy+3-urlHome->height());
	  urlHome->show();
	  cy-=urlHome->height();
	  drawSeparator=true;
	  temp="";
	} else {
	  urlHome->hide();
	}
      if(!current.emails.isEmpty())
	{
	  temp=i18n("email: ")+current.emails.first();
	  if(current.emails.count()>1)
	    {
	      temp+=" [..]";
	    }
	  urlEmail->setFont(font);
	  urlEmail->setText(temp);
	  urlEmail->move(Grid, cy-urlEmail->height()+5);
	  urlEmail->show();
	  cy-=urlEmail->height();
	  drawSeparator=true;
	  temp="";
	} else {
	  urlEmail->hide();
	}
      if(!current.telephone.isEmpty())
	{
	  temp+=i18n("tel: ")+(*current.telephone.at(1))
	    +" ("+(*current.telephone.at(0))+")";
	  if(current.telephone.count()>1)
	    {
	      temp+=" [..]";
	    }
	  p.drawText(Grid, cy, temp);
	  cy-=p.fontMetrics().height();
	  drawSeparator=true;
	  temp="";
	}
      if(drawSeparator)
	{
	  posSeparator=cy;
	  cy-=Grid;
	}
      contactHeight=height()-cy;
      if(drawSeparator)
	{
	  p.drawLine(Grid, posSeparator, pm.width()-Grid, posSeparator);
	}
    } else {
      urlHome->hide();
      urlEmail->hide();
    }
  // (now contactHeight is the actual number of pixels needed)
  if(showName)
    {
      // ----- print the birthday in the upper right corner if it is
      // valid:
      if(current.birthday.isValid())
	{ //       by now I do not take care if there is enough space
	  //       left
          p.drawText
	    (pm.width()-Grid
	     -p.fontMetrics().width
	     (KGlobal::locale()->formatDate(current.birthday)),
	     Grid+p.fontMetrics().ascent(),
	     KGlobal::locale()->formatDate(current.birthday));
	}
      // ----- draw the address, begin on top
      cy=Grid;
      font.setPointSize(12);
      p.setFont(font);
      if(!current.fn.isEmpty())
	{
	  temp=current.fn;
	} else {
	  if(!current.rank.isEmpty())
	    {
	      if(!temp.isEmpty()) temp+=" ";
	      temp+=current.rank;
	    }
	  if(!current.nameprefix.isEmpty())
	    {
	      if(!temp.isEmpty()) temp+=" ";
	      temp+=current.nameprefix;
	    }
	  if(!current.firstname.isEmpty())
	    {
	      if(!temp.isEmpty()) temp+=" ";
	      temp+=current.firstname;
	    }
	  if(!current.middlename.isEmpty())
	    {
	      if(!temp.isEmpty()) temp+=" ";
	      temp+=current.middlename;
	    }
	  if(!current.lastname.isEmpty())
	    {
	      if(!temp.isEmpty()) temp+=" ";
	      temp+=current.lastname;
	    }
	}
      if(!temp.isEmpty())
	{
	  font.setItalic(true);
	  p.setFont(font);
	  p.setPen(blue);
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), temp);
	  font.setItalic(false);
	  p.setFont(font);
	  p.setPen(black);
	  cy+=p.fontMetrics().height();
	}
      if(!current.title.isEmpty())
	{
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), current.title);
	  cy+=p.fontMetrics().height();
	}
    }
  // ----- now draw the address:
  if(showAddress)
    {
      // find starting point:
      cy=addressCombo->y()+addressCombo->height();
      if(!address.position.isEmpty())
	{
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), address.position);
	  cy+=p.fontMetrics().height();
	}
      if(!address.address.isEmpty())
	{
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), address.address);
	  cy+=p.fontMetrics().height();
	}
      temp = "";
      if(!address.town.isEmpty())
	{
	  temp+=address.town;
	}
      if(!address.state.isEmpty())
	{
	  if (!temp.isEmpty()) temp += " ";
	  temp+=address.state;
	}
      if(!address.zip.isEmpty())
	{
	  if (!temp.isEmpty()) temp += " ";
	  temp += address.zip;
	}
      if(!temp.isEmpty())
	{
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), temp);
	  cy+=p.fontMetrics().height();
	}
      if(!address.country.isEmpty())
	{
	  p.drawText(2*Grid, cy+p.fontMetrics().height(), address.country);
	  cy+=p.fontMetrics().height();
	}
      addressHeight=cy+Grid;
      addressCombo->show();
    } else {
      addressCombo->hide();
    }
  // ----- finish painting:
  p.end();
  bitBlt(this, 0, 0, &pm);
  // ###########################################################################
}

void KABBusinessCard::mailURLClicked(const QString& url)
{
  emit(sendEmail(url));
}

void KABBusinessCard::homeURLClicked(const QString& url)
{
  emit(browse(url));
}

void KABBusinessCard::setEntry(const AddressBook::Entry& e)
{
  QStringList strings;
  std::list<AddressBook::Entry::Address>::const_iterator pos;
  unsigned int count;
  // -----
  KABBasicLook::setEntry(e);
  currentAddress=0;
  for(pos=e.addresses.begin(); pos!=e.addresses.end(); ++pos)
    {
      strings.append((*pos).headline);
    }
  addressCombo->clear();
  if(e.noOfAddresses()==0)
    {
      addressCombo->setEnabled(false);
    } else {
      addressCombo->setEnabled(true);
      addressCombo->insertStringList(strings);
    }
  // -----
  /* WORK_TO_DO: enable after making telephone interactive */
  if(e.telephone.count()>0)
    {
      QString text;
      // -----
      for(count=0; 2*count<e.telephone.count(); ++count)
	{
	  text+=(*e.telephone.at(2*count))
	    +" ("+(*e.telephone.at(2*count+1))+")";
	  if(2*(count+1)<e.telephone.count()) text+="\n";
	}
      QToolTip::add(urlEmail, text);
    } else {
      QToolTip::remove(urlEmail);
    }
  // -----
  repaint(false);
}

void KABBusinessCard::addressSelected(int index)
{
  currentAddress=index;
  repaint(false);
}



#include "look_businesscard.moc"
