#include "Virtual.moc"
#include "AddVHost.h"
#include <klocale.h>
#include <pwd.h>
#include <sys/types.h>
#include <qwhatsthis.h>

Virtual::Virtual(QWidget *parent, const char *name):QWidget(parent, name)
{
	curHost=-1;
	int x=5, y=5;
	int w=630, h=325;
	ftpxs=0;
	hosts=new QListBox(this);
	connect(hosts, SIGNAL(highlighted(int)), this, SLOT(vHostSelected(int)));
	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."));
	add=new QPushButton(i18n("&Add"), this);
	connect(add, SIGNAL(clicked()), this, SLOT(addPressed()));
	QWhatsThis::add(add, i18n("Click here to add a new virtual host."));
	remove=new QPushButton(i18n("&Remove"), this);
	connect(remove, SIGNAL(clicked()), this, SLOT(removePressed()));
	QWhatsThis::add(remove, i18n("Remove the selected virtual host."));
	hosts->setGeometry(x,y,130,h-5-add->height());
	add->setGeometry(x, h-add->height(), 65, add->height());
	remove->setGeometry(x+65,h-add->height(), 65, add->height());
	x+=hosts->width()+5; y=5;
	int r=w-150-10;
	root=new InputFileCtl(i18n("Root directory:"), QString::null, true, QString::null, this);
	root->setGeometry(x, y, r-x, root->height()); y+=root->height()+5;
	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 /."));
	banner=new InputFileCtl(i18n("Banner:"), QString::null, false, QString::null, this);
	banner->setGeometry(x, y, r-x, banner->height()); y+=banner->height()+5;
	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."));
	logfile=new InputFileCtl(i18n("Logfile:"), QString::null, false, QString::null, this);
	logfile->setGeometry(x, y, r-x, logfile->height()); y+=logfile->height()+5;
	QWhatsThis::add(logfile, i18n("Transfers from this virtual server will be logged to the file specified here."));
	passwdfile=new InputFileCtl(i18n("Passwd file:"), QString::null, false, QString::null, this);
	passwdfile->setGeometry(x, y, r-x, passwdfile->height()); y+=passwdfile->height()+5;
	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."));
	shadowfile=new InputFileCtl(i18n("Shadow file:"), QString::null, false, QString::null, this);
	shadowfile->setGeometry(x, y, r-x, shadowfile->height()); y+=shadowfile->height()+5;
	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."));

	hostname=new InputCtl(i18n("Host name:"), QString::null, this);
	hostname->setGeometry(x, y, r-x, hostname->height()); y+=hostname->height()+5;
	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."));
	email=new InputCtl(i18n("Administrator Email:"), QString::null, this);
	email->setGeometry(x, y, r-x, email->height()); y+=email->height()+5;
	QWhatsThis::add(email, i18n("Email of the administrator for this virtual domain. This is used solely for the %E macro in welcome messages."));
	allowAnon=new QCheckBox(i18n("Allow anonymous logins"), this);
	allowAnon->setGeometry(x, y, r-x, allowAnon->height()); y+=allowAnon->height()+5;
	QWhatsThis::add(allowAnon, i18n("If checked, anonymous logins (username ftp or anonymous) are permitted for this virtual server."));
	
	x=r+5; y=15;
	real=new QButtonGroup(i18n("&Real user logins:"), this);
	QWhatsThis::add(real, i18n("Use the buttons here to control which real users can log in to this virtual server."));
	allowNone=new QRadioButton(i18n("&Deny all"), real);
	allowNone->setGeometry(5, y, allowNone->sizeHint().width(), allowNone->sizeHint().height()); y+=allowNone->height();
	allowAll=new QRadioButton(i18n("&Allow all"), real);
	allowAll->setGeometry(5, y, allowAll->sizeHint().width(), allowAll->sizeHint().height()); y+=allowNone->height();
	allowSpecified=new QRadioButton(i18n("Allow &specified:"), real);
	allowSpecified->setGeometry(5, y, allowSpecified->sizeHint().width(), allowSpecified->sizeHint().height()); y+=allowSpecified->height();
	denySpecified=new QRadioButton(i18n("Den&y specified:"), real);
	denySpecified->setGeometry(5, y, denySpecified->sizeHint().width(), denySpecified->sizeHint().height()); y+=denySpecified->height();
	allow=new QListBox(real);
	real->setGeometry(x, 5, w-r-10, h-5);
	allow->setGeometry(5,y,real->width()-10,real->height()-y-10);
	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->text());
		v->setBanner(banner->text());
		v->setLogfile(logfile->text());
		v->setHostname(email->text());
		v->setEmail(email->text());
		v->setPasswd(passwdfile->text());
		v->setShadow(shadowfile->text());
		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->setText(v->getRoot());
	banner->setText(v->getBanner());
	logfile->setText(v->getLogfile());
	hostname->setText(v->getHostname());
	email->setText(v->getHostname());
	passwdfile->setText(v->getPasswd());
	shadowfile->setText(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 = new AddVHost;
	connect(avh, SIGNAL(VHostAdded(QString const &)), SLOT(VHostAdded(QString const &)));
}
void Virtual::VHostAdded(QString const &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);
}
