/***************************************************************************
                          preferences.ui.h -  description
                             -------------------
begin		: June  2003
copyright	: (C) 2003 by Martin Koebele
email		: apollon@mkoebele.de
description	: the new apollon-settingsdialog

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <libgift/libgift.h>
#include <libgift/conf.h>

#include <qstring.h>
#include <qstringlist.h>
#include <qurl.h>

#include <kconfig.h>
#include <kdebug.h>
#include <kfiledialog.h>
#include <kmessagebox.h>

#include "pluginlistitem.h"
#include "progressbarpreview.h"

static QString home;

void ApollonPreferencesDialog::init()
{
	m_loader = KGlobal::iconLoader();
	sharedFolderPB->setPixmap(m_loader->loadIcon("folder", KIcon::Small, 16) );
	m_disabledPlugins = "";

	m_noPixmap = m_loader->loadIcon("no", KIcon::Small);
	m_okPixmap = m_loader->loadIcon("ok", KIcon::Small);

	if(home.isEmpty()) home = getenv("HOME");
	
	ApollonProgressBarPreview* preview = new ApollonProgressBarPreview(progressPreviewStack);
	progressPreviewStack->addWidget(preview, 1);

	connect(pluginsList, SIGNAL(clicked(QListBoxItem *)), this, SLOT(enableButton(QListBoxItem *)));
}

void ApollonPreferencesDialog::show()
{
	readConfig();
	QDialog::show();
}

void ApollonPreferencesDialog::accept()
{
	emit ok();
	QDialog::accept();
}

void ApollonPreferencesDialog::uploadsCheckToggled(bool enabled)
{
	uploadsSpin->setEnabled(enabled);
	userUploadsSpin->setEnabled(enabled);
	if(bandwidthCheck->isChecked())
	{
		upRestrictionSpin->setEnabled(enabled);
	}
}

void ApollonPreferencesDialog::bandwidthCheckToggled(bool enabled)
{
	downRestrictionSpin->setEnabled(enabled);
	if(uploadsCheck->isChecked())
	{
		upRestrictionSpin->setEnabled(enabled);
	}
	else
	{
		upRestrictionSpin->setDisabled(true);
	}
}

void ApollonPreferencesDialog::readGiftConfig( bool init )
{
	QString filename = home + "/.giFT/giftd.conf";
	Config *config = config_new_ex ((char*) filename.ascii(), FALSE);

	followSymlinksCheck->setChecked(config_get_int(config, (char*) "main/follow_symlinks"));

	QString plugins = config_get_str(config, (char*) "main/plugins");

	pluginsList->clear();
	QStringList list = list.split(QString(":"), plugins);
	for(QStringList::Iterator it = list.begin(); it != list.end(); ++it)
	{
		/*PluginListItem* newItem =*/ new PluginListItem(pluginsList, m_okPixmap, *it);
	}

	m_completed = config_get_str(config, (char *) "download/completed");
	downloadEdit->setText(m_completed);
	if ( init ) emit sharedFolder(m_completed);

	m_incoming = config_get_str(config, (char *) "download/incoming");

	userUploadsSpin->setValue(config_get_int(config, (char *) "sharing/max_peruser_uploads"));

	hideHiddenCheck->setChecked(config_get_int(config, (char *) "sharing/hide_dot_files"));

	sharedFolderList->clear();
	QString shared = config_get_str(config, (char *) "sharing/root");
	QStringList sharedList = sharedList.split(QString(":"), shared);
	for(QStringList::Iterator it = sharedList.begin(); it != sharedList.end(); ++it)
	{
		sharedFolderList->insertItem(*it);
		if(!(*it).isEmpty())
		{
			if ( init ) emit sharedFolder(*it);
		}
	}

	uploadsSpin->setValue(config_get_int(config, (char *) "sharing/max_uploads"));
	uploadsCheck->setChecked(!config_get_int(config, (char *) "sharing/shares_hidden"));

	int interval = config_get_int(config, (char *) "sharing/auto_resync_interval");
	if(interval == 0)
		syncCombo->setCurrentItem(0);
	else if (interval == 3600)
		syncCombo->setCurrentItem(1);
	else if (interval == 86400)
		syncCombo->setCurrentItem(2);
	else
		syncCombo->setCurrentItem(3);

	int shareCompleted = config_get_int(config, (char *) "sharing/share_completed");
	shareDownloadCheck->setChecked(shareCompleted);

	int downstream = config_get_int(config, (char *) "bandwidth/downstream") / 1024;
	int upstream = config_get_int(config, (char *) "bandwidth/upstream") / 1024;
	if(downstream || upstream)
	{
		bandwidthCheck->setChecked(true);
		downRestrictionSpin->setValue(downstream);
		upRestrictionSpin->setValue(upstream);
	}
	else
	{
		bandwidthCheck->setChecked(false);
	}

	config_free(config);

	// OpenFT config
	filename = home + "/.giFT/OpenFT/OpenFT.conf";
	config = config_new_ex ((char *) filename.ascii(), false);

	userEdit->setText(config_get_str(config, (char *) "main/alias"));
	int searchnode = config_get_int(config, (char *) "main/class");

	if(searchnode == 1)
	{
		checkSearchnode->setChecked(false);
	}
	else if(searchnode == 3)
	{
		checkSearchnode->setChecked(true);
		groupBoxPorts->setEnabled(true);
	}

	spinSearchPort->setValue(config_get_int(config, (char *) "main/port"));
	spinHttpPort->setValue(config_get_int(config, (char *) "main/port_http"));

	config_free(config);
}

