/*****************************************************************************
 *
 *  tunesettingsdialog.cpp -- Tune encoder settings.
 *
 *  Copyright (C) 2010 Starbuck <starbuck@labdv.com>
 *  All rights reserved.
 *
 *  This file is part of the Gui4 module of the DVDx 4 application.
 *
 *  GNU Lesser General Public License Usage
 *  This file may be used under the terms of the GNU Lesser General
 *  Public License version 2.1 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.LGPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU Lesser General Public License version 2.1 requirements
 *  will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 *  GNU General Public License Usage
 *  Alternatively, this file may be used under the terms of the GNU
 *  General Public License version 3.0 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.GPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU General Public License version 3.0 requirements will be
 *  met: http://www.gnu.org/copyleft/gpl.html.
 *
 *****************************************************************************/

#include "tunesettingsdialog.h"
#include "../video/video_functions.h"
#include <QDebug>

TuneSettingsDialog::TuneSettingsDialog(encoder_video_settings_t::filter_t *filters,
			QString *videoCodecName, 
			QMultiMap<QString, QString> *videoOptions, 
			QString *audioCodecName, 
			QMultiMap<QString, QString> *audioOptions,
			QWidget *parent)
	: QDialog(parent)
{
	setWindowTitle( tr("Encoder user settings") );
	
	videoFilters = filters;
	outputVideoOptions = videoOptions;
	outputAudioOptions = audioOptions;

	videoSignalMapper = new QSignalMapper(this);
	audioSignalMapper = new QSignalMapper(this);
	videoEditSignalMapper = new QSignalMapper(this);
	audioEditSignalMapper = new QSignalMapper(this);

	preprocessingGroup = new QGroupBox(tr("Video input pre-processing options"));
	preprocessingVLayout = new QVBoxLayout(preprocessingGroup);

	noskipHLayout = new QHBoxLayout;
	noskipCheckBox = new QCheckBox(preprocessingGroup);
	noskipCheckBox->setText( tr("Do not skip frames") );
	noskipCheckBox->setToolTip( tr("May improve audio/video synchronization") );
	noskipCheckBox->setChecked( videoFilters->noskip );
	noskipCheckBox->setDisabled(true); //*Alpha1 (bug workaround) to ensure a -vf before -vf-add

	noskipHLayout->addWidget(noskipCheckBox);

	preprocessingVLayout->addLayout(noskipHLayout);

	harddupHLayout = new QHBoxLayout;
	harddupCheckBox = new QCheckBox(preprocessingGroup);
	harddupCheckBox->setText( tr("Resubmit duplicate frames") );
	harddupCheckBox->setToolTip( tr("May iImprove audio/video synchronization") );
	harddupCheckBox->setChecked( videoFilters->harddup );

	harddupHLayout->addWidget(harddupCheckBox);

	preprocessingVLayout->addLayout(harddupHLayout);

	cliGroup = new QGroupBox(tr("Extra command line options"));
	cliVLayout = new QVBoxLayout(cliGroup);

	videoCodecLabel = new QLabel(cliGroup);
	videoCodecLabel->setText( tr("Video codec: %1").arg(*videoCodecName) );
	
	cliVLayout->addWidget(videoCodecLabel);

	QMapIterator<QString, QString> video(*outputVideoOptions);

	for (int i = 1; i <= outputVideoOptions->size() + 1; ++i)
	{
		videoHLayoutList << new QHBoxLayout;
		videoOptionEditList << new QLineEdit(cliGroup);
		videoParamsEditList << new QLineEdit(cliGroup);
		videoButtonList << new QPushButton(cliGroup);

		videoOptionEditList.last()->setFixedWidth( 80 );
		videoOptionEditList.last()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);

		videoParamsEditList.last()->setMinimumWidth( 160 );
		videoParamsEditList.last()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

		videoButtonList.last()->setFixedWidth( 24 );
		videoButtonList.last()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);

		videoHLayoutList.last()->addWidget( videoOptionEditList.last() );
		videoHLayoutList.last()->addWidget( videoParamsEditList.last() );
		videoHLayoutList.last()->addWidget( videoButtonList.last() );

		if ( video.hasNext() )
		{
			video.next();
			videoOptionEditList.last()->setText( video.key() );
			videoParamsEditList.last()->setText( video.value() );
		}
		else
		{
			videoParamsEditList.last()->setReadOnly(true);
			videoParamsEditList.last()->setToolTip( tr("Enter an option in left field before its parameters here.") );
		}

		videoButtonList.last()->setText( "-" );
		videoButtonList.last()->setToolTip( tr("Clear this option.") );

		cliVLayout->addItem(videoHLayoutList.last());

		connect(videoOptionEditList.last(), SIGNAL(editingFinished()), videoEditSignalMapper, SLOT(map()));
		videoEditSignalMapper->setMapping(videoOptionEditList.last(), videoOptionEditList.size());

		connect(videoButtonList.last(), SIGNAL(clicked()), videoSignalMapper, SLOT(map()));
		videoSignalMapper->setMapping(videoButtonList.last(), videoButtonList.size());
	}

	audioCodecLabel = new QLabel(cliGroup);
	audioCodecLabel->setText( tr("Audio codec: %1").arg(*audioCodecName) );
	
	cliVLayout->addWidget(audioCodecLabel);

	QMapIterator<QString, QString> audio(*outputAudioOptions);

	for (int i = 1; i <= outputAudioOptions->size() + 1; ++i)
	{
		audioHLayoutList << new QHBoxLayout;
		audioOptionEditList << new QLineEdit(cliGroup);
		audioParamsEditList << new QLineEdit(cliGroup);
		audioButtonList << new QPushButton(cliGroup);

		audioOptionEditList.last()->setFixedWidth( 80 );
		audioOptionEditList.last()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);

		audioParamsEditList.last()->setMinimumWidth( 160 );
		audioParamsEditList.last()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

		audioButtonList.last()->setFixedWidth( 24 );
		audioButtonList.last()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);

		audioHLayoutList.last()->addWidget( audioOptionEditList.last() );
		audioHLayoutList.last()->addWidget( audioParamsEditList.last() );
		audioHLayoutList.last()->addWidget( audioButtonList.last() );

		if ( audio.hasNext() )
		{
			audio.next();
			audioOptionEditList.last()->setText( audio.key() );
			audioParamsEditList.last()->setText( audio.value() );
		}
		else
		{
			audioParamsEditList.last()->setReadOnly(true);
			audioParamsEditList.last()->setToolTip( tr("Enter an option in left field before its parameters here.") );
		}

		audioButtonList.last()->setText( "-" );
		audioButtonList.last()->setToolTip( tr("Clear this option.") );

		cliVLayout->addItem(audioHLayoutList.last());

		connect(audioOptionEditList.last(), SIGNAL(editingFinished()), audioEditSignalMapper, SLOT(map()));
		audioEditSignalMapper->setMapping(audioOptionEditList.last(), audioButtonList.size());

		connect(audioButtonList.last(), SIGNAL(clicked()), audioSignalMapper, SLOT(map()));
		audioSignalMapper->setMapping(audioButtonList.last(), audioButtonList.size());
	}

	buttonBox = new QDialogButtonBox(this);
	buttonBox->setFocusPolicy(Qt::StrongFocus);
	buttonBox->setOrientation(Qt::Horizontal);
	buttonBox->setStandardButtons(QDialogButtonBox::Ok);
	buttonBox->setCenterButtons(true);

	mainLayout = new QVBoxLayout;
	mainLayout->addWidget(preprocessingGroup);
	mainLayout->addWidget(cliGroup);
	mainLayout->addWidget(buttonBox);

	setLayout(mainLayout);

	connect(noskipCheckBox, SIGNAL(clicked()),
			this, SLOT(noskipCheckBoxClicked()));	
	connect(harddupCheckBox, SIGNAL(clicked()),
			this, SLOT(harddupCheckBoxClicked()));	

	connect(videoSignalMapper, SIGNAL(mapped(const int)),
			this, SLOT(videoButtonClicked(const int)));	
	connect(audioSignalMapper, SIGNAL(mapped(const int)),
			this, SLOT(audioButtonClicked(const int)));	

	connect(videoEditSignalMapper, SIGNAL(mapped(const int)),
			this, SLOT(videoEditFinished(const int)));	
	connect(audioEditSignalMapper, SIGNAL(mapped(const int)),
			this, SLOT(audioEditFinished(const int)));	

	connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
	connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

	setAttribute(Qt::WA_AlwaysShowToolTips);
	setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
	setMinimumWidth( 360 );
}

