/*
	mstatstab.cpp - A statistics dialog
	Copyright (C) 2003  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 "configuration.h"
#include "mmainwindow.h"
#include "miscutils.h"
#include "mstatstab.h"

#include <tqcheckbox.h>
#include <tqprocess.h>
#include <tqregexp.h>
#include <tqtextedit.h>
#include <tqvbox.h>
#include <tqvgroupbox.h>
#include <tqwhatsthis.h>

#include <kiconloader.h>
#include <tdelocale.h>
#include <kpushbutton.h>

// public

MStatsTab *MStatsTab::_instance = 0;

MStatsTab::MStatsTab()
	: KDialogBase(
		ks_main,
		"MStatsTab",
		false, // modeless
		i18n("Statistics"),
		Close | Details,
		Close // default button
	),
	_buf(TQString::null)
{
	_process = new TQProcess(this);
	connect(_process, TQ_SIGNAL(processExited()), TQ_SLOT(slotProcessExit()));
	connect(_process, TQ_SIGNAL(readyReadStdout()), TQ_SLOT(slotReadStdout()));

	TQVBox *main = new TQVBox(this);
	setMainWidget(main);

	// output
	te_output = new TQTextEdit(main, "TQTextEdit::te_output");
	te_output->setMinimumSize(640, 320);
	te_output->setPaletteBackgroundColor(white);
	te_output->setPaletteForegroundColor(black);
	te_output->setReadOnly(true);
	te_output->setTextFormat(RichText); // allow HTML tags
	te_output->setWordWrap(TQTextEdit::NoWrap);
	// based on the "Linux User's Manual" (man w)
	TQWhatsThis::add(
		te_output,
		MiscUtils::HTML(i18n(
			"This view displays information about the users currently on the " \
			"machine, and their processes.<br>" \
			"The header shows how long the system has been running."
		))
	);

	TQHBox *buttons = new TQHBox(main);
	// refresh
	b_refresh = new KPushButton(SmallIcon("reload"), i18n("Refresh"), buttons, "KPushButton::b_refresh");
	connect(b_refresh, TQ_SIGNAL(clicked()), TQ_SLOT(slotRefresh()));

	// options
	TQVGroupBox *options = new TQVGroupBox(i18n("Options"), main);
	// long format
	c_longFormat = new TQCheckBox(i18n("More information"), options);
	c_longFormat->setChecked(kshutdownrc->statsLongFormat);
	connect(c_longFormat, TQ_SIGNAL(clicked()), TQ_SLOT(slotRefresh()));
	MiscUtils::setHint(c_longFormat, i18n("Show login time, JCPU and PCPU times."));
	// toggle from field
	c_toggleFromField = new TQCheckBox(i18n("Toggle \"FROM\""), options);
	c_toggleFromField->setChecked(kshutdownrc->statsToggleFromField);
	MiscUtils::setHint(c_toggleFromField, i18n("Toggle the \"FROM\" (remote hostname) field."));
	connect(c_toggleFromField, TQ_SIGNAL(clicked()), TQ_SLOT(slotRefresh()));

	setButtonGuiItem(Details, KStdGuiItem::configure());
	setDetailsWidget(options);
	adjustSize();
}

MStatsTab::~MStatsTab()
{
	killProcess();
}

// protected

void MStatsTab::keyPressEvent(TQKeyEvent *e) {
	// Ctrl+R, F5 = Refresh
	if (
		b_refresh->isEnabled() &&
		(
			((e->key() == Key_F5) && (e->state() == 0)) ||
			((e->key() == Key_R) && (e->state() == ControlButton))
		)
	) {
		slotRefresh();
		e->accept();
	}
	else {
		KDialogBase::keyPressEvent(e);
	}
}

// private

void MStatsTab::killProcess() const
{
	// kill previous process (if any)
	if (_process && _process->isRunning())
		_process->kill();
}

// private slots

void MStatsTab::slotProcessExit() {
	_buf.replace("\n", "<br>");
	_buf.replace(" ", "&nbsp;");

	#define KS_HEADER(text) \
		_buf.replace(text, "<font color=\"#a0a0a0\">" text "</font>");

	#define KS_WARNING(text) \
		_buf.replace(TQRegExp("\\b" text "\\b"), "<font color=\"#ff0000\">" text "</font>");

	// underline header
	KS_HEADER("USER")
	KS_HEADER("TTY")
	KS_HEADER("FROM")
	KS_HEADER("LOGIN@")
	KS_HEADER("JCPU")
	KS_HEADER("PCPU")
	KS_HEADER("IDLE")
	KS_HEADER("WHAT")
	// highlight some important words
// TODO: 2.0: add more keywords (e.g. backup)
	KS_WARNING("root")
	KS_WARNING("ssh")
	KS_WARNING("su")
	KS_WARNING("sudo")
	KS_WARNING("telnet")

	_buf.prepend("<pre style=\"font-family: " + TDEGlobalSettings::fixedFont().family() + "\"><b>");
	_buf.append("</b></pre>");

	te_output->setText(MiscUtils::HTML(_buf));
	b_refresh->setEnabled(true);
}

void MStatsTab::slotReadStdout() {
	_buf.append(_process->readStdout());
}

void MStatsTab::slotRefresh()
{
	b_refresh->setEnabled(false);

	// update config
	kshutdownrc->statsLongFormat = c_longFormat->isChecked();
	kshutdownrc->statsToggleFromField = c_toggleFromField->isChecked();

	_buf = "";
	killProcess();
	_process->clearArguments();
	_process->addArgument("w");
	if (!kshutdownrc->statsLongFormat)
		_process->addArgument("-s"); // -s - short format
	if (kshutdownrc->statsToggleFromField)
		_process->addArgument("-f"); // -f - toggle "from" field
	if (!_process->start()) {
		_buf = "<b><font color=\"#ff0000\">" + i18n("Error") + "</font><br><br>";
		_buf.append(i18n("Command: %1").arg(_process->arguments().join(" ")));
		_buf.append("</b>");
		te_output->setText(_buf);
		b_refresh->setEnabled(true);
	}
}
#include "mstatstab.moc"
