/*
	Copyright (C) 2022-2024 Mark Tyler

	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 3 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 in the file COPYING.
*/

#include "static.h"
#include "be.h"

#ifdef U_TK_QT5
	#include <mtqex5.h>
#endif

#ifdef U_TK_QT6
	#include <mtqex6.h>
#endif

#include <type_traits>



#define TEXT_TITLE_FLOAT	"Float"
#define TEXT_TITLE_DOUBLE	"Double"
#define TEXT_TITLE_INTEGER	"Integer"
#define TEXT_TITLE_RATIONAL	"Rational"
#define TEXT_TITLE_ERROR	"ERROR"



class MainWindow;
class DialogVars;



std::string choose_output_filename (
	QWidget		* parent,
	char	const	* title
	);

void report_file_error (
	QWidget			* parent,
	char		const	* message,
	std::string	const	& filename
	);



template < typename Tnum >
void save_a_number (
	QWidget		* const	parent,
	Tnum		const	& num,
	std::string	const	& filename
	)
{
	if ( 0 == filename.size() )
	{
		return;
	}

	if ( num.to_filename ( filename.c_str() ) )
	{
		report_file_error ( parent, "Unable to save file:", filename );
	}
}



template <typename Tnum>
std::string print_digits_label (
	Tnum	const	& num,
	int	const	size
	)
{
	char		buf[128];

	snprintf ( buf, sizeof(buf), "(%i sf, showing %i digit",
		(int)num.get_str_ndigits(), size );

	std::string str = ( buf );

	if ( size == 1 )
	{
		str += ")";
	}
	else
	{
		str += "s)";
	}

	return str;
}



class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	explicit MainWindow ( CommandLine & cline );
	~MainWindow ();

	MemPrefs const & get_mprefs() { return mprefs; }

private slots:
	void press_menu_quit ();
	void press_menu_preferences ();

	void press_help_about_qt ();
	void press_help_about ();

private:
	void create_menu ();

template < typename Tparser >
class TabUIelements
{
public:
	explicit TabUIelements ( MainWindow & mw )
		:
		mainwindow	( mw )
	{
		static_assert (
			std::is_same<Tparser, mtDW::FloatParser>::value
			|| std::is_same<Tparser, mtDW::DoubleParser>::value
			|| std::is_same<Tparser, mtDW::IntegerParser>::value
			|| std::is_same<Tparser, mtDW::RationalParser>::value
			, "TabUIelements: Unknown Type\n"
			);
	}

	void build ( QTabWidget * tabWidget );

	void click_evaluate ();
	void click_show_vars ();
	void click_show_funcs ();

/// ----------------------------------------------------------------------------

private:
	Tparser			m_parser;

	QGroupBox		* m_group_box	= nullptr;
	QPlainTextEdit		* m_text_input	= nullptr;
	QPlainTextEdit		* m_text_output	= nullptr;

	MainWindow		& mainwindow;
};

/// ----------------------------------------------------------------------------

	mtKit::UserPrefs	& uprefs;
	MemPrefs	const	& mprefs;

	mtDW::MathState		m_math;

	TabUIelements<mtDW::FloatParser>	m_ui_float;
	TabUIelements<mtDW::DoubleParser>	m_ui_double;
	TabUIelements<mtDW::IntegerParser>	m_ui_integer;
	TabUIelements<mtDW::RationalParser>	m_ui_rational;
};



class DialogVars : public QDialog
{
	Q_OBJECT

public:
	explicit DialogVars ( MainWindow * const mw )
		:
		QDialog		( mw ),
		m_mainwindow	( mw )
	{
	}

	void start ( mtDW::FloatParser const * parser );
	void start ( mtDW::DoubleParser const * parser );
	void start ( mtDW::IntegerParser const * parser );
	void start ( mtDW::RationalParser const * parser );

/// ----------------------------------------------------------------------------

	MainWindow		* m_mainwindow;
};

