/***************************************************************************
                          contactlistviewitem.cpp  -  description
                             -------------------
    begin                : Fri Mar 28 2003
    copyright            : (C) 2003 by Mike K. Bennett
                           (C) 2005 by Diederik van der Boor
    email                : mkb137b@hotmail.com
                           vdboor --at-- codingdomain.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 "contactlistviewitem.h"

#include <qobject.h>
#include <qregexp.h>
#include <qstylesheet.h>

#include <kdebug.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <klocale.h>

#include "kmessdebug.h"
#include "currentaccount.h"
#include "contact/contact.h"
#include "emoticoncollection.h"

#ifdef KMESSDEBUG_CONTACTLISTVIEWITEM
#define KMESSDEBUG_CONTACTLISTVIEWITEM_GENERAL
#endif


// The constructor
ContactListViewItem::ContactListViewItem(QListView *parent, Contact *contact)
 : QObject(0, "listItem"),
   KMessListViewItem( parent ),
   contact_(contact),
   italicIdentifier_(false),
   onlineStatus_(0)
{
  // Do general construction
  construct();
}



// The constructor
ContactListViewItem::ContactListViewItem(QListViewItem *parent, Contact *contact)
 : QObject(0, "listItem"),
   KMessListViewItem( parent ),
   contact_(contact),
   italicIdentifier_(false),
   onlineStatus_(0)
{
  // Do general construction
  construct();
}



// // Compare
// int ContactListViewItem::compare( QListViewItem *item, int col, bool asc) const
// {
// #ifdef KMESSTEST
//   ASSERT( dynamic_cast<KMessListViewItem *>(item) != 0 );
// #endif
// 
//   ContactListViewItem *that;
// 
//   int thatType = static_cast<KMessListViewItem *>(item) -> getType();
//   int result   = 0;
//   int first    = 0;
//   int second   = 0;
// 
// 
//   // Determine the sorting based on the object type.
//   if(thatType == LISTTYPE_CONTACT)
//   {
// #ifdef KMESSTEST
//     ASSERT( dynamic_cast<ContactListViewItem *>(item) != 0 );
// #endif
// 
//     that = static_cast<ContactListViewItem *>(item);
// 
//     QString thisId = this->identifier_.lower();
//     QString thatId = that->identifier_.lower();
// 
//     first  = that->onlineStatus_ - this->onlineStatus_;
//     second = thisId.localeAwareCompare( thatId );
// 
//     // Determine the sorting
//                     result = first;
//     if(result == 0) result = second;
//   }
//   else
//   {
//     // Groups
//     result = KMessListViewItem::compare(item, col, asc);
//   }
// 
// 
// 
//   // Return the correct value for the sorting algorithm.
//   if(result < 0) return -1;  // "this" is smaller then "that"
//   if(result > 0) return 1;   // "this" is greater then "that"
//   return 0;                  // "this" and "that" are equal.
// }



// Do general construction
void ContactListViewItem::construct()
{
  emoticons_ = EmoticonCollection::instance();

  // Visibility depends on whether or not allowed and removed contacts are shown.
  CurrentAccount *currentAccount = CurrentAccount::instance();

  // Connect account signals
  connect(currentAccount, SIGNAL(changedViewMode()),        this, SLOT(slotUpdateVisiblity()) );
  connect(currentAccount, SIGNAL(changedDisplaySettings()), this, SLOT(slotUpdateVisiblity()) );

  // Connect contact signals
  connect(contact_, SIGNAL(changedFriendlyName()),         this, SLOT(slotUpdateFriendlyName())            );
  connect(contact_, SIGNAL(changedStatus()),               this, SLOT(slotUpdateStatus())                  );
  connect(contact_, SIGNAL(changedList(Contact*)),         this, SLOT(slotUpdateStatus())                  );
  // changedList() is not connected to slotUpdateVisability because the "blocked" icon should also appear.

  // Call the event manually this time, to update the appearance.
  slotUpdateStatus();
  slotUpdateVisiblity();
}



// Return the contact
Contact * ContactListViewItem::getContact() const
{
  return contact_;
}



// Return the type ID
int ContactListViewItem::getType() const
{
  return LISTTYPE_CONTACT;
}



// Update the friendly name
void ContactListViewItem::slotUpdateFriendlyName()
{
  identifier_ = contact_->getFriendlyName();
  updateItemText();
}



// Update the appearance of the contact as it's status changes
void ContactListViewItem::slotUpdateStatus()
{
  KIconLoader  *loader  = KGlobal::iconLoader();
  KStandardDirs *dirs   = KGlobal::dirs();

  QString       msnStatus = contact_->getStatus();
  QString       iconName  = "online";
  QString       iconPath;


  // Update the status identifier.
  if(contact_->isBlocked())
  {
    // Show blocked regardless of status
    statusIdentifier_ = i18n( "Blocked" );
    iconName          = "blocked";
    onlineStatus_     = ( msnStatus != "FLN" ) ? 2 : 0;
  }
  else if(msnStatus == "AWY")
  {
    statusIdentifier_ = i18n( "Away" );
    iconName          = "away";
    onlineStatus_     = 1;
  }
  else if(msnStatus == "BRB")
  {
    statusIdentifier_ = i18n( "Be Right Back" );
    iconName          = "berightback";
    onlineStatus_     = 1;
  }
  else if(msnStatus == "BSY")
  {
    statusIdentifier_ = i18n( "Busy" );
    iconName          = "busy";
    onlineStatus_     = 1;
  }
  else if(msnStatus == "FLN")
  {
    statusIdentifier_ = "";
    iconName          = "offline";
    onlineStatus_     = 2;
  }
  else if(msnStatus == "IDL")
  {
    statusIdentifier_ = i18n( "Away - Idle" );
    iconName          = "away";
    onlineStatus_     = 1;
  }
  else if(msnStatus == "LUN")
  {
    statusIdentifier_ = i18n( "Out to Lunch" );
    iconName          = "lunch";
    onlineStatus_     = 1;
  }
  else if(msnStatus == "NLN")
  {
    statusIdentifier_ = "";
    iconName          = "online";
    onlineStatus_     = 0;
  }
  else if(msnStatus == "PHN")
  {
    statusIdentifier_ = i18n( "On the Phone" );
    iconName          = "onthephone";
    onlineStatus_     = 1;
  }
  else
  {
    statusIdentifier_ = "";
    onlineStatus_     = 2;
    kdDebug() << "Contact - '" << msnStatus << "' is not a valid status for contact " << contact_->getHandle() << "." << endl;
  }


  // Find the path to the given icon
  iconPath = dirs->findResource("data", "kmess/pics/" + iconName + ".png");
  if(iconPath.isEmpty())
  {
    // Not found?  Try KDE standard icons
    iconPath = loader->iconPath(iconName, KIcon::Small, false);
  }


  // Update
  italicIdentifier_ = (! contact_->isReverse());
  identifier_       = contact_->getFriendlyName();
  iconTag_          = "<img align=left src=\"" + iconPath + "\">";


  // Set the sort text
  // FIXME: remove this if the "QListViewItem::compare" method works.
  setText(0, QString::number(onlineStatus_) + " " + identifier_);

  // Ask parent to re-run the sorting algorithm
  resortParent();

  // Update our appearance.
  updateItemText();

  // Also update the visibility
  slotUpdateVisiblity();
}



// Update the visibility of the contact
void ContactListViewItem::slotUpdateVisiblity()
{
  // Visibility depends on whether or not allowed and removed contacts are shown.
  CurrentAccount *currentAccount = CurrentAccount::instance();

  if(QListViewItem::parent() == 0 && ! currentAccount->getShowContactsByGroup())
  {
    // Hide root items if contacts are shown in online/offline groups.
    setVisible(false);
  }
  else if(contact_->isOffline() && ! currentAccount->getShowOfflineContacts())
  {
    // Hide if online contacts are not shown
    setVisible(false);
  }
  else
  {
    if(contact_->isFriend())
    {
      // Friends should always be visible
      setVisible(true);
    }
    else if(contact_->isAllowed())
    {
      // Whether or not allowed contacts are visible depends on the contact setting
      setVisible( currentAccount->getShowAllowedContacts() );
    }
    else
    {
      // Whether or not removed contacts are visible depends on the contact setting
      setVisible( currentAccount->getShowRemovedContacts() );
    }
  }
}



// Update the item's text
void ContactListViewItem::updateItemText()
{
#ifdef KMESSTEST
  ASSERT( ! identifier_.isEmpty() );
#endif

  QString newIdentifier;
  QString newText;
  QString sortText;

  // Parse the emoticons
  newIdentifier = QStyleSheet::escape(identifier_);
  emoticons_->parseEmoticons(newIdentifier, true);

  // Icon
  newText = iconTag_ + " ";

  // Start italics?
  if(italicIdentifier_)
  {
    newText += "<i>";
  }

  // friendly name
  newText += newIdentifier;

  // End italics?
  if(italicIdentifier_)
  {
    newText += "</i>";
  }

  // Status identifier
  if( ! statusIdentifier_.isEmpty())
  {
    newText += "  (" + statusIdentifier_ + ")";
  }


  setHTMLText(newText);   // Replaces setText(0, "ff") in KMessListViewItem
}

#include "contactlistviewitem.moc"
