/***************************************************************************
                          kbearlogview.cpp  -  description
                             -------------------
    begin                : sön feb 10 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

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


//////////////////////////////////////////////////////
// Qt specific includes
#include <qvaluelist.h>
#include <qdir.h>
#include <qfileinfo.h>
#include <qdatetime.h>
#include <qtextstream.h>
//////////////////////////////////////////////////////
// KDE specific includes
#include <kdebug.h>
#include <kglobal.h>
#include <kconfig.h>
//////////////////////////////////////////////////////
// Application specific includes
#include "kbearlogview.h"
#include "kbearchildviewiface.h"
#include "misc.h"

#include "kbearlogview.moc"

using namespace KBear;

//-----------------------------------------------
KBearLogView::KBearLogView( KConfig* config, QWidget *parent, const QString& name )
	: QTabWidget/*KBearTabView*/( parent, name.latin1() )
{
	m_config = config;
	initValues();
	m_logFiles.setAutoDelete( true );
	m_logStreams.setAutoDelete( true );
	m_sites.setAutoDelete( true );
	m_tabs.setAutoDelete( true );
}
//-----------------------------------------------
KBearLogView::~KBearLogView(){
}
//-----------------------------------------------
void KBearLogView::slotAddPage( const SiteInfo& info ) {
	if( ! info.enableLog() )
		return;
	//Check if we already have atab with the specified label
	// If it already exists we do nothing
	for( int i = 0; i < count(); i++ ) {
		QString lbl = tabLabel( page( i ) );
		if( lbl == info.label() )
			return;
	}

	KBearTextEdit* w = new KBearTextEdit( this, info.label() );
	w->setCurrentFont( m_font );
	w->setReadOnly( true );
	m_tabs.insert( info.ID(), w );
	addTab( w, info.label() );
	showPage( w );
	m_sites.insert( info.ID(), new SiteInfo( info ) );
	if( m_enableFileLog ) {
		QDir dir( m_logFilePath );
		if( ! dir.exists() ) {
			dir.mkdir( m_logFilePath );
		}
		QFile* file = new QFile( m_logFilePath + info.label() + QString::fromLatin1(".log") );

		maybeDeleteLogFile( *file, m_overWriteFileLog );

		int mode = IO_ReadWrite;
		mode |= IO_Append;
		file->open( mode );
		m_logFiles.insert( info.ID(), file );
		QTextStream* stream = new QTextStream( file );
		m_logStreams.insert( info.ID(), stream );
	}
}
//-----------------------------------------------
void KBearLogView::maybeDeleteLogFile( const QFile& file, unsigned int intervall ) {
	if( ! file.exists() )
		return;

	QFileInfo info( file );
	QDateTime created = info.created();
	int days = created.daysTo( QDateTime::currentDateTime() );
	bool removeFile = false;
	switch( intervall ) {
		case KBear::DAY: {
			if( days > 0 )
				removeFile = true;
			break;
		}
		case KBear::WEEK: {
			if( days > 7 )
				removeFile = true;
			break;
		}
		case KBear::MONTH: {
			if( days > 30 )
				removeFile = true;
			break;
		}
		default: { //e.g NEVER
			break;
		}
	};
	if( removeFile )
		QFile::remove( file.name() );
}
//-----------------------------------------------
void KBearLogView::slotRemovePage( int ID ) {
	if( ID < 0 )
		return;
	QWidget* w = m_tabs.find( ID );
	if( w == currentPage() && count() > 1 ) {
		QTabWidget::removePage( w );
		setCurrentPage( 0 );
	}
	else
		QTabWidget::removePage( w );
	
	m_tabs.remove( ID ); // this will also delete the widget

	m_sites.remove( ID );
	if( m_enableFileLog ) {
		m_logStreams.remove( ID );
		m_logFiles.remove( ID );
	}
}
//-----------------------------------------------
void KBearLogView::slotLogMessage( int ID, const QString& message ){
	static const QString& respString = KGlobal::staticQString( "resp" );
	static const QString& commandString = KGlobal::staticQString( "command" );
	static const QString& multiString = KGlobal::staticQString( "multi-line" );
	static const QString& internalString = KGlobal::staticQString( "internal" );

	QWidget* w = m_tabs.find( ID );
	if( ! w )
		return;
	SiteInfo* site = m_sites.find( ID );
	if( ! site || ! site->enableLog() ) 
		return;
/*
	int tabNr = indexOf( w );
	if( tabNr == -1 ) {
		return;
	}
*/ 	
	KBearTextEdit* tEdit = static_cast<KBearTextEdit*>( w );
	QString tmp;
	if( message.left( respString.length() ) == respString && m_showServerCommand ) {
		tEdit->setColor( m_responseColor );
		tmp = message.mid( 5, message.length() );
	}
	else if( message.left( commandString.length() ) ==commandString && m_showClientCommand ) {
		tEdit->setColor( m_commandColor );
		tmp = message.mid( 8, message.length() );
	}
	else if( message.left( multiString.length() ) == multiString && m_showServerCommand ) {
		tEdit->setColor( m_multiLineColor );
		tmp = message.mid( 11, message.length() );
	}
	else if( message.left( internalString.length() ) == internalString && m_showClientCommand ) {
		tEdit->setColor( "black" );
		tmp = message.mid( 8, message.length() );
	}
	else if( site->protocol() != "kbearftp" && m_showClientCommand ){
		tEdit->setColor( "black" );
		tmp = message;
	}
	else // not a logmessage
		return;

	
	// hack to be sure the line breaks, for some reason they don't on some systems ?
	if( tmp.right( 1 ) == "\r" )
		tmp = tmp.left( tmp.length() );
	else if( tmp.right( 2 ) == "\r\n" )
		tmp = tmp.left( tmp.length() - 2 );
	if( tmp.right( 1 ) != "\n" )
		tmp += "\n";
	tEdit->append( tmp );
	tEdit->scrollToBottom();
	
	if( m_enableFileLog ) {
		QTextStream* stream = m_logStreams.find( ID );
		if( stream ) {
				(*stream) << tmp << flush; 
		}
	}
}
//-----------------------------------------------
void KBearLogView::slotSetActiveLogTab( KBearChildViewIface* view ) {
	QWidget* w = m_tabs.find( view->siteInfo().ID() );
	if( ! w )
		return;
	
	QTabWidget::showPage( w );
}
//-----------------------------------------------
void KBearLogView::initValues() {
	m_config->setGroup( QString::fromLatin1("LogConfig") );
	QValueList<int> c = m_config->readIntListEntry( QString::fromLatin1("CommandColor") );
	if( c.empty() || c.count() < 3 )
		m_commandColor =QColor( "darkblue" );
	else
		m_commandColor = QColor( c[0], c[1], c[2] );
	
	c = m_config->readIntListEntry( QString::fromLatin1("ResponseColor") );
	if( c.empty() || c.count() < 3 )
		m_responseColor =QColor( "darkred" );
	else
		m_responseColor = QColor( c[0], c[1], c[2] );
	
	c = m_config->readIntListEntry( QString::fromLatin1("MultiLineColor") );
	if( c.empty() || c.count() < 3 )
		m_multiLineColor =QColor( "darkgreen" );
	else
		m_multiLineColor = QColor( c[0], c[1], c[2] );
	
	m_enableFileLog = m_config->readBoolEntry( QString::fromLatin1("EnableFileLog"), false );
	
	m_overWriteFileLog = m_config->readUnsignedNumEntry( QString::fromLatin1("OverWriteLogFile"), KBear::DAY );
	
	m_logFilePath = m_config->readEntry( QString::fromLatin1("LogBasePath"), QDir::homeDirPath() );
	if( m_logFilePath.right( 1 ) != QString::fromLatin1( "/" ) )
		m_logFilePath += QString::fromLatin1("/");
	m_font = m_config->readEntry( QString::fromLatin1("Font") );
	
	m_showClientCommand = m_config->readBoolEntry( QString::fromLatin1("ShowClientCommands"), true );
	
	m_showServerCommand = m_config->readBoolEntry( QString::fromLatin1("ShowServerCommands"), true );
	
	KBearTextEdit* tEdit;
	for( int i = 0; i < count(); i++ ) {
		tEdit = static_cast<KBearTextEdit*>( page( i ) );
		if( tEdit ) {
			tEdit->setCurrentFont( m_font );
		}
	}
}
