/* This file implements the business card look.
 *
 * the KDE addressbook
 * copyright:  (C) Mirko Sucker, 1998, 1999, 2000
 * mail to:    Mirko Sucker <mirko@kde.org>
 * requires:   recent C++-compiler, at least Qt 2.0
 
 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., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.
 
 * $Revision: 1.9 $
 */

#include "look_businesscard.h"
#include <qstringlist.h>
#include <qpixmap.h>
#include <qpainter.h>
#include <qcombobox.h>
#include <qtooltip.h>
#include <klocale.h>
#include <kdebug.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)));
  resize(310, 160);
}

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!";
	}
    }
  // ----- 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(current.birthday.toString()),
	     Grid+p.fontMetrics().ascent(), current.birthday.toString());
	}
      // ----- 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(mailURLActivated());
  emit(sendEmail(url));
}

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

void KABBusinessCard::setEntry(const AddressBook::Entry& e)
{
  QStringList strings;
  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);
}

  

