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

#include "aptactionplugin.h"

#include <QAction>
#include <QApplication>
#include <QClipboard>

// NApplication
#include "applicationfactory.h"
#include "runcommand.h"


// NPlugin
#include <iprovider.h>
#include "iaptmediator.h"

#include "helpers.h"

namespace NPlugin 
{

const QString AptActionPlugin::PLUGIN_NAME = "AptActionPlugin";

AptActionPlugin::AptActionPlugin(IAptMediator* pMediator) :
 	_title("Apt-Action Plugin"),
	_briefDescription("Offers the menu and toolbar entries"),
	_description("This plugin offers the menu and toolbar entries for the APT plugin. "
		"This includes the possibilities to install and remove packages."),
	_pMediator(pMediator)
{
	QAction* pQAptUpdateAction = new QAction(tr("Update Apt-Package Database"), this);
	pQAptUpdateAction->setStatusTip(tr("Updates the package database"));
	_pUpdateAction = new Action(pQAptUpdateAction, false, "System");
	connect(pQAptUpdateAction, SIGNAL(triggered(bool)), SLOT(onUpdateAction()));
	
	QAction* pQReloadDbAction = new QAction(QObject::tr("Reload Package Database"), this);
	pQReloadDbAction->setStatusTip(tr("Reloads the package database from disk "
		"(e.g. if apt-get update was performed externally)."));
	_pReloadDbAction = new Action(pQReloadDbAction, false, "System");
	connect(pQReloadDbAction, SIGNAL(triggered(bool)), SLOT(onReloadAction()));


	QAction* pQAptGetLineAction = new QAction(tr("Copy Command Line for Installing Package to Clipboard"), this);
	pQAptGetLineAction->setToolTip(tr("Creates a command line to install the selected package, and copies it to the clipboard"));
	pQAptGetLineAction->setStatusTip(tr("Creates a command line to install the selected package, and copies it to the clipboard"));
	connect(pQAptGetLineAction, SIGNAL(triggered(bool)), SLOT(onCreateInstallLineAction()));
	_pCreateInstallLineAction = new Action(pQAptGetLineAction, true);
	
	QAction* pQAptGetInstallAction = new QAction(tr("Install/Update Package"), this);
	pQAptGetInstallAction->setToolTip(tr("Installs/updates the package"));
	pQAptGetInstallAction->setStatusTip(tr("Installs/updates the package"));
	connect(pQAptGetInstallAction, SIGNAL(triggered(bool)), SLOT(onInstallAction()));
	_pInstallAction = new Action(pQAptGetInstallAction, true, "Packages", "Main");

	QAction* pQAptGetRemoveAction = new QAction(tr("Remove Package"), this);
	pQAptGetRemoveAction->setToolTip(tr("Removes the package"));
	pQAptGetRemoveAction->setStatusTip(tr("Removes the package"));
	connect(pQAptGetRemoveAction, SIGNAL(triggered(bool)), SLOT(onRemoveAction()));
	_pRemoveAction = new Action(pQAptGetRemoveAction, true, "Packages", "Main");

	QAction* pQPurgeAction = new QAction(tr("Purge Package"), this);
	pQPurgeAction->setToolTip(tr("Removes package including configuration"));
	pQPurgeAction->setStatusTip(tr("Removes package including configuration"));
	connect(pQPurgeAction, SIGNAL(triggered(bool)), SLOT(onPurgeAction()));
	_pPurgeAction = new Action(pQPurgeAction, true, "Packages");

	QAction* pQSeparatorAction = new QAction(this);
	pQSeparatorAction->setSeparator(true);
	_pSeparatorAction = new Action(pQSeparatorAction, true, "System");
}


AptActionPlugin::~AptActionPlugin()
{
	delete _pUpdateAction;
	delete _pReloadDbAction;
	delete _pSeparatorAction;
	delete _pCreateInstallLineAction;
	delete _pInstallAction;
	delete _pRemoveAction;
	delete _pPurgeAction;
}

/////////////////////////////////////////////////////
// Plugin Interface
/////////////////////////////////////////////////////
	
void AptActionPlugin::init(IProvider* pProvider) 
{
	_pProvider = pProvider; 
	QIcon installIcon(_pProvider->iconDir()+"install-package.png");
	_pInstallAction->action()->setIcon(installIcon);
	QIcon removeIcon(_pProvider->iconDir()+"remove-package.png");
	_pRemoveAction->action()->setIcon(removeIcon);
};


/////////////////////////////////////////////////////
// ActionPlugin Interface
/////////////////////////////////////////////////////

vector<Action*> AptActionPlugin::actions() const
{
	vector<Action*> actions;
	actions.push_back(_pSeparatorAction);
	actions.push_back(_pUpdateAction);
	actions.push_back(_pReloadDbAction);
	actions.push_back(_pCreateInstallLineAction);
	actions.push_back(_pInstallAction);
	actions.push_back(_pRemoveAction);
	actions.push_back(_pPurgeAction);
	return actions;
}

/////////////////////////////////////////////////////
// Other Methods
/////////////////////////////////////////////////////

void AptActionPlugin::onCreateInstallLineAction()
{
	QClipboard *pCb = QApplication::clipboard();
	pCb->setText(installationToolCommand() + " install "+_pProvider->currentPackage(), QClipboard::Clipboard);
	pCb->setText(installationToolCommand() + " install "+_pProvider->currentPackage(), QClipboard::Selection);

}

void AptActionPlugin::onInstallAction()
{
	installOrRemove(true);
}

void AptActionPlugin::onRemoveAction()
{
	installOrRemove(false);
}

void AptActionPlugin::onPurgeAction()
{
	installOrRemove(false, true);
}

void AptActionPlugin::onUpdateAction()
{
	_pMediator->updateAptDatabase();
}

void AptActionPlugin::onReloadAction()
{
	_pMediator->reloadAptDatabase();
}

void  AptActionPlugin::installOrRemove(bool install, bool purge)
{
	NApplication::RunCommand* pCommand = NApplication::ApplicationFactory::getInstance()->getRunCommand("");
	pCommand->addArgument(installationToolCommand());
	if (install)
		pCommand->addArgument("install");
	else
	{
		if (purge)
			pCommand->addArgument("purge");
		else
			pCommand->addArgument("remove");
	}
	pCommand->addArgument(_pProvider->currentPackage());
	try
	{
		pCommand->startAsRoot();
	}
	catch (const NException::RuntimeException& e)
	{
		_pProvider->reportError(tr("Unable to launch command"), toQString(e.description()) +
			QString(tr("\nPlease configure to use \"apt\" as package administration tool "  
				"(Packagesearch->Settings->Apt Plugins)"))
		);
		delete pCommand;
	}
}


QString AptActionPlugin::installationToolCommand() 
{
	return _pMediator->installationToolCommand();
}

}
