/* -*- 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 <gtkmm/toolbutton.h>
#include <ctime>
#include <experimental/filesystem>
#include <sys/types.h>
#include <fstream>

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

namespace fs = std::experimental::filesystem;

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

// ui_files for running program in development environment
/*
#define UI_FILE "src/ui/galvani.ui"
#define UI_DATA_RW_FILE "src/ui/data_rw.ui"
#define UI_OPTIONS_FILE "src/ui/options.ui"
#define UI_EVAL_FILE "src/ui/eval.ui"
*/

// replace by the following definitions before compilation

#define UI_FILE PACKAGE_DATA_DIR"/ui/galvani.ui"
#define UI_DATA_RW_FILE PACKAGE_DATA_DIR"/ui/data_rw.ui"
#define UI_OPTIONS_FILE PACKAGE_DATA_DIR"/ui/options.ui"
#define UI_EVAL_FILE PACKAGE_DATA_DIR"/ui/eval.ui"



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

Messung::~Messung()
{
}
   
int
main (int argc, char *argv[])
{
	Gtk::Main kit(argc, argv);
	
	setlocale (LC_ALL, "");

	bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
	textdomain(GETTEXT_PACKAGE);
	
	//Main UI_FILE
	
	try
	{
		builder = Gtk::Builder::create_from_file(UI_FILE);
	}
	catch (const Glib::FileError & ex)
	{
		std::cerr << ex.what() << std::endl;
		return 1;
	}

	// initialize Measurement (Projekt)
	m_functions = {_("Time"),_("Wavelength"),_("DC Voltage"),_("AC Voltage"),_("DC Current"),_("AC Current"),
	_("Resistance"),_("Conductivity"),_("pH"),_("Temperature"),_("Absorption")};
	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 Messung;
	datum = std::time(nullptr);
	project->datum = std::asctime(std::localtime(&datum));
	builder->get_widget_derived("diagramm", diag);	
	builder->get_widget("main_window", main_win);
	builder->get_widget("browser", browser);
	builder->get_widget("projekt_prop", projekt_prop);
	builder->get_widget("projekt_prop_ok", projekt_prop_ok);
	builder->get_widget("projekt_prop_cancel", projekt_prop_cancel);
	builder->get_widget("error_msg", error_dialog);
	builder->get_widget("msg_dialog", msg_dialog);
	builder->get_widget("projekt_title", projekt_title);
	builder->get_widget("func_x", func_x);
	builder->get_widget("func_y", func_y);
	builder->get_widget("device_x", device_x);
	builder->get_widget("device_y", device_y);
	builder->get_widget("projekt_comment_view", projekt_comment_view);
	builder->get_widget("timer_dialog", timer_dialog);
	builder->get_widget("start_timer", start_timer);
	builder->get_widget("cancel_timer", cancel_timer);
	builder->get_widget("timer_start", timer_start);
	builder->get_widget("count_down_progress", count_down_progress);
	builder->get_widget("count_down_start", count_down_start);
	builder->get_widget("projekt_options", projekt_options);
	builder->get_widget("tit_options", tit_options);
	builder->get_widget("tit_ha", tit_ha);
	builder->get_widget("tit_haconc", tit_haconc);
	builder->get_widget("tit_baseconc", tit_baseconc);
	builder->get_widget("tit_havol", tit_havol);
	builder->get_widget("tit_speed", tit_speed);
	func_y->signal_changed().connect(sigc::ptr_fun(show_tit_options));
	func_x->signal_changed().connect(sigc::ptr_fun(show_settings_device_x));
	func_y->signal_changed().connect(sigc::ptr_fun(show_settings_device_y));
	device_x->signal_clicked().connect(sigc::ptr_fun(configure_settings_device_x));
	device_y->signal_clicked().connect(sigc::ptr_fun(configure_settings_device_y));
	
	
	//Menu
	builder->get_widget("menu_datei_neu", menu_datei_neu);
	menu_datei_neu->signal_activate().connect(sigc::ptr_fun(new_project));
	builder->get_widget("menu_datei_open", menu_datei_open);
	menu_datei_open->signal_activate().connect(sigc::ptr_fun(open_datafile));
	builder->get_widget("menu_datei_save", menu_datei_save);
	menu_datei_save->signal_activate().connect(sigc::ptr_fun(save_data));
	builder->get_widget("menu_datei_print", menu_datei_print);
	menu_datei_print->signal_activate().connect(sigc::ptr_fun(print_report));
	builder->get_widget("menu_quit", menu_quit);
	builder->get_widget("menu_mess_neu", menu_mess_neu);
	menu_mess_neu->signal_activate().connect(sigc::ptr_fun(begin_mess));
	builder->get_widget("menu_mess_start", menu_mess_start);
	menu_mess_start->signal_activate().connect(sigc::ptr_fun(start_mess));
	builder->get_widget("menu_mess_start_timer", menu_mess_start_timer);
	menu_mess_start_timer->signal_activate().connect(sigc::ptr_fun(start_mess_with_timer));
	builder->get_widget("menu_mess_cancel", menu_mess_cancel);
	menu_mess_cancel->signal_activate().connect(sigc::ptr_fun(cancel_mess));
	builder->get_widget("menu_mess_stop", menu_mess_stop);
	menu_mess_stop->signal_activate().connect(sigc::ptr_fun(stop_mess));
	builder->get_widget("menu_mess_delete", menu_mess_delete);
	menu_mess_delete->signal_activate().connect(sigc::ptr_fun(end_mess));	
	menu_quit->signal_activate().connect(sigc::ptr_fun(&Gtk::Main::quit));
	builder->get_widget("menu_eval_data", menu_eval_data);
	menu_eval_data->signal_activate ().connect(sigc::ptr_fun(eval_data));
	builder->get_widget("menu_export_diag", menu_export_diag);
	menu_export_diag->signal_activate().connect(sigc::ptr_fun(export_diag));
	builder->get_widget("menu_options_diag", menu_options_diag);
	menu_options_diag->signal_activate().connect(sigc::ptr_fun(set_options_diag));
	builder->get_widget("menu_options_deviceX", menu_options_deviceX);
	menu_options_deviceX->signal_activate().connect(sigc::ptr_fun(set_options_device_x));
	builder->get_widget("menu_options_deviceY", menu_options_deviceY);
	menu_options_deviceY->signal_activate().connect(sigc::ptr_fun(set_options_device_y));
	builder->get_widget("menu_options_save", menu_options_save);
	menu_options_save->signal_activate().connect(sigc::ptr_fun(save_all_options));
	builder->get_widget("menu_options_load", menu_options_load);
	menu_options_load->signal_activate().connect(sigc::ptr_fun(load_all_options));
	builder->get_widget("menu_options_autoload", menu_options_autoload);
	builder->get_widget("menu_options_autosave", menu_options_autosave);
	builder->get_widget("menu_view_display", menu_view_display);
	menu_view_display->signal_toggled().connect(sigc::ptr_fun(toggle_display));
	builder->get_widget("about_dialog", about_dialog);
	builder->get_widget("menu_about", menu_about);
	menu_about->signal_activate().connect(sigc::ptr_fun(about));
	about_dialog->set_version (VERSION);
	builder->get_widget("menu_help", menu_help);
	menu_help->signal_activate().connect(sigc::ptr_fun(help));
	

	//Toolbar
	builder->get_widget("button_messung", button_messung);
	button_messung->signal_clicked().connect(sigc::ptr_fun(begin_mess));
	// button_start
	builder->get_widget("button_start", button_start);
	// button_timer
	builder->get_widget("button_timer", button_timer);
	//button_stop
	builder->get_widget("button_stop", button_stop);
	button_stop->signal_clicked().connect(sigc::ptr_fun(stop_mess));
	//button_cancel
	builder->get_widget("button_cancel", button_cancel);
	button_cancel->signal_clicked().connect(sigc::ptr_fun(cancel_mess));
	//button_reset
	builder->get_widget("button_reset", button_reset);
	button_reset->signal_clicked().connect(sigc::ptr_fun(end_mess));
	//button_new
	builder->get_widget("button_new", button_new);
	button_new->signal_clicked().connect(sigc::ptr_fun(new_project));
	//button_edit
	builder->get_widget("button_edit", button_edit);
	button_edit->signal_clicked().connect(sigc::ptr_fun(define_project));
	//button_open
	builder->get_widget("button_open", button_open);
	button_open->signal_clicked().connect(sigc::ptr_fun(open_datafile));
	//button_save
	builder->get_widget("button_save", button_save);
	button_save->signal_clicked().connect(sigc::ptr_fun(save_data));
	//button_export
	builder->get_widget("button_export", button_export);
	button_export->signal_clicked().connect(sigc::ptr_fun(export_diag));
	//button_print
	builder->get_widget("button_print", button_print);
	button_print->signal_clicked().connect(sigc::ptr_fun(print_report));
	//Anzeigefelder
	builder->get_widget("display_x", display_x);
	builder->get_widget("display_y", display_y);
	//button_reset_scale
	builder->get_widget("button_reset_scale", button_reset_scale);
	button_reset_scale->signal_clicked().connect(sigc::ptr_fun(reset_diagscale));


	
	// Main window
	main_win->show_all();
	menu_mess_start->set_sensitive (false);
	menu_mess_start_timer->set_sensitive (false);
	menu_mess_cancel->set_sensitive (false);
	menu_mess_stop->set_sensitive (false);
	menu_mess_delete->set_sensitive (false);
	menu_eval_data->set_sensitive (false);
	button_start->hide();
	button_timer->hide();
	button_stop->hide();
	button_cancel->hide();
	button_reset->hide();
	button_reset_scale->hide();
	display_x->hide();
	display_y->hide();
	count_down_start->hide();
	count_down_progress->hide();
		
	//UI data_rw
	try
		{
			builder = Gtk::Builder::create_from_file(UI_DATA_RW_FILE);
		}
		catch (const Glib::FileError & ex)
		{
			std::cerr << ex.what() << std::endl;
			return 1;
		}
	builder->get_widget("choose_file", file_dialog);
	builder->get_widget("file_choose_ok", file_choose_ok);
	builder->get_widget("file_choose_cancel", file_choose_cancel);
	builder->get_widget("map_func", map_func);
	builder->get_widget("file_function_x", file_function_x);
	builder->get_widget("file_function_y", file_function_y);
	builder->get_widget("function_x", function_x);
	builder->get_widget("function_y", function_y);
	

	//UI options
	try
		{
			builder = Gtk::Builder::create_from_file(UI_OPTIONS_FILE);
		}
		catch (const Glib::FileError & ex)
		{
			std::cerr << ex.what() << std::endl;
			return 1;
		}
	
	builder->get_widget("options_dialog", options_dialog);
	builder->get_widget("options_ok", options_ok);
	builder->get_widget("options_cancel", options_cancel);
	builder->get_widget("options_reset", options_reset);
	builder->get_widget("edit_options", edit_options);
	builder->get_widget("diag_bkcolor", diag_bkcolor);
	builder->get_widget("diag_axcolor", diag_axcolor);
	builder->get_widget("diag_gridcolor", diag_gridcolor);
	builder->get_widget("diag_xycolor", diag_xycolor);
	builder->get_widget("diag_gridsw", diag_gridsw);
	builder->get_widget("diag_zerosw", diag_zerosw);
	builder->get_widget("diag_titlesw", diag_titlesw);
	builder->get_widget("diag_autoscalesw", diag_autoscalesw);
	builder->get_widget("diag_symbol", diag_symbol);
	builder->get_widget("diag_graph", diag_graph);
	builder->get_widget("diag_linestyle", diag_linestyle);
	builder->get_widget("diag_symbol_style", diag_symbolstyle);
	builder->get_widget("diag_xmin", diag_xmin);
	builder->get_widget("diag_xmax", diag_xmax);
	builder->get_widget("diag_ymin", diag_ymin);
	builder->get_widget("diag_ymax", diag_ymax);
	builder->get_widget("diag_symw", diag_symw);
	builder->get_widget("dmm1_serial_options", dmm_serial_options[0]);
	builder->get_widget("dmm2_serial_options", dmm_serial_options[1]);
	builder->get_widget("dmm1_dmm_options", dmm_dmm_options[0]);
	builder->get_widget("dmm2_dmm_options", dmm_dmm_options[1]);
	builder->get_widget("dmm2_device_options", dmm_device_options);
	builder->get_widget("dmm1_scpi", dmm_scpi[0]);
	builder->get_widget("dmm2_scpi", dmm_scpi[1]);
	builder->get_widget("dmm1_typ", dmm_typ[0]);
	builder->get_widget("dmm2_typ", dmm_typ[1]);
	builder->get_widget("dmm1_name", dmm_name[0]);
	builder->get_widget("dmm2_name", dmm_name[1]);
	builder->get_widget("device_name", device_name);
	builder->get_widget("dmm1_simtyp", dmm_simtyp[0]);
	builder->get_widget("dmm2_simtyp", dmm_simtyp[1]);
	builder->get_widget("dmm1_interface", dmm_interface[0]);
	builder->get_widget("dmm2_interface", dmm_interface[1]);
	builder->get_widget("device_interface", device_interface);
	builder->get_widget("dmm1_baud", dmm_baud[0]);
	builder->get_widget("dmm2_baud", dmm_baud[1]);
	builder->get_widget("dmm1_bits", dmm_bits[0]);
	builder->get_widget("dmm2_bits", dmm_bits[1]);
	builder->get_widget("dmm1_flowcontrol", dmm_flowcontrol[0]);
	builder->get_widget("dmm2_flowcontrol", dmm_flowcontrol[1]);
	builder->get_widget("dmm1_stopbits", dmm_stopbits[0]);
	builder->get_widget("dmm2_stopbits", dmm_stopbits[1]);
	builder->get_widget("dmm1_parity", dmm_parity[0]);
	builder->get_widget("dmm2_parity", dmm_parity[1]);
	builder->get_widget("dmm1_polling", dmm_polling[0]);
	builder->get_widget("dmm2_polling", dmm_polling[1]);
	builder->get_widget("dmm1_num_bytes", dmm_num_bytes[0]);
	builder->get_widget("dmm2_num_bytes", dmm_num_bytes[1]);
	builder->get_widget("dmm1_num_val", dmm_num_val[0]);
	builder->get_widget("dmm2_num_val", dmm_num_val[1]);
	builder->get_widget("dmm1_timeout", dmm_timeout[0]);
	builder->get_widget("dmm2_timeout", dmm_timeout[1]);
	builder->get_widget("dmm1_funktion", dmm_funktion[0]);
	builder->get_widget("dmm2_funktion", dmm_funktion[1]);
	builder->get_widget("dmm1_range", dmm_range[0]);
	builder->get_widget("dmm2_range", dmm_range[1]);
	builder->get_widget("dmm_mtime", dmm_mtime);
	builder->get_widget("dmm1_loadoptions", dmm_loadoptions[0]);
	dmm_loadoptions[0]->signal_clicked().connect(sigc::bind<int>(sigc::ptr_fun(load_dmm_options), 0));
	builder->get_widget("dmm2_loadoptions", dmm_loadoptions[1]);
	dmm_loadoptions[1]->signal_clicked().connect(sigc::bind<int>(sigc::ptr_fun(load_dmm_options), 1));
	builder->get_widget("dmm1_saveoptions", dmm_saveoptions[0]);
	dmm_saveoptions[0]->signal_clicked().connect(sigc::bind<int>(sigc::ptr_fun(save_dmm_options), 0));
	builder->get_widget("dmm2_saveoptions", dmm_saveoptions[1]);
	dmm_saveoptions[1]->signal_clicked().connect(sigc::bind<int>(sigc::ptr_fun(save_dmm_options), 1));
	builder->get_widget("dmmoptions_save_ok", dmmoptions_save_ok);
	builder->get_widget("dmmoptions_save_cancel", dmmoptions_save_cancel);
	builder->get_widget("dmmoptions_save_dialog", dmmoptions_save_dialog);
	builder->get_widget("dmm1_remote_control", dmm_remote_control[0]);
	builder->get_widget("dmm2_remote_control", dmm_remote_control[1]);
	builder->get_widget("dmm1_control_options", dmm_control_options[0]);
	builder->get_widget("dmm2_control_options", dmm_control_options[1]);
	builder->get_widget("dmm1_function_control", dmm_function_control[0]);
	builder->get_widget("dmm2_function_control", dmm_function_control[1]);
	builder->get_widget("dmm1_DCV", dmm_DCV[0]);
	builder->get_widget("dmm1_ACV", dmm_ACV[0]);
	builder->get_widget("dmm1_DCmA", dmm_DCmA[0]);
	builder->get_widget("dmm1_ACmA", dmm_ACmA[0]);
	builder->get_widget("dmm1_DCA", dmm_DCA[0]);
	builder->get_widget("dmm1_ACA", dmm_ACA[0]);
	builder->get_widget("dmm1_Res", dmm_Res[0]);
	builder->get_widget("dmm1_Cond", dmm_Cond[0]);
	builder->get_widget("dmm1_pH", dmm_pH[0]);
	builder->get_widget("dmm1_Temp", dmm_Temp[0]);
	builder->get_widget("dmm2_DCV", dmm_DCV[1]);
	builder->get_widget("dmm2_ACV", dmm_ACV[1]);
	builder->get_widget("dmm2_DCmA", dmm_DCmA[1]);
	builder->get_widget("dmm2_ACmA", dmm_ACmA[1]);
	builder->get_widget("dmm2_DCA", dmm_DCA[1]);
	builder->get_widget("dmm2_ACA", dmm_ACA[1]);
	builder->get_widget("dmm2_Res", dmm_Res[1]);
	builder->get_widget("dmm2_Cond", dmm_Cond[1]);
	builder->get_widget("dmm2_pH", dmm_pH[1]);
	builder->get_widget("dmm2_Temp", dmm_Temp[1]);
	// set diag limits manual or auto
	diag_autoscalesw->signal_state_changed().connect(sigc::ptr_fun(show_diag_manual_limits));
	// Recall options if dmm_typ changed
	dmm_typ[0]->signal_changed().connect(sigc::ptr_fun(restart_options_x));
	dmm_typ[1]->signal_changed().connect(sigc::ptr_fun(restart_options_y));
	dmm_name[0]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(select_dmm), 0));
	dmm_name[1]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(select_dmm), 1));
	//Show serial options for dmm if RS232C
	dmm_interface[0]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_interface_options), 0));
	dmm_interface[1]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_interface_options), 1));
	// Show/Hide dmm_control_options, if dmm_remote_control changed
	dmm_remote_control[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_control_options), 0));
	dmm_remote_control[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_control_options), 1));
	dmm_DCV[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_ACV[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_DCmA[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_ACmA[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_DCA[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_ACA[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_Res[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_Cond[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_pH[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_Temp[0]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 0));
	dmm_DCV[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_ACV[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_DCmA[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_ACmA[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_DCA[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_ACA[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_Res[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_Cond[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_pH[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	dmm_Temp[1]->signal_state_flags_changed().connect(sigc::bind<int>(sigc::ptr_fun(show_dmm_function_control), 1));
	// Change range options, if function changed
	dmm_funktion[0]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(set_range_options_device), 0));
	dmm_funktion[1]->signal_changed().connect(sigc::bind<int>(sigc::ptr_fun(set_range_options_device), 1));
	

	//UI eval
	try
		{
			builder = Gtk::Builder::create_from_file(UI_EVAL_FILE);
		}
		catch (const Glib::FileError & ex)
		{
			std::cerr << ex.what() << std::endl;
			return 1;
		}
	
	builder->get_widget("evaloptions_dialog", evaloptions_dialog);
	builder->get_widget("evaloptions", evaloptions);
	builder->get_widget("evaloption_vol", evaloption_vol);
	builder->get_widget("evaloption_volspeed", evaloption_volspeed);
	builder->get_widget("evaloption_xtherm", evaloption_xtherm);
	builder->get_widget("evaloption_ytherm", evaloption_ytherm);
	builder->get_widget("evaloption_xreziproksw", evaloption_xreziproksw);
	builder->get_widget("evaloption_yreziproksw", evaloption_yreziproksw);
	builder->get_widget("evaloption_xlogsw", evaloption_xlogsw);
	builder->get_widget("evaloption_ylogsw", evaloption_ylogsw);
	builder->get_widget("diag_funktcolor", diag_funktcolor);
	builder->get_widget("evaloption_reglin", evaloption_reglin);
	builder->get_widget("evaloption_integration", evaloption_integration);
	builder->get_widget("evaloption_diff", evaloption_diff);
	builder->get_widget("eval_results", eval_results);
	builder->get_widget("eval_results_view", eval_results_view);
	builder->get_widget("eval_funktion", eval_funktion);
	builder->get_widget("evaloption_minpeakscale", evaloption_minpeakscale);
	builder->get_widget("evaloption_mindiffscale", evaloption_mindiffscale);
	builder->get_widget("evaloption_show_baseline", evaloption_show_baseline);
	builder->get_widget("evaloption_show_peakarea", evaloption_show_peakarea);
	builder->get_widget("evaloption_show_peaklimits", evaloption_show_peaklimits);
	builder->get_widget ("integration_options", integration_options);
	evaloption_integration->signal_state_changed().connect(sigc::ptr_fun(show_evaloptions_integration));


	//Make directories
	homedir = getenv("HOME");
	confdir = homedir;
	confdir.append("/.galvani");
	workdir = homedir;
	workdir.append("/galvani");
	datadir = workdir;
	datadir.append("/data");
	tmpdir = "/tmp/galvani";
	try
	{
		if (!fs::exists(workdir))
		{
			fs::create_directory (workdir);
			fs::copy (PACKAGE_DATA_DIR"/dmm", workdir, fs::copy_options::recursive);
		}
		
	}
	catch (fs::filesystem_error const& ex) {fehler(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);
	}
	catch (fs::filesystem_error const& ex) {fehler(ex.what());}
	
	//Make 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);
		try
		{
			ini_file << "autosave: "<< autosave << "\n";
			ini_file << "autoload: "<< autoload << "\n";
			ini_file << "display: "<< show_display << "\n";
		}
		catch (fs::filesystem_error const& ex) {fehler(ex.what());}
		ini_file.close();
	}
	if (read_ini ("autosave: ") == "1") autosave = true; else autosave = false;
	if (read_ini ("autoload: ") == "1") autoload = true; else autoload = false;
	if (read_ini ("display: ") == "1") show_display = true; else 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: "));
	if (autoload) load_all_options ();
	menu_options_autosave->set_active(autosave);
	menu_options_autoload->set_active(autoload);
	menu_view_display->set_active(show_display);
	if (full_screen) main_win->maximize ();
	else // define minimum width and height 
	{
		if ((mainwin_width > 600) && (mainwin_height > 400)) main_win->resize (mainwin_width, mainwin_height);
	}
	
	ini_file.close();
	
	if (main_win)
	{
		kit.run(*main_win);
	}
	app_quit();
	return 0;
}

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

	//Save options
	autosave = menu_options_autosave->get_active();
	if (autosave) save_all_options ();
	//Save autoload/autosave-status
	autoload = menu_options_autoload->get_active();
	show_display = menu_view_display->get_active();
	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: "<< autosave << "\n";
		ini_file << "autoload: "<< autoload << "\n";
		ini_file << "display: "<< 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) {fehler(ex.what());}
	ini_file.close();
	
	//free all pointers
	if (project) delete project;
	if (diag) delete diag;
	if (printjob) delete printjob;

	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;
}

void about ()
{
	
	int result = about_dialog->run();
	
	about_dialog->hide();
	return;
}

void help ()
{
	std::string lcode;
	std::string doc_dir, doc, error_msg;
	
	//locate the help files
	doc_dir = "/usr/share/doc/galvani/";
	lcode = std::locale("").name();
	lcode = lcode.substr(0,2);
	doc_dir += lcode;
	doc += doc_dir + "/index.html";
	if (!fs::exists(doc)) 
	{
		error_msg = _("Documentation ");
		error_msg += doc + _(" not found");
		fehler(error_msg);
	}
	else
	{
		doc = "file://" + doc;
		browser->show();
		browser->hide();
		browser->show_uri (doc, GDK_CURRENT_TIME);
	}
		
	return;
}

