/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * main.cc
 * Copyright (C) 2020-2024 Burkard Lutz <b.lutz@online.de>
 *
 * galvani 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.
 *
 * galvani 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, see <http://www.gnu.org/licenses/>.
 */

#include <gtkmm.h>
#include <iostream>
#include <ctime>
#include <filesystem>
#include <sys/types.h>
#include <fstream>

#include "config.h"
#include "main.h"
#include <glibmm/i18n.h>
#include <locale.h>

namespace fs = std::filesystem;

#ifdef ENABLE_NLS
#  include <libintl.h>
#endif


AppGalvani::AppGalvani()
: Gtk::Application("com.gitlab.galvani")
{
  Glib::set_application_name("Galvani");
}

Glib::RefPtr<AppGalvani> AppGalvani::create()
{
  return Glib::make_refptr_for_instance<AppGalvani>( new AppGalvani() );
}


void AppGalvani::create_window ()
{
	main_win = new Main_Window;
	add_window (*main_win);
	set_menubar (main_win->menu);
	main_win->set_visible (true);
}

void AppGalvani::on_activate ()
{
	create_window ();

	//add actions to app
	add_action("quit", sigc::ptr_fun(app_quit));


	//define shortcuts
	set_accel_for_action("win.new", "<Primary>n");
	set_accel_for_action("win.open", "<Primary>o");
	set_accel_for_action("win.save", "<Primary>s");
	set_accel_for_action("win.export_diag", "<Primary>e");
	set_accel_for_action("win.print", "<Primary>p");
	set_accel_for_action("app.quit", "<Primary>q");
	set_accel_for_action("win.mess_start", "Return");
	set_accel_for_action("win.mess_stop", "space");
	set_accel_for_action("app.help", "F1");

	//Make directories
	homedir = getenv("HOME");
	confdir = homedir;
	confdir.append("/.galvani");
	workdir = homedir;
	workdir.append("/galvani");
	datadir = workdir;
	datadir.append("/data");
        dmmdir = workdir;
        dmmdir.append ("/dmm");
	tmpdir = "/tmp/galvani";
	try
	{
		if (!fs::exists(workdir))
		{
			fs::create_directory (workdir);
                        fs::create_directory (dmmdir);
			fs::copy (PACKAGE_DATA_DIR"/dmm", dmmdir, fs::copy_options::recursive);
		}

	}
	catch (fs::filesystem_error const& ex) {error_msg(ex.what());}
	try
	{
		if (!fs::exists(datadir)) fs::create_directory (datadir);
		if (!fs::exists(confdir)) fs::create_directory (confdir);
		if (!fs::exists(tmpdir)) fs::create_directory (tmpdir);
		fs::current_path (datadir);
	}
	catch (fs::filesystem_error const& ex) {error_msg(ex.what());}

	//Make or read ini-file
	ini_filename = confdir + "/galvani.ini";
	ini_file.open (ini_filename, std::ios_base::in);
	if (!ini_file.is_open())
	{
		ini_file.open (ini_filename, std::ios_base::out); //create ini-file
		try
		{
			ini_file << "autosave: "<< main_win->autosave << "\n";
			ini_file << "autoload: "<< main_win->autoload << "\n";
			ini_file << "display: "<< main_win->show_display << "\n";
		}
		catch (fs::filesystem_error const& ex) {error_msg(ex.what());}
		ini_file.close();
		main_win->autosave = false;
		main_win->autoload = false;
		full_screen = false;
		main_win->show_display = true;
	}
	else
	{
		if (read_ini ("autosave: ") == "1") main_win->autosave = true; else main_win->autosave = false;
		if (read_ini ("autoload: ") == "1") main_win->autoload = true; else main_win->autoload = false;
		if (read_ini ("display: ") == "1") main_win->show_display = true; else main_win->show_display = false;
		if (read_ini ("fullscreen: ") == "1") full_screen = true; else full_screen = false;
		mainwin_width = get_intstr(read_ini ("width: "));
		mainwin_height = get_intstr(read_ini ("height: "));
		ini_file.close();
	}
	main_win->display_toggle->change_state (main_win->show_display);
	main_win->toggle_autoload->change_state (main_win->autoload);
	main_win->toggle_autosave->change_state (main_win->autosave);
	if (main_win->autoload) main_win->options_dialog->load_all_options ();

	// set main window width and height
	if (full_screen) main_win->maximize ();
	else // define minimum width and height
	{
		if ((mainwin_width > 600) && (mainwin_height > 400)) main_win->set_default_size (mainwin_width, mainwin_height);
	}

}

