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

#include <string>

#include <qlineedit.h>
#include <qpushbutton.h>
#include <QMainWindow>

// NPlugin
#include <iprovider.h>

// NApplication
#include <runcommandforoutput.h>

// NXml
#include <xmldata.h>

#include <helpers.h>

#include "orphanplugin.h"

#include "orphansearchinputimpl.h"
#include "orphanfeedbackwidgetimpl.h"

namespace NPlugin {

const QString OrphanPlugin::PLUGIN_NAME = "OrphanPlugin";


OrphanPlugin::OrphanPlugin()
{
	_pOrphanFeedbackWidget = 0;
	_pProvider = 0;
	_pInputWidget = 0;
}


OrphanPlugin::~OrphanPlugin()
{
	delete _pInputWidget;
	delete _pOrphanFeedbackWidget;
}



/////////////////////////////////////////////////////
// Plugin Interface
/////////////////////////////////////////////////////

QString OrphanPlugin::title() const
{ 
	return tr("Orphan Plugin"); 
}

QString OrphanPlugin::briefDescription() const
{
	return tr("Plugin to search for orphaned packages.");
}

QString OrphanPlugin::description() const
{
	return tr("This plugin supports to search for packages which are orphaned.\n"
		"It uses deborphan to implement the search.");
}

void OrphanPlugin::init(IProvider* pProvider)
{
	_pProvider = pProvider;
	QMainWindow* pWindow = pProvider->mainWindow();
	_pInputWidget = new OrphanSearchInputImpl(pWindow);
	connect( _pInputWidget, SIGNAL(searchChanged()), SLOT(evaluateSearch()) );
	_pOrphanFeedbackWidget = new OrphanFeedbackWidget(pWindow);
	_pOrphanFeedbackWidget->setClearButton(
		pProvider->createClearButton(_pOrphanFeedbackWidget, "ClearButton"), 0);
	connect( _pOrphanFeedbackWidget->_pClearButton, SIGNAL(clicked()), SLOT(onClearSearch()) );
}

QDomElement OrphanPlugin::loadSettings(const QDomElement source)
{
	if (source.tagName() != name())
		return source;
	float settingsVersion;
	NXml::getAttribute(source, settingsVersion, "settingsVersion", 0.0);
	if (settingsVersion < 0.1)
	{
		qDebug("Settings version for OrphanPlugin to old");
		return NXml::getNextElement(source);
	}
	
	// load the real data
	int searchOption;
	NXml::getAttribute(source, searchOption, "searchOption", 1);
	_pInputWidget->setSearchOption(OrphanSearchInputImpl::OrphanSearchOption(searchOption));
	
	return NXml::getNextElement(source);
}

void OrphanPlugin::saveSettings(NXml::XmlData& outData, QDomElement parent) const
{
	QDomElement orphanPluginElement = outData.addElement(parent, name());
	outData.addAttribute(orphanPluginElement, 0.1f, "settingsVersion");
	outData.addAttribute(orphanPluginElement, _pInputWidget->searchOption(), "searchOption");
}



/////////////////////////////////////////////////////
// Search Plugin Interface
/////////////////////////////////////////////////////

QWidget* OrphanPlugin::shortInputAndFeedbackWidget() const
{
	return _pOrphanFeedbackWidget;
}

QWidget* OrphanPlugin::inputWidget() const
{
	return _pInputWidget;
}

QString OrphanPlugin::inputWidgetTitle() const 
{ 
	return tr("Orphans"); 
};


void OrphanPlugin::clearSearch()
{
	_pInputWidget->clearSearch();
//	evaluateSearch();
}


bool OrphanPlugin::isInactive() const
{
	return !_pInputWidget->isActive();
}

/////////////////////////////////////////////////////
// Search Helper Methods
/////////////////////////////////////////////////////
	
void OrphanPlugin::evaluateSearch()
{
	qDebug("evaluating orphan search");
	_pProvider->reportBusy(this, tr("Searching orphans"));
	_searchResult.clear();
	if ( !isInactive() )	// if the search is not empty
	{
		QString commandLine = _pInputWidget->getDeborphanCommandLine();
		_pOrphanFeedbackWidget->_pTextDisplay->setText(commandLine);
		NApplication::RunCommandForOutput ro(commandLine);
		if (ro.run(commandLine, 0))
		{
			QStringList lines = ro.getOutput();
			// the output of deborphan is one package per line
			for (QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it)
			{
				_searchResult.insert( extractPackageNameFromDeborphanLine(toString(*it)) );
			}
		}
		else
			_pProvider->reportError(tr("Error running deborphan"), tr("An error occured running <tt>")+ commandLine+"</tt>");
	}
	else
		_pOrphanFeedbackWidget->_pTextDisplay->clear();
		
	_pOrphanFeedbackWidget->setShown(!isInactive());

	_pProvider->reportReady(this);
	emit searchChanged(this);
}

string OrphanPlugin::extractPackageNameFromDeborphanLine(const string& line ) 
{
	return line.substr(0, line.find(":"));
}



}
