/*
	miscutils.cpp - Misc functions
	Copyright (C) 2004  Konrad Twardowski <kdtonline@poczta.onet.pl>

	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.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <sys/types.h>

#include "configuration.h"
#include "miscutils.h"
#include "mmainwindow.h"
#include "msystemtray.h"

#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqwhatsthis.h>

#include <tdeaction.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <knotifyclient.h>
#include <kpassivepopup.h>
#include <kpushbutton.h>
#include <krun.h>
#include <twindowinfo.h>

// public

void MiscUtils::closeCDTray()
{
	if (kshutdownrc->cdTrayClose)
		runShellCommand(kshutdownrc->cdTrayCloseCommand, TDEProcess::Block);
}

void MiscUtils::customMessage(const TQString &text, const TQString &testCommand)
{
	TQString c;
	if (testCommand.isNull())
		c = kshutdownrc->customMessageCommand;
	else
		c = testCommand;

	if (kshutdownrc->customMessageEnabled)
	{
		c.replace("%appname", "KShutDown");
		c.replace("%text", text);
		c.replace("%title", ks_main->caption());
		runShellCommand(c);
	}
}

TQString MiscUtils::formatDateTime(const int secs, const TQString &format)
{
	if ((secs >= 86400) || (secs < 0)) // 24h
		return ">24";

	int h = secs / 3600;
	int m = (secs / 60) % 60;
	int s = secs % 60;
	TQTime t(h, m, s);

	if (format.isNull())
		return t.toString();

	return t.toString(format);
}

TQString MiscUtils::formatDateTime(const TQDateTime &dt)
{
	TQDateTime now = TQDateTime::currentDateTime();

	return
		dt.toString(
			TDEGlobal::locale()->use12Clock()
				? "hh:mm ap, dddd"
				: "hh:mm, dddd"
		) +
		" (+" + formatDateTime(now.secsTo(dt), "hh:mm") + ")";
}

bool MiscUtils::isRestricted(const TQString &key)
{
	return !kapp->authorize("kshutdown_" + key);
}

void MiscUtils::notifyUser(const int secs)
{
	if ((secs < 60) && (secs % 3 == 0)) {
		KWindowInfo::showMessage(ks_main, i18n("Warning"), SmallIcon("messagebox_warning"), 1000);
	}

	switch (secs)
	{
		case 3600: // 1 hour
			customMessage(i18n("1 hour warning"));
			break;
		case 300: // 5 minutes
			notifyUser("kshutdown-5m", i18n("5 minutes warning"));
			customMessage(i18n("5 minutes warning"));
			break;
		case 60: // 1 minute
			notifyUser("kshutdown-1m", i18n("1 minute warning"));
			customMessage(i18n("1 minute warning"));
			break;
		case 10: // 10 seconds
			customMessage(i18n("10 seconds warning"));
			break;
	}
}

void MiscUtils::passiveMessage(const TQString &text, TQWidget *parent) {
	KPassivePopup *popup = KPassivePopup::message(
		"KShutDown",
		text,
		SmallIcon("kshutdown"),
		parent
	);
	if (parent == 0)
		popup->move(0, 0);
}

void MiscUtils::plug(const TDEAction *action, KPushButton *pushButton) {
	pushButton->disconnect(); // disconnect all
	pushButton->connect(pushButton, TQ_SIGNAL(clicked()), action, TQ_SLOT(activate()));
	pushButton->setIconSet(action->iconSet());
	TQString text = action->text();
	if (text.contains("%1"))
		text = text.arg(action->shortcutText());
	pushButton->setText(text);
}

bool MiscUtils::runCommand(const TQString &command)
{
	pid_t pid = KRun::run(command, KURL::List());

	if (pid)
		return true; // ok

	showRunErrorMessage(command);

	return false; // error
}

void MiscUtils::runCommandBeforeAction(const TQString &configEntry)
{
	TDEConfig *conf = kshutdownrc->config();

	if (!conf->hasGroup(configEntry))
		return;

	conf->setGroup(configEntry);

	if (!conf->readBoolEntry("RunCommandBeforeAction", false))
		return;

	TQString command = conf->readEntry("CommandBeforeAction", "");
	int pause = conf->readNumEntry("CommandBeforeActionPause", 10);
	if ((pause < 0) || (pause > 300))
		pause = 10;
	runShellCommand(command, TDEProcess::DontCare, pause);
}

bool MiscUtils::runShellCommand(const TQString &command, const TDEProcess::RunMode mode, const int pause)
{
	if (command.isEmpty())
		return false;

	TDEProcess *p = new TDEProcess();
	if (!p)
	{
		showRunErrorMessage(command);

		return false; // error
	}

	bool retVal = true; // assume ok

	p->setUseShell(true);
	*p << command;
	if (!p->start(mode))
	{
		showRunErrorMessage(command);

		retVal = false; // error
	}
	else
	{
		// pause
		if (pause > 0)
			p->wait(pause);
	}
	delete p;

	return retVal;
}

void MiscUtils::setAutostart(const bool yes) {
	TDEConfig *config = kapp->config();
	config->setGroup("KShutDown");
	config->writeEntry("Autostart", yes);
}

void MiscUtils::setHint(TQWidget *widget, const TQString &value)
{
	TQToolTip::add(widget, value);
	TQWhatsThis::add(widget, value);
}

void MiscUtils::showRunErrorMessage(const TQString &command)
{
	notifyUser("kshutdown-runerror", i18n("Could not run \"%1\"!").arg(command));
}

void MiscUtils::showTestMessage(const TQString &message)
{
	KMessageBox::information(0, message, i18n("Test"));
}

// private

void MiscUtils::notifyUser(const TQString &name, const TQString &text)
{
	WId id;
	if (MSystemTray::isInstance())
		id = ks_tray->winId();
	else
		id = ks_main->winId();
	KNotifyClient::event(id, name, text);
}