void TuneSettingsDialog::accept()
{
	outputVideoOptions->clear();

	for ( int i = videoOptionEditList.count() - 1; i >= 0; --i)
	{
		QString key = videoOptionEditList[i]->text();

		if ( !key.isEmpty() ) outputVideoOptions->insert( key, videoParamsEditList[i]->text() );
	}

	outputAudioOptions->clear();

	for ( int i = audioOptionEditList.count() - 1; i >= 0; --i)
	{
		QString key = audioOptionEditList[i]->text();

		if ( !key.isEmpty() ) outputAudioOptions->insert( key, audioParamsEditList[i]->text() );
	}

	QDialog::accept();
}

void TuneSettingsDialog::harddupCheckBoxClicked()
{
	videoFilters->harddup = harddupCheckBox->isChecked();
}

void TuneSettingsDialog::noskipCheckBoxClicked()
{
	videoFilters->noskip = noskipCheckBox->isChecked();
}

void TuneSettingsDialog::videoButtonClicked(const int value)
{
	// Clear related options
	videoOptionEditList.at( value - 1 )->clear();
	videoParamsEditList.at( value - 1 )->clear();
}

void TuneSettingsDialog::audioButtonClicked(const int value)
{
	// Clear related options
	audioOptionEditList.at( value - 1 )->clear();
	audioParamsEditList.at( value - 1 )->clear();
}

void TuneSettingsDialog::videoEditFinished(const int value)
{
	videoOptionEditList.at( value - 1 )->setText( videoOptionEditList.at( value - 1 )->text().trimmed() );

	// Enable related parameters
	if ( !videoOptionEditList.at( value - 1 )->text().isEmpty() )
	{
		videoParamsEditList.at( value - 1 )->setReadOnly(false);
	}
	else
	{
		videoParamsEditList.at( value - 1 )->setReadOnly(true);
	}

}

void TuneSettingsDialog::audioEditFinished(const int value)
{
	audioOptionEditList.at( value - 1 )->setText( audioOptionEditList.at( value - 1 )->text().trimmed() );

	// Enable related parameters
	if ( !audioOptionEditList.at( value - 1 )->text().isEmpty() )
	{
		audioParamsEditList.at( value - 1 )->setReadOnly(false);
	}
	else
	{
		audioParamsEditList.at( value - 1 )->setReadOnly(true);
	}
}
