/*
 *                            COPYRIGHT
 *
 *  pcb-rnd, interactive printed circuit board design
 *  (this file is based on PCB, interactive printed circuit board design)
 *  Copyright (C) 1994,1995,1996,2006 Thomas Nau
 *  pcb-rnd Copyright (C) 2017,2018 Alain Vigne
 *  pcb-rnd Copyright (C) 2018,2020,2021 Tibor 'Igor2' Palinkas
 *  sch-rnd Copyright (C) 2022 Tibor 'Igor2' Palinkas
 *
 *  (Supported by NLnet NGI0 PET Fund in 2022)
 *
 *  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., 31 Milk Street, # 960789 Boston, MA 02196 USA.
 *
 *  Contact:
 *    Project page: http://repo.hu/projects/pcb-rnd
 *    lead developer: http://repo.hu/projects/pcb-rnd/contact.html
 *    mailing list: pcb-rnd (at) list.repo.hu (send "subscribe")
 *
 */

#include <libcschem/config.h>
#include <signal.h>
#include <genvector/gds_char.h>
#include "conf_core.h"
#include "build_run.h"
#include <librnd/hid/hid_init.h>
#include <librnd/core/compat_misc.h>

#include "emergency.h"

extern void sch_rnd_main_uninit(void);

void sch_rnd_quit_app(void)
{
	/* save data if necessary.  It not needed, then don't trigger EmergencySave
	 * via our atexit() registering of csch_emergency_save().  We presumably wanted to
	 * exit here and thus it is not an emergency. */
	sch_rnd_emergency_save();

	if (rnd_gui->do_exit == NULL) {
		sch_rnd_main_uninit();
		exit(0);
	}
	else
		rnd_gui->do_exit(rnd_gui);
}

char *sch_rnd_get_info_program(void)
{
	static gds_t info;
	static int first_time = 1;

	if (first_time) {
		first_time = 0;
		gds_init(&info);
		gds_append_str(&info, "This is sch-rnd " CSCH_VERSION " (" CSCH_REVISION ")" "\nan interactive ");
		gds_append_str(&info, "schematics editor\nfrom the Ringdove EDA suite\ncompiled using librnd version " RND_VER_STR "\nrunning with librnd version ");
		gds_append_str(&info, rnd_ver_str);
		gds_append(&info, '\n');
	}
	return info.array;
}

char *sch_rnd_get_info_copyright(void)
{
	static gds_t info;
	static int first_time = 1;

	if (first_time) {
		first_time = 0;
		gds_init(&info);

		gds_append_str(&info, "sch-rnd copyright:\n");
		gds_append_str(&info, "Copyright (C) Tibor Palinkas 2019..2026\n");
		gds_append_str(&info, "With some code copied from fellow Ringdove application pcb-rnd\n(see http://www.repo.hu/projects/pcb-rnd)\n\n");
	}
	return info.array;
}

char *sch_rnd_get_info_websites(const char **url_out)
{
	static gds_t info;
	static int first_time = 1;
	static const char *URL = "http://www.repo.hu/projects/sch-rnd\n";

	if (first_time) {
		first_time = 0;
		gds_init(&info);

		gds_append_str(&info, "For more information see:\n");
		gds_append_str(&info, URL);
	}

	if (url_out != NULL)
		*url_out = URL;

	return info.array;
}

char *sch_rnd_get_info_comments(void)
{
	static gds_t info;
	static int first_time = 1;
	char *tmp;

	if (first_time) {
		first_time = 0;
		gds_init(&info);

		tmp = sch_rnd_get_info_program();
		gds_append_str(&info, tmp);
		tmp = sch_rnd_get_info_websites(NULL);
		gds_append_str(&info, tmp);
	}
	return info.array;
}


char *sch_rnd_get_info_compile_options(void)
{
	rnd_hid_t **hids;
	int i;
	static gds_t info;
	static int first_time = 1;

#define TAB "    "

	if (first_time) {
		first_time = 0;
		gds_init(&info);

		gds_append_str(&info, "----- Run Time Options -----\n");
		gds_append_str(&info, "GUI: ");
		if (rnd_gui != NULL) {
			gds_append_str(&info, rnd_gui->name);
			gds_append_str(&info, "\n");
		}
		else
			gds_append_str(&info, "none\n");

		gds_append_str(&info, "\n----- Compile Time Options -----\n");
		hids = rnd_hid_enumerate();
		gds_append_str(&info, "GUI:\n");
		for (i = 0; hids[i]; i++) {
			if (hids[i]->gui) {
				gds_append_str(&info, TAB);
				gds_append_str(&info, hids[i]->name);
				gds_append_str(&info, " : ");
				gds_append_str(&info, hids[i]->description);
				gds_append_str(&info, "\n");
			}
		}

		gds_append_str(&info, "Exporters:\n");
		for (i = 0; hids[i]; i++) {
			if (hids[i]->exporter) {
				gds_append_str(&info, TAB);
				gds_append_str(&info, hids[i]->name);
				gds_append_str(&info, " : ");
				gds_append_str(&info, hids[i]->description);
				gds_append_str(&info, "\n");
			}
		}

		gds_append_str(&info, "Printers:\n");
		for (i = 0; hids[i]; i++) {
			if (hids[i]->printer) {
				gds_append_str(&info, TAB);
				gds_append_str(&info, hids[i]->name);
				gds_append_str(&info, " : ");
				gds_append_str(&info, hids[i]->description);
				gds_append_str(&info, "\n");
			}
		}
	}
#undef TAB
	return info.array;
}

char *sch_rnd_get_info_license(void)
{
	static gds_t info;
	static int first_time = 1;

	if (first_time) {
		first_time = 0;
		gds_init(&info);

		gds_append_str(&info, "sch-rnd is licensed under the terms of the GNU\n");
		gds_append_str(&info, "General Public License version 2\n");
		gds_append_str(&info, "See the COPYING file for more information\n\n");
	}
	return info.array;
}

/* Catches signals which abort the program. */
void sch_rnd_catch_signal(int Signal)
{
	const char *s;

	switch (Signal) {
#ifdef SIGHUP
	case SIGHUP:
		s = "SIGHUP";
		break;
#endif
	case SIGINT:
		s = "SIGINT";
		break;
#ifdef SIGQUIT
	case SIGQUIT:
		s = "SIGQUIT";
		break;
#endif
	case SIGABRT:
		s = "SIGABRT";
		break;
	case SIGTERM:
		s = "SIGTERM";
		break;
	case SIGSEGV:
		s = "SIGSEGV";
		break;
	default:
		s = "unknown";
		break;
	}
	rnd_message(RND_MSG_ERROR, "aborted by %s signal\n", s);
	exit(1);
}
