/*
 * 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 "PlotStyleWidget.h"
#include "PlotStyle.h"

#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QGridLayout>
#include <QtGui/QSpinBox>

PlotStyleWidget::PlotStyleWidget(QWidget *parent)
: PlotOptionWidget(parent), plotStyle_(new PlotStyle)
{
	setWindowTitle(tr("Style"));
	setWhatsThis(tr("plot {with &lt;style&gt;}"));

	styleCheckBox = new QCheckBox;
	styleCheckBox->setText(tr("&Specify:"));

	styleComboBox = new QComboBox;
	for (int i = 0; !PlotStyle::STYLE[i].isEmpty(); i++) {
		styleComboBox->addItem(PlotStyle::STYLE[i]);
	}
	connect(styleCheckBox, SIGNAL(toggled(bool)),
			styleComboBox, SLOT(setEnabled(bool)));

	lineTypeCheckBox = new QCheckBox;
	lineTypeCheckBox->setText(tr("Specify a &line type:"));

	lineTypeSpinBox = new QSpinBox;
	connect(lineTypeCheckBox, SIGNAL(toggled(bool)),
			lineTypeSpinBox, SLOT(setEnabled(bool)));

	lineWidthCheckBox = new QCheckBox;
	lineWidthCheckBox->setText(tr("Specify l&ine width:"));

	lineWidthDoubleSpinBox = new QDoubleSpinBox;
	connect(lineWidthCheckBox, SIGNAL(toggled(bool)),
			lineWidthDoubleSpinBox, SLOT(setEnabled(bool)));

	pointTypeCheckBox = new QCheckBox;
	pointTypeCheckBox->setText(tr("Specify a &point type:"));

	pointTypeSpinBox = new QSpinBox;
	connect(pointTypeCheckBox, SIGNAL(toggled(bool)),
			pointTypeSpinBox, SLOT(setEnabled(bool)));

	pointSizeCheckBox = new QCheckBox;
	pointSizeCheckBox->setText(tr("Specify poi&nt size:"));

	pointSizeDoubleSpinBox = new QDoubleSpinBox;
	connect(pointSizeCheckBox, SIGNAL(toggled(bool)),
			pointSizeDoubleSpinBox, SLOT(setEnabled(bool)));

	connect(styleCheckBox, SIGNAL(toggled(bool)),
			this, SLOT(setWidget(bool)));

	QGridLayout *mainLayout = new QGridLayout;
	mainLayout->addWidget(styleCheckBox, 0, 0);
	mainLayout->addWidget(styleComboBox, 0, 1);
	mainLayout->addItem(new QSpacerItem(40, 20, 
				QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2);
	mainLayout->addWidget(lineTypeCheckBox, 1, 0);
	mainLayout->addWidget(lineTypeSpinBox, 1, 1);
	mainLayout->addWidget(lineWidthCheckBox, 2, 0);
	mainLayout->addWidget(lineWidthDoubleSpinBox, 2, 1);
	mainLayout->addWidget(pointTypeCheckBox, 3, 0);
	mainLayout->addWidget(pointTypeSpinBox, 3, 1);
	mainLayout->addWidget(pointSizeCheckBox, 4, 0);
	mainLayout->addWidget(pointSizeDoubleSpinBox, 4, 1);
	mainLayout->addItem(new QSpacerItem(20, 40,
				QSizePolicy::Minimum, QSizePolicy::Expanding), 5, 0);

	setLayout(mainLayout);
}

PlotStyleWidget::~PlotStyleWidget()
{
	delete plotStyle_;
}

void PlotStyleWidget::setPlotStyle(const PlotStyle &plotStyle)
{
	*plotStyle_ = plotStyle;
	setWidget();
}

const PlotStyle &PlotStyleWidget::plotStyle() const
{
	return *plotStyle_;
}

void PlotStyleWidget::apply()
{
	int style = styleCheckBox->isChecked() ?
		styleComboBox->currentIndex() : -1;
	plotStyle_->setStyle(style);

	int lineType = lineTypeCheckBox->isChecked() ?
		lineTypeSpinBox->value() : -1;
	plotStyle_->setLineType(lineType);

	double lineWidth = lineWidthCheckBox->isChecked() ?
		lineWidthDoubleSpinBox->value() : -1;
	plotStyle_->setLineWidth(lineWidth);

	int pointType = pointTypeCheckBox->isChecked() ?
		pointTypeSpinBox->value() : -1;
	plotStyle_->setPointType(pointType);

	double pointSize = pointSizeCheckBox->isChecked() ?
		pointSizeDoubleSpinBox->value() : -1;
	plotStyle_->setPointSize(pointSize);
}

void PlotStyleWidget::setWidget(bool isEnabled)
{
	lineTypeCheckBox->setEnabled(isEnabled);
	lineTypeSpinBox->setEnabled(isEnabled 
			&& lineTypeCheckBox->isChecked());

	lineWidthCheckBox->setEnabled(isEnabled);
	lineWidthDoubleSpinBox->setEnabled(isEnabled
			&& lineWidthCheckBox->isChecked());

	pointTypeCheckBox->setEnabled(isEnabled);
	pointTypeSpinBox->setEnabled(isEnabled
			&& pointTypeCheckBox->isChecked());

	pointSizeCheckBox->setEnabled(isEnabled);
	pointSizeDoubleSpinBox->setEnabled(isEnabled
			&& pointSizeCheckBox->isChecked());
}

void PlotStyleWidget::setWidget()
{
	int style = plotStyle_->style();
	bool hasStyle = (style >= 0);
	styleCheckBox->setChecked(hasStyle);
	styleComboBox->setEnabled(hasStyle);

	lineTypeCheckBox->setEnabled(hasStyle);
	lineTypeSpinBox->setEnabled(hasStyle);

	lineWidthCheckBox->setEnabled(hasStyle);
	lineWidthDoubleSpinBox->setEnabled(hasStyle);

	pointTypeCheckBox->setEnabled(hasStyle);
	pointTypeSpinBox->setEnabled(hasStyle);

	pointSizeCheckBox->setEnabled(hasStyle);
	pointSizeDoubleSpinBox->setEnabled(hasStyle);

	if (hasStyle) {
		styleComboBox->setCurrentIndex(style);

		int lineType = plotStyle_->lineType();
		bool hasLineType = (lineType >= 0);
		lineTypeCheckBox->setChecked(hasLineType);
		lineTypeSpinBox->setEnabled(hasLineType);
		if (hasLineType) {
			lineTypeSpinBox->setValue(lineType);
		}

		double lineWidth = plotStyle_->lineWidth();
		bool hasLineWidth = (lineWidth >= 0);
		lineWidthCheckBox->setChecked(hasLineWidth);
		lineWidthDoubleSpinBox->setEnabled(hasLineWidth);
		if (hasLineWidth) {
			lineWidthDoubleSpinBox->setValue(lineWidth);
		}

		int pointType = plotStyle_->pointType();
		bool hasPointType = (pointType >= 0);
		pointTypeCheckBox->setChecked(hasPointType);
		pointTypeSpinBox->setEnabled(hasPointType);
		if (hasPointType) {
			pointTypeSpinBox->setValue(pointType);
		}

		double pointSize = plotStyle_->pointSize();
		bool hasPointSize = (pointSize >= 0);
		pointSizeCheckBox->setChecked(hasPointSize);
		pointSizeDoubleSpinBox->setEnabled(hasPointSize);
		if (hasPointSize) {
			pointSizeDoubleSpinBox->setValue(pointSize);
		}
	}
}
