/***************************************************************************
 *   Copyright (C) 2005 by Nicolas Ternisien                               *
 *   nicolas.ternisien@gmail.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.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

//TQt includes
#include <tqstringlist.h>
#include <tqdatetime.h>
#include <tqobject.h>

#include <tqpainter.h>
#include <tqpen.h>
#include <tqclipboard.h>
#include <tqcolor.h>

//KDE includes
#include <klocale.h>
#include <kmessagebox.h>
#include <kdebug.h>
//For compatibility with old versions of KDE
#include <kdeversion.h>

//Project includes
#include "itemFactory.h"
#include "parentLogLine.h"
#include "logMode.h"
#include "ksystemlogConfig.h"


#include "logListItem.h"


LogListItem::LogListItem(TQListView* list, LogLine* l) :
	KListViewItem(list),
	line(l)
	{

}

LogListItem::LogListItem(TQListViewItem* parent, LogLine* l) :
	KListViewItem(parent),
	line(l)
	{

}


LogListItem::~LogListItem() {

}

TQString LogListItem::getFormattedText() {
	return(ItemFactory::createFormattedText(line));
}

TQString LogListItem::getToolTipText() {
	return(ItemFactory::createToolTipText(line));
}

LogLine* LogListItem::getLogLine() {
	return(line);
}

int LogListItem::compare(TQListViewItem* it, int col, bool ascending) const {

	if (col==0) {
		
		LogListItem* item=dynamic_cast<LogListItem*> (it);
		if (item!=NULL) {

			if (line->getTime() < item->getTime())
				return(-1);
			else if (line->getTime() == item->getTime())
				return(0);
			else
				return(1);
		}
		
		return(1);
	}
	else {
		return(TQListViewItem::compare(it, col, ascending));
	}
}

TQDateTime& LogListItem::getTime() {
	return(line->getTime());
}


TQString LogListItem::exportToText() {
	int columnCount=listView()->columns();
	
	TQString exporting;
	
	if (columnCount==0)
		return(exporting);

	int i=0;
	while(i<columnCount) {
		if (i>0) {
			exporting.append('\t');
		}
		
		exporting.append(this->text(i));
		
		i++;
	}
	
	return(exporting);
}

/**
 * Method inspired from a paintCell method of Amarok.
 * Many thanks for the team (and the GPL, of course!)
 * TODO Retest this method
 */

void LogListItem::paintCell(TQPainter* p, const TQColorGroup& cg, int column, int width, int align) {
	/* For debugging
	KListViewItem::paintCell( p, cg, column, width, align );
	return;
	*/
	
	//Get the KListView item
	KListView* lv = (KListView *) listView();
	if (lv==NULL) {
		kdDebug() << "LogListItem::paintCell() : KListView null" << endl;
		KListViewItem::paintCell( p, cg, column, width, align );
		return;
	}
	
	//flicker-free drawing
	static TQPixmap buffer;
	buffer.resize(width, height());

	//If there is a problem, let KListViewItem class draw this item
	if( buffer.isNull() ) {
		kdDebug() << "LogListItem::paintCell() : TQPixmap null" << endl;
		KListViewItem::paintCell(p, cg, column, width, align);
		return;
	}

	//kdDebug() << "LogListItem::paintCell() : Painting the cell" << endl;
	
	//Initialize our drawing object
	TQPainter pBuf( &buffer, true );
	
	
	//Use or not an alternate background
#if defined(KDE_MAKE_VERSION) && KDE_VERSION >= KDE_MAKE_VERSION(3,4,0)
	if (line->isParentLogLine()==true && column==0)
		pBuf.fillRect( buffer.rect(), isSelected() ? cg.highlight() : cg.highlight() );
	else
		pBuf.fillRect( buffer.rect(), isSelected() ? cg.highlight() : backgroundColor(column) );
#else
	pBuf.fillRect( buffer.rect(), isSelected() ? cg.highlight() : backgroundColor() );
#endif


	//Change the pen color
	pBuf.setPen(cg.button());
	
	//Draw a line at the right
	pBuf.drawLine(width-1, 0, width-1, height());

	//Gets the current font and font metric
	TQFont font(p->font());
	TQFontMetrics fm(p->fontMetrics());
	

	if (line->isParentLogLine()==true && column==0) {
		//Draw 3 gray lines around the parent item
		pBuf.setPen(cg.button());
		pBuf.drawLine(0, 0, width, 0);
		pBuf.drawLine(0, height()-1, width, height()-1);
		//if (column==0) {
			pBuf.drawLine(width-1, 0, width-1, height()-1);
			pBuf.drawLine(0, 0, 0, height()-1);
		//}
	}


	
	//Draw the item name in bold if it is a recent one
	if (line->isRecent()==true && column==lv->columns()-1)
		font.setBold(true);
	//Draw in italic and bold if it's a parent item
	else if (line->isParentLogLine()==true && column==0) {
		font.setItalic(true);
		font.setBold(true);
	}
	//Normal drawing
	else
		font.setBold(false);
	
	
	pBuf.setFont(font);
	TQFontMetrics fmName(font);
	
	//Draw the pixmap m_loadingPix
	if (pixmap(column)) {
		pBuf.drawPixmap( (lv->treeStepSize() - pixmap(column)->width())/2,
							(height() - pixmap(column)->height())/2,
							*pixmap(column) );
	}
	
	int text_x;
	if (column==0)
		text_x=lv->treeStepSize() + 3;
	else
		text_x=1;
	
	
	//If this is the first column and also a parent log line
	if (line->isParentLogLine()==true && column==0) {
		if (KSystemLogConfig::colorizeLogLines() && ((ParentLogLine*)line)->getGroupBy()==GROUP_BY_LOG_LEVEL)
			pBuf.setPen( isSelected() ? cg.text() : line->getLogLevel()->color);
		else
			pBuf.setPen( isSelected() ? cg.text() : cg.highlightedText());
	}
	//If this is the last column and the colorizeLogLines options is enabled
	else if (KSystemLogConfig::colorizeLogLines() && column==lv->columns()-1) {
		pBuf.setPen( isSelected() ? cg.highlightedText() : line->getLogLevel()->color );
	}
	//Normal line
	else {
		pBuf.setPen( isSelected() ? cg.highlightedText() : cg.text() );
	}
	
	TQString name = text(column);
	if( fmName.width(name) + text_x + lv->itemMargin()*2 > width ) {
		int ellWidth = fmName.width( "..." );
		TQString text = TQString::fromLatin1("");
		int i = 0;
		int len = name.length();
		while ( i < len && fmName.width( text + name[ i ] ) + ellWidth < width - text_x - lv->itemMargin()*2  ) {
			text += name[ i ];
			i++;
		}
		name = text + "...";
	}

	int textHeight = fm.lineSpacing() + lv->itemMargin() + 1;
	
	pBuf.drawText( text_x, 0, width, textHeight, AlignVCenter, name );
	
	//End the draw
	pBuf.end();
	p->drawPixmap( 0, 0, buffer );

}


