/***************************************************************************
    File                 : FitDialog.h
    Project              : SciDAVis
    --------------------------------------------------------------------
    Copyright            : (C) 2006 by Ion Vasilief, Tilman Benkert
    Email (use @ for *)  : ion_vasilief*yahoo.fr, thzs*gmx.net
    Description          : Fit Wizard

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

/***************************************************************************
 *                                                                         *
 *  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                                           *
 *                                                                         *
 ***************************************************************************/
#ifndef FITDIALOG_H
#define FITDIALOG_H

#include "Graph.h"

class QPushButton;
class QLineEdit;
class QComboBox;
class QStackedWidget;
class QWidget;
class QTextEdit;
class QListWidget;
class QCheckBox;
class QTableWidget;
class QSpinBox;
class QLabel;
class QRadioButton;
class QLineEdit;
class ColorButton;
class Fit;

//! Fit Wizard
class FitDialog : public QDialog
{
    Q_OBJECT

public:
    FitDialog(QWidget* parent = 0, Qt::WindowFlags fl = 0 );

protected:
	//! On closing show the fit function in the plot window if that option is selected
	void closeEvent (QCloseEvent * e );
	//! Initialized the widget for the first dialog page
    void initFitPage();
	//! Initialized the widget for the second dialog page
	void initEditPage();
	//! Initialized the widget for the third dialog page
	void initAdvancedPage();

public slots:
	//! Start the actual fitting
	void accept();
	//! Add a list of user defined functions
	void addUserFunctions(const QStringList& list);
	//! Clear the list of user defined functions
	void clearUserFunctions();
    //! Clears the function editor, the parameter names and the function name
    void resetFunction();
	//! Show the fit page
	void showFitPage();
	//! Show the edit function page
	void showEditPage();
	//! Show the advanced options page
	void showAdvancedPage();
	//! Populate the functions list with functions from the given 'category'
	void showFunctionsList(int category);
	//! Populate the functions list with functions from MyParser
	void showParseFunctions();
	//! Populate the functions list with user-defined functions
	void showUserFunctions();
	//! Load the fit plugins
	void loadPlugins();
	//! Populate the expression text box according to the given function
	void showExpression(int function);
	//! Paste the expression of the current function into the editing text box
	void pasteExpression();
	//! Paste the name of the current function into the editing text box
	void pasteFunctionName();
	//! Toggle between predefined function and function editing
	void setFunction(bool ok);
	//! Save the user-defined function
	void saveUserFunction();
	//! Remove a user-defined function
	void removeUserFunction();
	//! Populate the list of build-in function names
	void setBuiltInFunctionNames();
	//! Populate the list of build-in function
	void setBuiltInFunctions();
	//! Check whether the given function contains a user-defined function
	bool containsUserFunctionName(const QString& function);
	//! Set the graph that is to be fitted
	void setGraph(Graph *g);
	//! Read the range of curve 'curveName' and set the from/to fields
	void activateCurve(const QString& curveName);
	//! Let the user select the Plugin folder
	void choosePluginsFolder();
	//! Check the validity of the initial values
	bool validInitialValues();
	//! Read the selected data range from the graph
	void changeDataRange();
	//! Fit using a built-in function
	void fitBuiltInFunction(const QString& function, double* initVal);

	//! Populate the list of tables containing data displayed in the corresponding graph
	void setSrcTables(QList<MyWidget*>* tables);
	//! Select a table from the source tables list
	void selectSrcTable(int tabnr);
	//! Enable/disable widgets for selection of custom error source.
	void yErrorSourceChanged(int index);
	//! Enable the X points spin box
	void showPointsBox(bool);
	//! Display the parameters table
	void showParametersTable();
	//! Display the covariance matrix
	void showCovarianceMatrix();

	//! Applies the user changes to the numerical format of the output results
	void applyChanges();

	//! Deletes the result fit curves from the plot
	void deleteFitCurves();

private slots:
    //! Enable the "Apply" button
	void enableApplyChanges(int = 0);

signals:
	void clearFunctionsList();
	void saveFunctionsList(const QStringList&);

private:
    Fit *d_fitter;
	Graph *d_graph;
	QStringList d_user_functions, d_user_function_names, d_user_function_params;
	QStringList d_built_in_function_names, d_built_in_functions;
	QStringList d_plugin_function_names, d_plugin_functions, d_plugin_files_list, d_plugin_params;
	QList<MyWidget*> *d_src_table;

    QCheckBox* boxUseBuiltIn;
	QStackedWidget* tw;
    QPushButton* buttonOk;
	QPushButton* buttonCancel1;
	QPushButton* buttonCancel2;
	QPushButton* buttonCancel3;
	QPushButton* buttonAdvanced;
	QPushButton* buttonClear;
    QPushButton* buttonClearUsrList;
	QPushButton* buttonPlugins;
	QPushButton* btnBack;
	QComboBox* boxCurve;
	QComboBox* boxAlgorithm;
	QTableWidget* boxParams;
	QLineEdit* boxFrom;
	QLineEdit* boxTo;
	QLineEdit* boxTolerance;
	QSpinBox* boxPoints, *generatePointsBox, *boxPrecision, *polynomOrderBox;
	QWidget *fitPage, *editPage, *advancedPage;
	QTextEdit *editBox, *explainBox, *boxFunction;
	QListWidget *categoryBox, *funcBox;
	QLineEdit *boxName, *boxParam;
	QLabel *lblFunction, *lblPoints, *polynomOrderLabel;
	QPushButton *btnAddFunc, *btnDelFunc, *btnContinue, *btnApply;
	QPushButton *buttonEdit, *btnAddTxt, *btnAddName, *btnDeleteFitCurves;
	ColorButton* btnColor;
	QComboBox *boxYErrorSource, *tableNamesBox, *colNamesBox;
	QRadioButton *generatePointsBtn, *samePointsBtn;
	QPushButton *btnParamTable, *btnCovMatrix;
	QLineEdit *covMatrixName, *paramTableName;
	QCheckBox *plotLabelBox, *logBox, *scaleErrorsBox;
};

#endif // FITDIALOG_H
