/***************************************************************************
 begin                : Thu Sep 5 2002
 copyright            : (C) 2002 by Christian Hubinger
 email                : chubinger@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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "kmfprocout.h"

// KDE includes
#include <klocale.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <kpushbutton.h>


// QT includes
#include <qtextbrowser.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qpixmap.h>

KMFProcOut::KMFProcOut( QWidget *parent, const char *name, WFlags fl ) : QWidget( parent, name, fl ) {
	stderrbuf = new QString( "" );
	stdoutbuf = new QString( "" );
	m_job_name = "UNDEFINED";
	childproc = new KShellProcess( "/bin/sh" );
	connect( childproc, SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, SLOT( slotReceivedOutput( KProcess*, char*, int ) ) );
	connect( childproc, SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, SLOT( slotReceivedError( KProcess*, char*, int ) ) );
	connect( childproc, SIGNAL( processExited( KProcess* ) ), this, SLOT( slotProcessExited( KProcess* ) ) ) ;
	initGUI();
	hide();
	kdDebug() << "KMFProcOut: Finished initialisation." << endl;
}

KMFProcOut::~KMFProcOut() {
	delete childproc;
}

void KMFProcOut::initGUI() {
	KIconLoader * loader = KGlobal:: iconLoader();
	QString icon_name;

	icon_name = "stop";
	icon_stop = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "quit";
	icon_close = loader->loadIcon( icon_name, KIcon::Small );

	m_layout = new QGridLayout( this, 0, 0, 2, 2, "layout" );

	m_lbview = new QTextBrowser( this, "m_lbview" );
	m_lbview->setTextFormat( RichText );

	m_ljob_name = new QLabel( this, "m_ljob_name" );
	QFont ljob_name_font( m_ljob_name->font() );
	ljob_name_font.setBold( TRUE );
	m_ljob_name->setFont( ljob_name_font );
	m_ljob_name->setFrameShape( QLabel::StyledPanel );
	m_ljob_name->setFrameShadow( QLabel::Sunken );
	m_ljob_name->setText( i18n( "Nothing to do yet..." ) );

	m_bkill = new KPushButton( icon_stop, i18n( "Kill Process" ) , this, "m_bkill" );
	m_bkill->setEnabled( false );
	connect( m_bkill, SIGNAL( clicked() ), this, SLOT( slotKillJob() ) );

	m_layout->addMultiCellWidget( m_ljob_name, 0, 0, 0, 9 );
	m_layout->addMultiCellWidget( m_bkill, 0, 0, 9, 10 );
	m_layout->addMultiCellWidget( m_lbview, 1, 1, 0, 10 );
}


void KMFProcOut::runCmd( const QString& cmd, const QString& job_name ) {
	kdDebug() << "KMFProcOut::runCmd(QString& cmd)"/* << cmd */<< endl;
// 	kdDebug() << "cmd: " << cmd << endl;
	show();
// 	raise();
	m_lbview->clear();
	m_lbview->setTextFormat( RichText );
	m_ljob_name->setText( i18n( "Running: %1" ).arg( job_name ) );
	m_job_name = job_name;
	prepareJob( cmd );
	startJob();

}

void KMFProcOut::prepareJob( const QString &dir ) {
	childproc->clearArguments();
	*childproc << dir;
}

void KMFProcOut::startJob() {
	m_bkill->setEnabled( true );
	childproc->start( KProcess::NotifyOnExit, KProcess::AllOutput );
}

void KMFProcOut::slotKillJob() {
	kdDebug() << "void KMFProcOut::killJob()" << endl;
	childproc->kill();
}

bool KMFProcOut::isRunning() {
	return childproc->isRunning();
}

void KMFProcOut::slotReceivedOutput( KProcess *, char *buffer, int buflen ) {
	// Flush stderr buffer
	if ( !stderrbuf->isEmpty() ) {
		insertStderrLine( *stderrbuf );
		stderrbuf = new QString( "" );
	}

	*stdoutbuf += QString::fromLatin1( buffer, buflen );
	int pos;
	while ( ( pos = stdoutbuf->find( '\n' ) ) != -1 ) {
		QString line = stdoutbuf->left( pos );
		insertStdoutLine( line );
		stdoutbuf->remove
		( 0, pos + 1 );
	}
}

void KMFProcOut::slotReceivedError( KProcess *, char *buffer, int buflen ) {
	// Flush stdout buffer
	if ( !stdoutbuf->isEmpty() ) {
		insertStdoutLine( *stdoutbuf );
		stdoutbuf = new QString( "" );
	}

	*stderrbuf += QString::fromLatin1( buffer, buflen );
	int pos;
	while ( ( pos = stderrbuf->find( '\n' ) ) != -1 ) {
		QString line = stderrbuf->left( pos );
		insertStderrLine( line );
		stderrbuf->remove
		( 0, pos + 1 );
	}
}

void KMFProcOut::slotProcessExited( KProcess * ) {
	kdDebug() << "KMFProcOut::slotProcessExited()" << endl;
	emit processExited( childproc );
	childFinished( childproc->normalExit(), childproc->exitStatus() );
	return ;
}

void KMFProcOut::insertStdoutLine( const QString &line ) {
	m_lbview->append( line + "" );
}

void KMFProcOut::insertStderrLine( const QString &line ) {
	const QString & line2 = i18n( "<b>Error:</b> %1" ).arg( line );
	m_lbview->append( "<font color=\"red\">" + line2 + "</font>" );
}

void KMFProcOut::childFinished( bool , int status ) {
	QString stat;
	stat.setNum( status );
	const QString& job_name = m_job_name;
	if ( status != 0 ) {
		m_lbview->append( i18n( "<br><font color=\"red\"><b>Execution failed</b></font>" ) );
		m_lbview->append( i18n( "<font color=\"red\"><b>Exit(Code): %1</b></font>" ).arg( stat ) );
		emit sigJobFinished( false, job_name );
	} else {
		m_lbview->append( i18n( "<br><b>Finished successfully</b>" ) );
		emit sigJobFinished( true, job_name );
	}
	m_bkill->setEnabled( false );
	kdDebug() << "childFinished" << endl;
	return ;
}

void KMFProcOut::setText( const QString& str ) {
	kdDebug() << "void KMFProcOut::setText(const QString& text)" << endl;
// 	kdDebug() << "Text: " << str << endl;
	QString *text = new QString( str );
	m_ljob_name->setText( i18n( "Show firewall script..." ) );
	m_lbview->clear();
	m_lbview->setTextFormat( PlainText );
	int pos;
	while ( ( pos = text->find( '\n' ) ) != -1 && !text->isEmpty() ) {
		QString line = text->left( pos );
		insertStdoutLine( line );
		text->remove
		( 0, pos + 1 );
	}
}


#include "kmfprocout.moc"