void ApollonPreferencesDialog::readConfig( bool init )
{
	kdDebug() << k_funcinfo << "init = " << init << endl;
	
	readGiftConfig( init );
	KConfig *config = KGlobal::config();
	{
		KConfigGroupSaver saver(config, "Behaviour");

		bool stop = config->readBoolEntry("shutApollon", false);
		removeSysTrayCheck->setChecked(stop);
		if ( init ) emit shutApollon(stop);

		bool docked = config->readBoolEntry("Docked", false);
		startSysTrayCheck->setChecked(docked);
		if ( init ) emit startDocked(docked);

		int pops = config->readNumEntry("ShowPopups", 1);
		notificationComboBox->setCurrentItem(pops);
		if ( init ) emit showPopUps(pops);

		int startpage = config->readNumEntry("StartPage", 0);
		pageCombo->setCurrentItem(startpage);
		if ( init ) emit startPage(startpage);

		int killdaemon = config->readBoolEntry("KillDaemon", true);
		killDaemonCheck->setChecked(!killdaemon);
		if ( init ) emit killDaemon(killdaemon);

		QStringList disabledPluginList = config->readListEntry("disabled_plugins", ':');
		for(QStringList::Iterator it = disabledPluginList.begin(); it != disabledPluginList.end(); ++it)
		{
			PluginListItem *newItem = new PluginListItem(pluginsList, m_noPixmap, *it);
			newItem->setEnabled(false);
		}

		bool docking = config->readBoolEntry("Docking", true);
		dockingEnabledCheck->setChecked(docking);
		if ( init ) emit dockingEnabled(docking);
		
		int pbartype = config->readNumEntry("ProgressBarType", 0);
		progressTypeCombo->setCurrentItem(pbartype);
		progressPreviewStack->raiseWidget(pbartype);
		if ( init ) emit progressBarType(pbartype);
	}

	{
		KConfigGroupSaver saver(config, "giFT");
		int searchInterval = config->readNumEntry("AutoSearchInterval", 30);
		autoSearchSpin->setValue(searchInterval);
		if ( init ) emit autoSearchInterval(searchInterval);

		int max_uploads = config->readNumEntry("max_uploads", 5);
		int max_per_user = config->readNumEntry("max_per_user", 1);
		if(!(uploadsCheck->isChecked()))
		{
			uploadsSpin->setValue(max_uploads);
			userUploadsSpin->setValue(max_per_user);
		}

		int downstream = config->readNumEntry("downstream", 10 * 1024) / 1024;
		int upstream = config->readNumEntry("upstream", 5 * 1024) / 1024;
		if(!(bandwidthCheck->isChecked()))
		{
			downRestrictionSpin->setValue(downstream);
			upRestrictionSpin->setValue(upstream);
		}

		pluginsList->sort(false);
	}

	m_giftChanged = false;
}

