#include <qapplication.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qhgroupbox.h>
#include <qvgroupbox.h>
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qvbuttongroup.h>
#include <qlistview.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qlayout.h>
#include <qregexp.h>

#include "formatsconfig.h"
#include "configuration.h"

// FormatsListItem

FormatsListItem::FormatsListItem(const QString &fileExtension, const QString &mplayerArguments, QListView *parent)
	: QListViewItem(parent)
{
	setText(0, fileExtension);
	setText(1, mplayerArguments);
}

bool FormatsListItem::edit()
{
	FormatsEditorDialog editDialog(this);
	bool result = editDialog.exec() == QDialog::Accepted;
	return result;
}	


// FormatsFileExtensionValidator

FormatsFileExtensionValidator::FormatsFileExtensionValidator(QWidget *parent, const char *name)
	: QValidator(parent, name)
{
}

QValidator::State FormatsFileExtensionValidator::validate(QString &input, int &) const
{
	if (input[input.length() - 1] == ',' && input[input.length() - 2] != ',')
		return QValidator::Intermediate;
	else
	{
		QRegExp re("^([a-z0-9]+,)*[a-z0-9]+$");
		if (re.match(input) == 0)
			return QValidator::Acceptable;
		else
			return QValidator::Invalid;
	}
}
	
void FormatsFileExtensionValidator::fixup(QString &input) const
{
	if (input[input.length() - 1] == ',')
		input = input.left(input.length() - 1);
}


// FormatsEditorDialog

FormatsEditorDialog::FormatsEditorDialog(FormatsListItem *item, QWidget *parent, const char *name)
	:	QDialog(parent, name, true, 0),
		item_(item)
{
	setCaption("Format Editor");
	setSizeGripEnabled(false);
	
	QVBoxLayout *mainLayout = new QVBoxLayout(this);
	QGridLayout *gridLayout = new QGridLayout(this, 2, 2, 8);

	QLabel *fileExtensionsLabel = new QLabel("File Extensions:", this);
	fileExtensionsLineEdit_ = new QLineEdit(this);
	fileExtensionsLineEdit_->setFixedWidth(250);
	gridLayout->addWidget(fileExtensionsLabel, 0, 0);
	gridLayout->addWidget(fileExtensionsLineEdit_, 0, 1);
	
	QLabel *mplayerArgumentsLabel = new QLabel("MPlayer Arguments:", this);
	mplayerArgumentsLineEdit_ = new QLineEdit(this);
	mplayerArgumentsLineEdit_->setFixedWidth(250);
	gridLayout->addWidget(mplayerArgumentsLabel, 1, 0);
	gridLayout->addWidget(mplayerArgumentsLineEdit_, 1, 1);
	
	QPushButton *okButton = new QPushButton(tr("OK"), this);
	connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
	
	QPushButton *cancelButton = new QPushButton(tr("Cancel"), this);
	connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));

	QHBoxLayout *buttonsLayout = new QHBoxLayout(this, 8);
	buttonsLayout->setDirection(QBoxLayout::RightToLeft);
	buttonsLayout->addWidget(okButton, 0);
	buttonsLayout->addWidget(cancelButton, 0);
	
	mainLayout->addLayout(gridLayout);
	mainLayout->addLayout(buttonsLayout);
	
	fileExtensionsLineEdit_->setText(item_->text(0));
	fileExtensionsLineEdit_->setValidator(new FormatsFileExtensionValidator(fileExtensionsLineEdit_));
	mplayerArgumentsLineEdit_->setText(item_->text(1));
}
	
int FormatsEditorDialog::exec()
{
	int result = QDialog::exec();

	if (result == QDialog::Accepted)
	{
		QString fileExtensions = fileExtensionsLineEdit_->text();
		fileExtensionsLineEdit_->validator()->fixup(fileExtensions);
		item_->setText(0, fileExtensions);
		item_->setText(1, mplayerArgumentsLineEdit_->text());
		result = true;
	}

	return result;
}


// FormatsConfig

FormatsConfig::FormatsConfig(Configuration& config, QWidget *parent, const char *name)
	: QWidget(parent, name),
	  config_(config)
{
	createWidgets();
	setStatesByConfiguration(config);
}

void FormatsConfig::setStatesByConfiguration(const Configuration& config)
{
	if (&config != &config_)
		config_ = config;

	list->clear();
	
	for (int i = 0; i < config.formatFileExtensions.count(); ++i)
		new FormatsListItem(config.formatFileExtensions[i], config.formatMPlayerArguments[i], list);
}

void FormatsConfig::createWidgets()
{
	QVBoxLayout *mainLayout = new QVBoxLayout(this);

	QHBoxLayout *buttonLayout = new QHBoxLayout(this);
			
	QPushButton *editButton = new QPushButton(tr("Edit"), this);
	connect(editButton, SIGNAL(clicked()), this, SLOT(editSelectedFormat()));
	
	QPushButton *addButton = new QPushButton(tr("Add"), this);
	connect(addButton, SIGNAL(clicked()), this, SLOT(addNewFormat()));

	QPushButton *removeButton = new QPushButton(tr("Remove"), this);
	connect(removeButton, SIGNAL(clicked()), this, SLOT(removeSelectedFormat()));
	
	buttonLayout->addWidget(editButton);
	buttonLayout->addWidget(addButton);
	buttonLayout->addWidget(removeButton);

	mainLayout->addLayout(buttonLayout);

	// List
	list = new QListView(this);
	list->setAllColumnsShowFocus(true);
	list->addColumn(tr("File Extensions"));
	list->addColumn(tr("MPlayer Arguments"));
	connect(list, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(editFormat(QListViewItem *)));
	mainLayout->addWidget(list);
}

void FormatsConfig::saveStatesToConfiguration()
{
	config_.formatFileExtensions.clear();
	config_.formatMPlayerArguments.clear();
	
	for (QListViewItemIterator it(list); it.current(); ++it)
	{
		FormatsListItem *item = static_cast<FormatsListItem *>(it.current());
		config_.formatFileExtensions.append(item->text(0));
		config_.formatMPlayerArguments.append(item->text(1));
	}
}

void FormatsConfig::addNewFormat()
{
	FormatsListItem *item = new FormatsListItem("", "", list);
	if (!item->edit())
		delete item;
}

void FormatsConfig::removeSelectedFormat()
{
	if (list->selectedItem())
		delete list->selectedItem();
}

void FormatsConfig::editSelectedFormat()
{
	if (list->selectedItem())
		editFormat(list->selectedItem());
}

void FormatsConfig::editFormat(QListViewItem *item)
{
	static_cast<FormatsListItem *>(item)->edit();
}