AppGalvani::~AppGalvani ()
{
}


Project::Project ()
{
	datum = "";
	title = "";
	funktion_x = _("Time");
	funktion_y = _("DC Voltage");
	unit_x = "s";
	unit_y = "V";
	comment = "";
	evalresults = "";
 }

Project::~Project()
{
}

int
main (int argc, char *argv[])
{
	Glib::set_init_to_users_preferred_locale(false);	//set decimal point to '.'
	auto app = AppGalvani::create();

	setlocale (LC_ALL, "");
	bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
	textdomain(GETTEXT_PACKAGE);
	// initialize Measurement (Projekt)
	m_functions = {_("Time"),_("DC Voltage"),_("AC Voltage"),_("DC Current"),_("AC Current"),
	_("Resistance"),_("Conductivity"),_("pH"),_("Temperature")};
	acid = {
	{_("Hydrochloric acid"),1,-6.0},
	{_("Hydrobromic acid"),1,-6.0},
	{_("Bromic acid"),1,0.0},
	{_("Acetic acid"),1,4.76},
	{_("Hypochloric acid"),1,7.25},
	{_("Chloric acid"),1,0},
	{_("Hydrofluoric acid"),1,3.14},
	{_("Hydroiodic acid"),1,-8.0},
	{_("Iodic acid"),1,0.0},
	{_("Nitrous acid"),1,3.35},
	{_("Nitric acid"),1,-1.32},
	{_("Phosphoric acid"),3,1.96,7.21,12.32},
	{_("Sulfurous acid"),2,1.96,7.2},
	{_("Sulfuric acid"), 2,-3.0,1.92},
	{_("Formic acid"),1,3.74},
	{_("Chloroacetic acid"),1,2.86},
	{_("Dichloroacetic acid"),1,1.30},
	{_("Trichloroacetic acid"),1,0.70},
	{_("Benzoic acid"),1,4.20},
	{_("Oxalic acid"),2,1.25,4.29},
	{_("Tartaric acid"),2,2.98,4.34},
	{_("Citric acid"),3,3.13,4.76,6.4},
        }; //Data from H.R.Christen: Grundlagen der allgemeinen und anorganischen Chemie, Frankfurt a.M. 1980
        //G.H.Aylward, T.J.V.Findlay: Datensammlung Chemie, Weinheim 1975
	project = new Project;
	datum = std::time(nullptr);
	project->datum = std::asctime(std::localtime(&datum));


	app->run(argc, argv);

	return 0;
}

void app_quit()	//Quit Program
{
	if (!data_saved)
	{
		if (main_win->msg_dialog->dialog_ok(_("Save data?"))) save_data();
	}

	//Save options
	if (main_win->autosave) main_win->options_dialog->save_all_options ();
	full_screen = main_win->is_maximized ();
	mainwin_width = main_win->get_width();
	mainwin_height = main_win->get_height();
	ini_file.open (ini_filename, std::ios_base::out);
	try
	{
		ini_file << "autosave: "<< main_win->autosave << "\n";
		ini_file << "autoload: "<< main_win->autoload << "\n";
		ini_file << "display: "<< main_win->show_display << "\n";
		ini_file << "fullscreen: "<< full_screen << "\n";
		ini_file << "width: "<< mainwin_width << "\n";
		ini_file << "height: "<< mainwin_height << "\n";
	}
	catch (fs::filesystem_error const& ex) {error_msg(ex.what());}
	ini_file.close();

	//free all pointers
	if (project) delete project;
        if (main_win) delete main_win;

	return;
}

std::string read_ini(std::string opt_item)
{
	std::string opt = "", line;
	int pos;

	while (!ini_file.eof())
	{
		getline(ini_file,line);
		pos = line.find (opt_item);
		if (pos <= line.length())
		{
			opt = line.substr (pos + opt_item.length ());
			break;
		}
	}
	return opt;
}





