/*
 * Cueplot: a GUI front-end to gnuplot
 * Copyright (C) 2007, 2008 Muneyuki Noguchi
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, 
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "FitBasicWidget.h"
#include "FileLineEdit.h"

#include <QtCore/QCoreApplication>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QFileDialog>
#include <QtGui/QGroupBox>
#include <QtGui/QGridLayout>
#include <QtGui/QPushButton>
#include <QtGui/QRadioButton>
#include <QtGui/QVBoxLayout>

FitBasicWidget::FitBasicWidget(QWidget *parent)
: QWidget(parent)
{
	setWindowTitle(tr("Basic"));
	setWhatsThis(tr("fit &lt;function&gt; '&lt;datafile&gt;'<br>"
				"via '&lt;parameter file&gt;'<br>"
				"| &lt;var1&gt;{,&lt;var2&gt;,...}"));

	nameLineEdit = new QLineEdit;
	connect(nameLineEdit, SIGNAL(textChanged(const QString &)),
			this, SIGNAL(optionChanged()));

	QLabel *nameLabel = new QLabel;
	nameLabel->setText(tr("Function &name:"));
	nameLabel->setBuddy(nameLineEdit);

	functionLineEdit = new QLineEdit;
	connect(functionLineEdit, SIGNAL(textChanged(const QString &)),
			this, SIGNAL(optionChanged()));

	QLabel *functionLabel = new QLabel;
	functionLabel->setText(tr("F&unction:"));
	functionLabel->setBuddy(functionLineEdit);

	QLabel *lvalueLabel = new QLabel;
	lvalueLabel->setText("<big><strong>=</strong></big>");
	lvalueLabel->setSizePolicy(
			QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));

	dataFileLineEdit = new FileLineEdit("fit");
	connect(dataFileLineEdit, SIGNAL(textChanged(const QString &)),
			this, SIGNAL(optionChanged()));

	QLabel *dataFileLabel = new QLabel;
	dataFileLabel->setSizePolicy(
			QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed));
	dataFileLabel->setText(tr("&Data file:"));
	dataFileLabel->setBuddy(dataFileLineEdit);

	QPushButton *getDatafilePushButton = new QPushButton;
	getDatafilePushButton->setSizePolicy(
			QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
	connect(getDatafilePushButton, SIGNAL(clicked()),
			SLOT(openDataFile()));
	getDatafilePushButton->setText(tr("&Open..."));

	paramFileRadioButton = new QRadioButton;
	paramFileRadioButton->setText(tr("&Parameter file:"));
	connect(paramFileRadioButton, SIGNAL(toggled(bool)),
			this, SIGNAL(optionChanged()));

	paramFileLineEdit = new FileLineEdit("fit_via");
	paramFileLineEdit->setEnabled(false);
	connect(paramFileRadioButton, SIGNAL(toggled(bool)),
			paramFileLineEdit, SLOT(setEnabled(bool)));
	connect(paramFileLineEdit, SIGNAL(textChanged(const QString &)),
			this, SIGNAL(optionChanged()));

	QPushButton *getParamFilePushButton = new QPushButton;
	getParamFilePushButton->setEnabled(false);
	getParamFilePushButton->setText(tr("Op&en..."));
	connect(paramFileRadioButton, SIGNAL(toggled(bool)),
			getParamFilePushButton, SLOT(setEnabled(bool)));
	connect(getParamFilePushButton, SIGNAL(clicked()),
			SLOT(openParamFile()));

	paramCSLRadioButton = new QRadioButton;
	paramCSLRadioButton->setText(tr("Co&mma seperated list:"));
	paramCSLRadioButton->setChecked(true);

	paramCSLLineEdit = new QLineEdit;
	connect(paramCSLRadioButton, SIGNAL(toggled(bool)),
			paramCSLLineEdit, SLOT(setEnabled(bool)));
	connect(paramCSLLineEdit, SIGNAL(textChanged(const QString &)),
			this, SIGNAL(optionChanged()));

	QGridLayout *funcFileLayout = new QGridLayout;
	funcFileLayout->addWidget(nameLabel, 0, 0);
	funcFileLayout->addWidget(nameLineEdit, 0, 1, 1, 2);
	funcFileLayout->addWidget(functionLabel, 1, 0);
	funcFileLayout->addWidget(lvalueLabel, 1, 1);
	funcFileLayout->addWidget(functionLineEdit, 1, 2, 1, 3);
	funcFileLayout->addWidget(dataFileLabel, 2, 0);
	funcFileLayout->addWidget(dataFileLineEdit, 2, 1, 1, 3);
	funcFileLayout->addWidget(getDatafilePushButton, 2, 4);

	QGridLayout *paramLayout = new QGridLayout;
	paramLayout->addWidget(paramFileRadioButton, 0, 0, 1, 3);
	paramLayout->addItem(new QSpacerItem(20, 20, 
				QSizePolicy::Fixed, QSizePolicy::Minimum), 1, 0);
	paramLayout->addWidget(paramFileLineEdit, 1, 1);
	paramLayout->addWidget(getParamFilePushButton, 1, 2);
	paramLayout->addWidget(paramCSLRadioButton, 2, 0, 1, 2);
	paramLayout->addItem(new QSpacerItem(20, 20,
				QSizePolicy::Fixed, QSizePolicy::Minimum), 3, 0);
	paramLayout->addWidget(paramCSLLineEdit, 3, 1, 1, 2);

	QGroupBox *paramGroupBox = new QGroupBox(tr("Parameters"));
	paramGroupBox->setLayout(paramLayout);

	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->setMargin(0);
	mainLayout->addLayout(funcFileLayout);
	mainLayout->addWidget(paramGroupBox);
	mainLayout->addStretch();

	setLayout(mainLayout);
}

void FitBasicWidget::setFitFunctionName(const QString &functionName)
{
	nameLineEdit->setText(functionName);
}

QString FitBasicWidget::fitFunctionName() const
{
	return nameLineEdit->text();
}

void FitBasicWidget::setFitFunction(const QString &function)
{
	functionLineEdit->setText(function);
}

QString FitBasicWidget::fitFunction() const
{
	return functionLineEdit->text();
}

void FitBasicWidget::setFitDataFile(const QString &file)
{
	dataFileLineEdit->setText(file);
}

QString FitBasicWidget::fitDataFile() const
{
	return dataFileLineEdit->text();
}

void FitBasicWidget::setFitParameterFile(bool isFile)
{
	if (isFile) {
		paramFileRadioButton->setChecked(true);
	} else {
		paramCSLRadioButton->setChecked(true);
	}
}

bool FitBasicWidget::isFitParameterFile() const
{
	return paramFileRadioButton->isChecked();
}

void FitBasicWidget::setFitParameterFile(const QString &file)
{
	paramFileLineEdit->setText(file);
}

QString FitBasicWidget::fitParameterFile() const
{
	return paramFileLineEdit->text();
}

void FitBasicWidget::setFitVariable(const QStringList &var)
{
	paramCSLLineEdit->setText(var.join(","));
}

QStringList FitBasicWidget::fitVariable() const
{
	return paramCSLLineEdit->text().split(",");
}

void FitBasicWidget::openDataFile()
{
	QString file = QFileDialog::getOpenFileName(this,
			tr("Open a data file") + " - "
			+ QCoreApplication::applicationName(),
			dataFileLineEdit->file());
	if (!file.isNull()) {
		dataFileLineEdit->setFile(file);
	}
}

void FitBasicWidget::openParamFile()
{
	QString file = QFileDialog::getOpenFileName(this,
			tr("Open a parameter file") + " - " 
			+ QCoreApplication::applicationName(),
			paramFileLineEdit->file());
	if (!file.isNull()) {
		paramFileLineEdit->setFile(file);
	}
}

bool FitBasicWidget::canFit() const
{
	if (nameLineEdit->text().isEmpty() 
			|| functionLineEdit->text().isEmpty() 
			|| dataFileLineEdit->text().isEmpty()) {
		return false;
	}
	if (paramFileRadioButton->isChecked()) {
		return !paramFileLineEdit->text().isEmpty();
	}
	if (paramCSLRadioButton->isChecked()) {
		return !paramCSLLineEdit->text().isEmpty();
	}
	return false;
}