void ApollonPreferencesDialog::saveGiftConfig()
{
	QString filename = home + "/.giFT/giftd.conf";
	Config *config = config_new_ex((char *) filename.ascii(), false);

	// General tab
	config_set_str(config, (char *) "download/completed", (char*) downloadEdit->text().ascii());
	config_set_int(config, (char *) "sharing/share_completed", shareDownloadCheck->isChecked());

	// Shared folders tab
	QString shared("");
	for(uint i = 0; i < sharedFolderList->count(); i++)
	{
		shared += sharedFolderList->text(i);
		if(i + 1 < sharedFolderList->count())
			shared += QString(":");
	}
	config_set_str(config, (char *) "sharing/root", (char*) shared.ascii());

	// Traffic tab
	if(uploadsCheck->isChecked())
	{
		config_set_int(config, (char *) "sharing/shares_hidden", 0);
		emit showShares();
	}
	else
	{
		config_set_int(config, (char *) "sharing/shares_hidden", 1);
		emit hideShares();
	}
	config_set_int(config, (char *) "sharing/max_uploads", uploadsSpin->value());
	config_set_int(config, (char *) "sharing/max_peruser_uploads", userUploadsSpin->value());

	int downstream = 0, upstream = 0;
	if(bandwidthCheck->isChecked())
	{
		downstream = downRestrictionSpin->value();
		upstream = upRestrictionSpin->value();
	}
	config_set_int(config, (char *) "bandwidth/downstream", downstream * 1024);
	config_set_int(config, (char *) "bandwidth/upstream", upstream * 1024);

	// Advanced tab
	QString plugins("");
	for(uint i = 0; i < pluginsList->count(); i++)
	{
		if(((PluginListItem *) pluginsList->item(i))->isEnabled())
		{
			plugins += ((PluginListItem *) pluginsList->item(i))->text();
			if(i + 1 < pluginsList->count())
				plugins += QString(":");
		}
	}
	config_set_str(config, (char *) "main/plugins", (char*) plugins.ascii());

	config_set_int(config, (char *) "sharing/hide_dot_files",   hideHiddenCheck->isChecked());
	config_set_int(config, (char *) "main/follow_symlinks", followSymlinksCheck->isChecked());

	int interval = 0;
	int sync = syncCombo->currentItem();
	switch(sync)
	{
		case 0:
			interval = 0; break;
		case 1:
			interval = 3600; break;
		case 2:
			interval = 86400; break;
		case 3:
			interval = 604800; break;
	}
	config_set_int(config, (char *) "sharing/auto_resync_interval", interval);

	config_write(config);
	config_free(config);

	// OpenFT config
	filename = home + "/.giFT/OpenFT/OpenFT.conf";
	if(QFile::exists(filename))
	{
		config = config_new_ex((char *) filename.ascii(), false);
		config_set_str(config, (char *) "main/alias", (char *) userEdit->text().ascii());

		config_set_int(config, (char *) "main/class", checkSearchnode->isChecked() ? 3 : 1);
		config_set_int(config, (char *) "main/port", spinSearchPort->value());
		config_set_int(config, (char *) "main/port_http", spinHttpPort->value());

		config_write(config);
		config_free(config);
	}
}

// this slot gets called, when the settings are changed, therefore
// we also have to re-send the informations
void ApollonPreferencesDialog::saveConfig()
{
	KConfig *config = KGlobal::config();
	{
		KConfigGroupSaver saver(config, "Behaviour");

		config->writeEntry("shutApollon", removeSysTrayCheck->isChecked());
		emit shutApollon(removeSysTrayCheck->isChecked());

		config->writeEntry("Docked", startSysTrayCheck->isChecked());

		config->writeEntry("ShowPopups", notificationComboBox->currentItem());
		emit showPopUps(notificationComboBox->currentItem());

		config->writeEntry("StartPage", pageCombo->currentItem());

		config->writeEntry("KillDaemon", !killDaemonCheck->isChecked());
		emit killDaemon(!killDaemonCheck->isChecked());

		config->writeEntry("Docking", dockingEnabledCheck->isChecked());
		emit dockingEnabled(dockingEnabledCheck->isChecked());

		m_disabledPlugins = QString("");
		for(uint i = 0; i < pluginsList->count(); i++)
		{
			if(!(((PluginListItem *) pluginsList->item(i))->isEnabled()))
			{
				m_disabledPlugins += ((PluginListItem *) pluginsList->item(i))->text();
				if(i + 1 < pluginsList->count())
					m_disabledPlugins += QString(":");
			}
		}

		config->writeEntry("disabled_plugins", m_disabledPlugins);
		
		config->writeEntry("ProgressBarType", progressTypeCombo->currentItem());
		emit progressBarType(progressTypeCombo->currentItem());
		
	}

	KConfigGroupSaver saver(config, "giFT");

	config->writeEntry("AutoSearchInterval", autoSearchSpin->value());
	emit autoSearchInterval(autoSearchSpin->value());

	config->writeEntry("max_uploads", uploadsSpin->value());
	config->writeEntry("max_per_user", userUploadsSpin->value());
	config->writeEntry("downstream", downRestrictionSpin->value()*1024);
	config->writeEntry("upstream", upRestrictionSpin->value()*1024);

	config->sync(); // write data immediately to disk

	saveGiftConfig();

	if(m_giftChanged)
	{
		int answer = KMessageBox::questionYesNo(this, tr2i18n("You made some changes which can only be applied after reconnecting.\n"
		                                                      "Do you want to reconnect now?"), tr2i18n("Settings changes"));
		if(answer == KMessageBox::Yes)
		{
			emit restartDaemon();
		}
		m_giftChanged = false;
	}
}

