/***************************************************************************
 begin                : Thu Sep 5 2002
 copyright            : (C) 2002 by Christian Hubinger
 email                : chubinger@irrsinnig.org
***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <tqtextbrowser.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqpixmap.h>
#include <tqfont.h>

// Project Includes
#include "../core/xmlnames.h"
namespace KMF {
KMFProcOut::KMFProcOut( TQWidget *parent, const char *name, WFlags fl ) : TQWidget( parent, name, fl ) {
	stderrbuf = new TQString( "" );
	stdoutbuf = new TQString( "" );
	m_job_name = XML::Undefined_Value;
	childproc = new KProcess();
	
	connect( childproc, TQT_SIGNAL( receivedStdout( KProcess*, char*, int ) ), this, TQT_SLOT( slotReceivedOutput( KProcess*, char*, int ) ) );
	connect( childproc, TQT_SIGNAL( receivedStderr( KProcess*, char*, int ) ), this, TQT_SLOT( slotReceivedError( KProcess*, char*, int ) ) );
	connect( childproc, TQT_SIGNAL( processExited( KProcess* ) ), this, TQT_SLOT( slotProcessExited( KProcess* ) ) ) ;
	initGUI();
	hide();
	kdDebug() << "KMFProcOut: Finished initialisation." << endl;
}

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

void KMFProcOut::initGUI() {
	KIconLoader * loader = KGlobal:: iconLoader();
	TQString 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 TQGridLayout( this, 0, 0, 2, 2, "layout" );

	m_lbview = new TQTextBrowser( this, "m_lbview" );
	m_lbview->setTextFormat( RichText );
	
	
	m_lbview->setFont( TQFont( "Nimbus Mono L", 9 ) );
	
	m_ljob_name = new TQLabel( this, "m_ljob_name" );
	TQFont ljob_name_font( m_ljob_name->font() );
	ljob_name_font.setBold( TRUE );
	m_ljob_name->setFont( ljob_name_font );
	m_ljob_name->setFrameShape( TQLabel::StyledPanel );
	m_ljob_name->setFrameShadow( TQLabel::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, TQT_SIGNAL( clicked() ), this, TQT_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 TQString& cmd, const TQString& job_name, const TQString& job_description, bool useKdeSu  ) {
	kdDebug() << "KMFProcOut::runCmd(TQString& cmd)"/* << cmd */<< endl;
	show();
	m_lbview->clear();
	m_lbview->setTextFormat( RichText );
	m_ljob_name->setText( job_description );
	m_job_name = job_name;
	startJob( cmd, useKdeSu );
}

void KMFProcOut::startJob( const TQString &cmd, bool useKdeSu ) {
	m_bkill->setEnabled( true );
	
	childproc->clearArguments();
	if( useKdeSu ) {
		*childproc << "kdesu" << "-t" << "-i" << "kmyfirewall" << "--noignorebutton" << "-d" << "-c" << cmd;
	} else {
		*childproc << "bash" << cmd;
	}
	
	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 TQString( "" );
	}

	*stdoutbuf += TQString::fromLatin1( buffer, buflen );
	int pos;
	while ( ( pos = stdoutbuf->find( '\n' ) ) != -1 ) {
		TQString 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 TQString( "" );
	}

	*stderrbuf += TQString::fromLatin1( buffer, buflen );
	int pos;
	while ( ( pos = stderrbuf->find( '\n' ) ) != -1 ) {
		TQString 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 TQString &line ) {
	m_lbview->append( line + "" );
}

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

void KMFProcOut::childFinished( bool , int status ) {
	TQString stat;
	stat.setNum( status );
	const TQString& 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 TQString& str, const TQString& commandName ) {
	kdDebug() << "void KMFProcOut::setText(const TQString& text)" << endl;
// 	kdDebug() << "Text: " << str << endl;
	m_ljob_name->setText( commandName );
	m_lbview->clear();
	m_lbview->setTextFormat( PlainText );
	m_lbview->append( str );
/*
	TQString *text = new TQString( str );
	int pos;
	while ( ( pos = text->find( '\n' ) ) != -1 && !text->isEmpty() ) {
		TQString line = text->left( pos );
		insertStdoutLine( line );
		text->remove( 0, pos + 1 );
	}*/
}

}

#include "kmfprocout.moc"
