//
// C++ Implementation: runcommandinwindow
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//

#ifdef __USE_KDE_LIBS

#include <iostream>
#include <iomanip>


#include <qregexp.h>
#include <QProcess>
#include <qpushbutton.h>


#include "runcommandinwindow.h"

using namespace std;


namespace NApplication
{

RunCommandInWindow::RunCommandInWindow(QObject* parent, const char* name)
{
// 	_lastLinePar = 0;
	_pOutput = 0;
	_pProcess = new QProcess(parent);
	if (name)
		_pProcess->setObjectName(name);
	_pProcess->setReadChannelMode(QProcess::MergedChannels);
	connect( _pProcess, SIGNAL(readyReadStandardOutput()), SLOT(onReadyReadStdout()) );
	// forward signal to outer world 
	connect(_pProcess, SIGNAL(finished(int)), SLOT(onProcessExited()));
}

RunCommandInWindow::~RunCommandInWindow()
{
	delete _pProcess;
	delete _pOutput;	// should not be neccessary
}
	
void RunCommandInWindow::addArgument(const QString& s)
{ 
	if (_command.isEmpty())
		_command = s;
	else
		_arguments.push_back(s);
}

bool RunCommandInWindow::start()
{
	_pOutput = new RunCommandWidget(0, "CommandWindow");
	_pOutput->resize(500,400);
	_pOutput->show();
	connect(_pOutput->_pCloseButton, SIGNAL(clicked()), SLOT(onCommandWindowClosed()));
	connect(_pOutput->_pAbortButton, SIGNAL(clicked()), SLOT(onAbort()));

	_pProcess->start(_command, _arguments, QIODevice::ReadOnly);
	// TODO work correct here!
	return true;
}
 
bool RunCommandInWindow::processExitedSuccessful() const
{
	return _pProcess->exitCode() == 0;
}


// 13 is CR, 10 is LF
void RunCommandInWindow::onReadyReadStdout()
{
	QString newString(_pProcess->readAllStandardOutput());
// 	qDebug("--- begin chunk ---");
// 	for (int i=0; i<strlen(buffer); ++i)
// 	{
// 		cout << setw(4) << (int) buffer[i] << " " << setw(3) << ( ( (((int) buffer[i])!=13) && (((int) buffer[i])!=10)) ? buffer[i] : ' ' ) << " ";
// 		if (i%10 == 0)
// 			cout << endl;
// 	}
// 	cout.flush();
// 	qDebug("\n--- end chunk ---");
	QStringList lines = QStringList::split(QRegExp("\r?\n\r?"), newString, true);
	bool firstLine = true;
	for (QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it)
	{
		QString line = *it;
// 		qDebug(line);
		// only append if this is not the first entry in the splitting
		if (!firstLine)
		{
			// WARNING: don't remove the space here, because QTextBrowser seems not to
			// append a line if an empty String is handed!
			_pOutput->append(" ");
			_lastLine = "";
		}
		else
			firstLine = false;
		if (line.isEmpty())
			continue;
		// find the last position of a carriage return (anything before this is
		// meaningless as there are no \n mark in)
		int crPos = line.findRev('\015');
		if (crPos == -1)
		{
			line.prepend(_lastLine);
		}
		else
		{
			// take everything after the cr
			line = line.mid(crPos+1);
		}
		_lastLine = line;
		_pOutput->replaceLastLine(line);
	}
}

// void RunCommandInWindow::onReadyReadStderr(KProcess *proc, char *buffer, int buflen)
// {
// 	QString newString(buffer);
// 	QStringList lines = QStringList::split(QRegExp("\r?\n\r?"), newString, true);
// 	bool firstLine = true;
// 	for (QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it)
// 	{
// 		QString line = *it;
// 		// only append if this is not the first entry in the splitting
// 		if (!firstLine)
// 		{
// 			// WARNING: don't remove the space here, because QTextBrowser seems not to
// 			// append a line if an empty String is handed!
// 			_pOutput->append(" ");
// 			_lastLine = "";
// 		}
// 		else
// 			firstLine = false;
// 		if (line.isEmpty())
// 			continue;
// 		// find the last position of a carriage return (anything before this is
// 		// meaningless as there are no \n mark in)
// 		int crPos = line.findRev('\015');
// 		if (crPos == -1)
// 		{
// 			line.prepend(_lastLine);
// 		}
// 		else
// 		{
// 			// take everything after the cr
// 			line = line.mid(crPos+1);
// 		}
// 		_lastLine = line;
// 		_pOutput->replaceLastLine(line);
// 	}
// }

void RunCommandInWindow::onProcessExited()
{
	_pOutput->_pCloseButton->setEnabled(true);
	_pOutput->_pAbortButton->setEnabled(false);
	emit processExited();
}

void RunCommandInWindow::onCommandWindowClosed()
{
	// deferred deleting as the sender of the close signal
	_pOutput->deleteLater();
	_pOutput=0;
	emit quit();
}


void RunCommandInWindow::onAbort()
{
	if (_pProcess)
		_pProcess->terminate();
}

}	// namespace NApplication


#endif	// __USE_KDE_LIBS
