/* ====================================================================
 * Copyright 2006-2007,     Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "LogLvi.h"
#include "Cancel.h"
#include "sublib/Utility.h"

// qt
#include <QtGui/QPainter>
#include <QtGui/QIconSet>
#include <QtGui/QToolButton>
#include <QtGui/QImage>
#include <Qt3Support/Q3Header>

static const int ColAction  = 0;
static const int ColStatus  = 1;
static const int ColMessage = 2;
static const int ColCancel  = ColMessage;


LogLvi::LogLvi( Q3ListView* parent, const LogData* data )
: super(parent, QString::fromUtf8(data->getAction()), 
  QString::fromUtf8(data->getState()), QString::fromUtf8(data->getMsg())),
  _sortId(Id::next()), _data(data), _stopped(false), _canceled(false),
  _last(NULL), _cancel(NULL)
{
}

LogLvi::LogLvi( Q3ListViewItem* parent, const LogData* data )
: super(parent, QString::fromUtf8(data->getAction()), 
  QString::fromUtf8(data->getState()), QString::fromUtf8(data->getMsg())),
  _sortId(Id::next()), _data(data), _stopped(false), _canceled(false),
  _last(NULL), _cancel(NULL)
{
}

LogLvi::~LogLvi()
{
  //delete _data;
}

// -1  i > this
// 0   i = this
// 1   i < this
int LogLvi::compare( Q3ListViewItem * i, int /*col*/, bool /*ascending*/ ) const
{
  unsigned long sortId = ((LogLvi*)i)->_sortId;

  if( sortId == _sortId )
    return 0;

  if( sortId > _sortId )
    return -1;
  else
    return 1;
}

void LogLvi::paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int alignment )
{
  QColorGroup g(cg);

  //if( _data->getType()column == 1 )
  {
    //g.setColor( QColorGroup::Base, QColor(200,200,200) );
  }
  super::paintCell(p,g,column,width,alignment);
}

unsigned long LogLvi::getId()
{
  return _data->getId();
}

void LogLvi::add( const LogData* data )
{
  if( ! isStopped() )
  {
    // if not stopped, add a new item.

    setText( ColStatus, /*QString::fromUtf8(_data->getState())
      +*/ QString( "\n%1" )
      .arg(QString::fromUtf8(data->getState()) ) );

    setText( ColMessage, QString::fromUtf8(_data->getMsg())
      + QString( "\n%1 %2" )
      .arg( QString::fromUtf8(data->getAction()) )
      .arg( QString::fromUtf8(data->getMsg()) ) );

    _last = new LogLvi( this, data );
  }
  else
  {
    // if stoppped, extend last item.

    _last->setText( ColMessage, _last->text(ColMessage)
      + QString(" %1").arg(QString::fromUtf8(data->getMsg())) );
  }
}

void LogLvi::start()
{
  setMultiLinesEnabled(true);
  setText( ColMessage, QString::fromUtf8(_data->getMsg())
    + QString("\n%1").arg(_q("running...")) );
}

void LogLvi::stop()
{
  _stopped = true;

  setMultiLinesEnabled(false);  

  // hiding/unhiding fixes a redraw bug:
  // sometimes an item still occupies multi line space after disabling
  // multi lines. Strange enough this happens only for non-cancelables.
  setVisible(false);
  setVisible(true);

  if( isCancelable() )
  {
    setPixmap( ColCancel, QPixmap() );
  }

  if( hasError() )
  {
    setPixmap( ColStatus, QPixmap(getIconDir() + "FailedSmall.png") );
  }
  else
  {
    setText( ColStatus, QString::null );
  }

  setText( ColMessage, QString::fromUtf8(_data->getMsg()) );
}

void LogLvi::setCancelable( Cancel* cancel )
{
  _cancel = cancel;
}

bool LogLvi::isCancelable() const
{
  return _cancel != NULL;
}

bool LogLvi::isStopped() const
{
  return _stopped;
}

bool LogLvi::isError() const
{
  return _data->isError();
}

void LogLvi::setCanceled()
{
  _canceled = true;
  setCancelDisabled();
  _cancel->setCanceled();
}

void LogLvi::setCancelNormal()
{
  if( isCancelable() && ! isStopped() && !_canceled )
  {
    setPixmap( ColCancel, QPixmap(getIconDir() + "Cancel-Normal.png") );
  }
}

void LogLvi::setCancelActive()
{
  if( isCancelable() && ! isStopped() && !_canceled )
  {
    setPixmap( ColCancel, QPixmap(getIconDir() + "Cancel-Active.png") );
  }
}

void LogLvi::setCancelDisabled()
{
  if( isCancelable() && ! isStopped() )
  {
    setPixmap( ColCancel, QPixmap(getIconDir() + "Cancel-Disabled.png") );
  }
}

bool LogLvi::isOnCancel( int x )
{
  if( pixmap(ColCancel) == NULL )
  {
    return false;
  }

  int xpos   = listView()->header()->sectionPos(ColCancel);
  int xwidth = pixmap(ColCancel)->width();

  return x >= xpos && x <= (xpos + xwidth);
}

bool LogLvi::hasError()
{
  Q3ListViewItemIterator it(firstChild());
  while( it.current() )
  {
    LogLvi* item = (LogLvi*)it.current();
    if( item->isError() )
    {
      return true;
    }
    ++it;
  }
  return false;
}

void LogLvi::adjustColumns()
{
  listView()->adjustColumn(ColAction);
  listView()->adjustColumn(ColStatus);
  listView()->adjustColumn(ColMessage);
}
