/***************************************************************************
 *   Copyright (C) 2005 by David Saxton                                    *
 *   david@bluehaze.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 "externallanguage.h"
#include "languagemanager.h"
#include "logview.h"

#include <kdebug.h>
#include <kprocess.h>
#include <tqregexp.h>
#include <tqtimer.h>

ExternalLanguage::ExternalLanguage( ProcessChain *processChain, KTechlab *parent, const TQString &name )
 : Language( processChain, parent, name )
{
	m_languageProcess = 0l;
}


ExternalLanguage::~ExternalLanguage()
{
	deleteLanguageProcess();
}


void ExternalLanguage::deleteLanguageProcess()
{
	if (!m_languageProcess)
		return;
	
	// I'm not too sure if this combination of killing the process is the best way....
// 	m_languageProcess->tryTerminate();
// 	TQTimer::singleShot( 5000, m_languageProcess, TQ_SLOT( kill() ) );
//  	delete m_languageProcess;
	m_languageProcess->kill();
	m_languageProcess->deleteLater();
	
	m_languageProcess = 0L;
}


void ExternalLanguage::receivedStdout( TDEProcess *, char * buffer, int buflen )
{
	TQStringList lines = TQStringList::split( '\n', TQString::fromLocal8Bit( buffer, buflen ), false );
	TQStringList::iterator end = lines.end();
	
	for ( TQStringList::iterator it = lines.begin(); it != end; ++it )
	{
		if ( isError( *it ) )
		{
			outputError( *it );
			outputtedError( *it );
		}
		else if ( isWarning( *it ) )
		{
			outputWarning( *it );
			outputtedWarning( *it );
		}
		else
		{
			outputMessage( *it );
			outputtedMessage( *it );
		}
	}
}


void ExternalLanguage::receivedStderr( TDEProcess *, char * buffer, int buflen )
{
	TQStringList lines = TQStringList::split( '\n', TQString::fromLocal8Bit( buffer, buflen ), false );
	TQStringList::iterator end = lines.end();
	
	for ( TQStringList::iterator it = lines.begin(); it != end; ++it )
	{
		if ( isStderrOutputFatal( *it ) )
		{
			outputError( *it );
			outputtedError( *it );
		}
		else
		{
			outputWarning( *it );
			outputtedWarning( *it );
		}
	}
}


void ExternalLanguage::processExited( TDEProcess * )
{
	if ( !m_languageProcess )
		return;
	bool allOk = processExited( m_languageProcess->normalExit() && m_errorCount == 0 );
	finish(allOk);
	deleteLanguageProcess();
}


void ExternalLanguage::processInitFailed()
{
	finish(false);
	deleteLanguageProcess();
}


bool ExternalLanguage::start()
{
	displayProcessCommand();
	
	return m_languageProcess->start( TDEProcess::NotifyOnExit, TDEProcess::All );
}


void ExternalLanguage::resetLanguageProcess()
{
	reset();
	deleteLanguageProcess();
	m_errorCount = 0;
	
	m_languageProcess = new TDEProcess(this);
	
	connect( m_languageProcess, TQ_SIGNAL(receivedStdout( TDEProcess*, char*, int )),
			 this, TQ_SLOT(receivedStdout( TDEProcess*, char*, int )) );
	
	connect( m_languageProcess, TQ_SIGNAL(receivedStderr( TDEProcess*, char*, int )),
			 this, TQ_SLOT(receivedStderr( TDEProcess*, char*, int )) );
	
	connect( m_languageProcess, TQ_SIGNAL(processExited( TDEProcess* )),
			 this, TQ_SLOT(processExited( TDEProcess* )) );
}


void ExternalLanguage::displayProcessCommand()
{
	TQStringList quotedArguments;
	TQValueList<TQCString> arguments = m_languageProcess->args();
	
	if ( arguments.size() == 1 )
		quotedArguments << arguments[0];
		
	else
	{
		TQValueList<TQCString>::const_iterator end = arguments.end();
	
		for ( TQValueList<TQCString>::const_iterator it = arguments.begin(); it != end; ++it )
		{
			if ( (*it).isEmpty() || (*it).contains( TQRegExp("[\\s]") ) )
				quotedArguments << TDEProcess::quote( *it );
			else
				quotedArguments << *it;
		}
	}
	
// 	outputMessage( "<i>" + quotedArguments.join(" ") + "</i>" );
	outputMessage( quotedArguments.join(" ") );
// 	LanguageManager::self()->logView()->addOutput( quotedArguments.join(" "), LogView::ot_info );
}


#include "externallanguage.moc"