void ApollonPreferencesDialog::downloadDir()
{
	KFileDialog dialog( downloadEdit->text().replace(QString("~"), home), QString("*"), this, "dirselect", true, 0);
	dialog.setMode(KFile::Directory);
	KURL url = dialog.getExistingDirectory();
	if(!url.isEmpty())
	{
		downloadEdit->setText(url.path());
	}
}

void ApollonPreferencesDialog::addSharedFolder()
{
	KFileDialog dialog(downloadEdit->text().replace(QString("~"), home), QString("*"), this, "dirselect", true, 0);
	dialog.setMode(KFile::Directory);
	KURL url = dialog.getExistingDirectory();
		
	if(!url.isEmpty())
		sharedFolderList->insertItem(url.path());
}

void ApollonPreferencesDialog::deleteSharedFolder()
{
	sharedFolderList->removeItem(sharedFolderList->currentItem());
}

void ApollonPreferencesDialog::newPlugin()
{
	QDir dir1("/usr/local/lib/giFT");
	QDir dir2("/usr/lib/giFT");
	QString path;
	if (dir1.exists() && dir2.exists() && dir1.count() > 2 && dir2.count() > 2) {
		int ret = KMessageBox::warningContinueCancel(this, i18n("The path to the installed plugins is ambiguous, you may adjust the correct path"
				"in the following dialog."), "Several paths found");
		if (ret == KMessageBox::Continue)
			path = KFileDialog::getOpenFileName(dir2.path(),"*.so");
		else
			return;
	}
	else	if (dir1.exists() && dir1.count() > 2)
		path = KFileDialog::getOpenFileName(dir1.path(),"*.so");
	else if (dir2.exists() && dir2.count() > 2)
		path = KFileDialog::getOpenFileName(dir2.path(),"*.so");
	else
		path = KFileDialog::getOpenFileName(QString::null,"*.so");
	
	
	if(!path.isEmpty())
	{
		QUrl url = QUrl(QString("file:") + path);
		QString file = url.fileName();
		if(file.contains("lib"))
		{
			path = file.remove("lib");
			path = path.remove(".so");
		}
		new PluginListItem(pluginsList, m_okPixmap, path);
	}
}

void ApollonPreferencesDialog::deletePlugin()
{
	pluginsList->removeItem(pluginsList->currentItem());
}

void ApollonPreferencesDialog::disablePlugin()
{
	int i = pluginsList->currentItem();
	PluginListItem *item = (PluginListItem *) pluginsList->item(i);
	QString text = item->text();

	pluginsList->removeItem(i);

	if(item->isEnabled())
	{
		enablePluginButton->setText(tr2i18n("&Enable"));
		PluginListItem *newItem = new PluginListItem(pluginsList, m_noPixmap, text);
		newItem->setEnabled(false);
	}
	else
	{
		enablePluginButton->setText(tr2i18n("D&isable"));
		PluginListItem *newItem = new PluginListItem(pluginsList, m_okPixmap, text);
		newItem->setEnabled(true);
	}
	pluginsList->sort(false);
}

void ApollonPreferencesDialog::enableButton(QListBoxItem *it)
{
	if(it)
	{
		PluginListItem *item = (PluginListItem *) it;
		if(item->isEnabled())
			enablePluginButton->setText(tr2i18n("D&isable"));
		else
			enablePluginButton->setText(tr2i18n("&Enable"));
	}
}

QString ApollonPreferencesDialog::incomingPath()
{
	m_incoming = m_incoming.replace(QString("~"), home);
	return m_incoming;
}

QString ApollonPreferencesDialog::completedPath()
{
	m_completed = m_completed.replace(QString("~"), home);
	return m_completed;
}

void ApollonPreferencesDialog::giftSettingsChanged()
{
	m_giftChanged = true;
}