/* Amarok source code
bool detailedView = PlaylistBrowser::instance()->viewMode() == PlaylistBrowser::DetailedView;

//flicker-free drawing
static TQPixmap buffer;
buffer.resize( width, height() );

if( buffer.isNull() ) {
	KListViewItem::paintCell( p, cg, column, width, align );
	return;
}

TQPainter pBuf( &buffer, true );
// use alternate background
pBuf.fillRect( buffer.rect(), isSelected() ? cg.highlight() : backgroundColor() );

if( detailedView ) {
	// draw a line at the top
	pBuf.setPen( cg.text() );
	pBuf.drawLine( 0, 0, width, 0 );
}

KListView *lv = (KListView *)listView();

TQRect rect( ((lv->treeStepSize()-9) / 2) + 1, (height()-9) / 2, 9, 9 );

if( m_loading && m_loadingPix ) {
	pBuf.drawPixmap( (lv->treeStepSize() - m_loadingPix->width())/2,
							(height() - m_loadingPix->height())/2,
							*m_loadingPix );
}
else if( m_trackCount ) {
	//draw +/- symbol to expande/collapse the playlist

		pBuf.setPen( cg.mid() );
		pBuf.drawRect( rect );
		//fill the rect with base color if the item has alternate color and viceversa
		TQColor color = backgroundColor() == lv->alternateBackground() ? cg.base() : lv->alternateBackground();
		pBuf.fillRect( rect.x()+1, rect.y()+1, rect.width()-2, rect.height()-2, color );
		// +/- drawing
		pBuf.setPen( cg.text() );
		pBuf.drawLine( rect.x()+2, rect.y()+4, rect.x()+6, rect.y()+4 );
		if( !isOpen() )
			pBuf.drawLine( rect.x()+4, rect.y()+2, rect.x()+4, rect.y()+6 );
}

TQFont font( p->font() );
TQFontMetrics fm( p->fontMetrics() );

// Use underlined font for "Current Playlist"
if ( m_url.protocol() == "cur" )
	font.setUnderline( true );

// Use italic font for "Cool-Streams"
if ( text( 0 ) == "Cool-Streams" )
	font.setItalic( true );

int text_x = lv->treeStepSize() + 3;
int textHeight = detailedView ? fm.lineSpacing() + lv->itemMargin() + 1 : height();
pBuf.setPen( isSelected() ? cg.highlightedText() : cg.text() );

//if the playlist has been modified a save icon is shown
if( m_modified && m_savePix ) {
	pBuf.drawPixmap( text_x, (textHeight - m_savePix->height())/2, *m_savePix );
	text_x += m_savePix->width()+4;
} else if( pixmap(0) ) {
	int y = (textHeight - pixmap(0)->height())/2;
	if( detailedView ) y++;
	pBuf.drawPixmap( text_x, y, *pixmap(0) );
	text_x += pixmap(0)->width()+4;
}

// draw the playlist name in bold
font.setBold( PlaylistBrowser::instance()->viewMode() == PlaylistBrowser::DetailedView );
pBuf.setFont( font );
TQFontMetrics fmName( font );

TQString name = text(0);
if( fmName.width( name ) + text_x + lv->itemMargin()*2 > width ) {
		int ellWidth = fmName.width( "..." );
		TQString text = TQString::fromLatin1("");
		int i = 0;
		int len = name.length();
		while ( i < len && fmName.width( text + name[ i ] ) + ellWidth < width - text_x - lv->itemMargin()*2  ) {
			text += name[ i ];
			i++;
		}
		name = text + "...";
	}

	pBuf.drawText( text_x, 0, width, textHeight, AlignVCenter, name );

	if( detailedView ) {
		TQString info;

		text_x = lv->treeStepSize() + 3;
		font.setBold( false );
		pBuf.setFont( font );

		if ( m_url.protocol() != "cur" )
		{
			if( m_loading )
					info = i18n( "Loading..." );
			else
			{	  //playlist loaded
					// draw the number of tracks and the total length of the playlist
					info += i18n("1 Track", "%n Tracks", m_trackCount);
					if( m_length )
						info += TQString(" - [%2]").arg( MetaBundle::prettyTime( m_length ) );
			}

			pBuf.drawText( text_x, textHeight, width, fm.lineSpacing(), AlignVCenter, info);
		}
	}

	pBuf.end();
	p->drawPixmap( 0, 0, buffer );
	*/
