#include "Virtual.moc"
#include "AddVHost.h"

#include <klocale.h>
#include <kurlrequester.h>

#include <pwd.h>
#include <sys/types.h>

#include <qwhatsthis.h>
#include <qlistbox.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <qbuttongroup.h>

Virtual::Virtual(QWidget *parent, const char *name)
 : VirtualBase(parent, name)
{
	curHost=-1;
	ftpxs=0;
	
	root->setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::Directory);
	banner->setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::File);
	logfile->setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::File);
	passwdfile->setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::File);
	shadowfile->setMode(KFile::ExistingOnly | KFile::LocalOnly | KFile::File);
	
	QWhatsThis::add(hosts, i18n("Select the virtual host you want to edit here. If this field is empty, click the <b>Add</b> button below to create a virtual host."));
	connect(add, SIGNAL(clicked()), this, SLOT(addPressed()));
	QWhatsThis::add(add, i18n("Click here to add a new virtual host."));
	connect(remove, SIGNAL(clicked()), this, SLOT(removePressed()));
	QWhatsThis::add(remove, i18n("Remove the selected virtual host."));
	QWhatsThis::add(root, i18n("Select the root directory of this virtual host.<br>The root directory is the directory users logging in to this server will see as /."));
	QWhatsThis::add(banner, i18n("The file selected here will be displayed to the user before logging in.<br><b>Note:</b> The file name is relative to the root directory specified above."));
	QWhatsThis::add(logfile, i18n("Transfers from this virtual server will be logged to the file specified here."));
	QWhatsThis::add(passwdfile, i18n("If you specify a file here, it will be used as an alternative passwd file for authenticating users on this virtual server.\nIf you leave this blank, the system passwd file will be used."));
	QWhatsThis::add(shadowfile, i18n("If you specify a file here, it will be used as an alternative shadow file (storing passwords) for authenticating users on this virtual server.\nIf you leave this blank, the system shadow file will be used, unless you specified a passwd file containing password entries above."));
	QWhatsThis::add(hostname, i18n("Host name of this virtual host. The host name specified here will be displayed to the user before login; it is also returned for the %L macros in welcome messages."));
	QWhatsThis::add(email, i18n("Email of the administrator for this virtual domain. This is used solely for the %E macro in welcome messages."));
	QWhatsThis::add(allowAnon, i18n("If checked, anonymous logins (username ftp or anonymous) are permitted for this virtual server."));
	QWhatsThis::add(real, i18n("Use the buttons here to control which real users can log in to this virtual server."));
	allowNone->setChecked(true);
	allow->setSelectionMode(QListBox::Multi);
	setpwent();
	passwd *p;
	while((p=getpwent()))
		allow->insertItem(p->pw_name);
	endpwent();
}
void Virtual::ftpaccessLoaded(ftpaccess *xs)
{
	ftpxs=xs;
	redraw();
	if(xs->getNumVirtual())
		hosts->setSelected(0, true);
}
void Virtual::redraw()
{
	bool haveVirtual=ftpxs->getNumVirtual()!=0;
	hosts->clear();
	for(int i=0; i<ftpxs->getNumVirtual(); i++)
		hosts->insertItem(ftpxs->getVirtual(i)->getIP());
	hosts->setEnabled(haveVirtual);
	remove->setEnabled(haveVirtual);
	root->setEnabled(haveVirtual);
	banner->setEnabled(haveVirtual);
	logfile->setEnabled(haveVirtual);
	passwdfile->setEnabled(haveVirtual);
	shadowfile->setEnabled(haveVirtual);
	hostname->setEnabled(haveVirtual);
	email->setEnabled(haveVirtual);
	allowAnon->setEnabled(haveVirtual);
	real->setEnabled(haveVirtual);
	allowNone->setEnabled(haveVirtual);
	allowAll->setEnabled(haveVirtual);
	allowSpecified->setEnabled(haveVirtual);
	denySpecified->setEnabled(haveVirtual);
	allow->setEnabled(haveVirtual);
}
void Virtual::update()
{
	if(curHost>=0) {
		ftpvirtual *v=ftpxs->getVirtual(curHost);
		v->setRoot(root->url());
		v->setBanner(banner->url());
		v->setLogfile(logfile->url());
		v->setHostname(email->text());
		v->setEmail(email->text());
		v->setPasswd(passwdfile->url());
		v->setShadow(shadowfile->url());
		v->setAnon(allowAnon->isChecked());
		if(allowNone->isChecked())
			v->setReal(ftpvirtual::none);
		else if(allowAll->isChecked())
			v->setReal(ftpvirtual::all);
		else if(allowSpecified->isChecked() || denySpecified->isChecked()) {
			if(allowSpecified->isChecked())
				v->setReal(ftpvirtual::allowSpecified);
			else
				v->setReal(ftpvirtual::denySpecified);
			v->clearUsers();
			for(unsigned int i=0; i<allow->count(); i++)
				if(allow->isSelected(i))
					v->addUser(allow->text(i));
		}
	}
}
void Virtual::vHostSelected(int host)
{
	if(curHost>=0)
		update();
	ftpvirtual *v=ftpxs->getVirtual(host);
	root->setURL(v->getRoot());
	banner->setURL(v->getBanner());
	logfile->setURL(v->getLogfile());
	hostname->setText(v->getHostname());
	email->setText(v->getHostname());
	passwdfile->setURL(v->getPasswd());
	shadowfile->setURL(v->getShadow());
	allowAnon->setChecked(v->getAnon());
	if(v->getReal()==ftpvirtual::none)
		allowNone->setChecked(true);
	else if(v->getReal()==ftpvirtual::all)
		allowAll->setChecked(true);
	else if(v->getReal()==ftpvirtual::allowSpecified)
		allowSpecified->setChecked(true);
	else
		denySpecified->setChecked(true);
	if(v->getReal()==ftpvirtual::allowSpecified || v->getReal()==ftpvirtual::denySpecified) {
		QStringList s=v->getUserList();
		for(unsigned int i=0; i<allow->count(); i++)
			allow->setSelected(i, s.contains(allow->text(i)));
	}
	curHost=host;
}
void Virtual::addPressed()
{
	AddVHost avh;
	connect(&avh, SIGNAL(VHostAdded(const QString &)), SLOT(VHostAdded(const QString &)));
	avh.exec();
}
void Virtual::VHostAdded(const QString &IP)
{
	ftpvirtual *v=new ftpvirtual;
	v->setIP(IP);
	ftpxs->addVirtual(v);
	redraw();
	hosts->setSelected(ftpxs->getNumVirtual()-1, true);
}
void Virtual::removePressed()
{
	curHost=-1;
	for(unsigned int i=0; i<hosts->count(); i++)
		if(hosts->isSelected(i))
			ftpxs->deleteVirtual(i);
	redraw();
	if(ftpxs->getNumVirtual())
		hosts->setSelected(0, true);
	vHostSelected(0);
}
