/*
 *                            COPYRIGHT
 *
 *  cschem - modular/flexible schematics editor - SPICE netlist export
 *  Copyright (C) 2023 Tibor 'Igor2' Palinkas
 *
 *  (Supported by NLnet NGI0 Entrust in 2023)
 *
 *  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.
 *
 *  Contact:
 *    Project page: http://repo.hu/projects/sch-rnd
 *    contact lead developer: http://www.repo.hu/projects/sch-rnd/contact.html
 *    mailing list: http://www.repo.hu/projects/sch-rnd/contact.html
 */

#include <librnd/hid/hid.h>
#include <librnd/hid/hid_attrib.h>
#include <librnd/hid/hid_nogui.h>
#include <librnd/hid/hid_init.h>
#include <libcschem/project.h>
#include <libcschem/util_export.h>
#include <sch-rnd/export.h>

static const char spice_cookie[] = "SPICE export hid";

static const rnd_export_opt_t spice_options[] = {
	{"outfile", "Name of the SPICE netlist output file",
	 RND_HATT_STRING, 0, 0, {0, 0, 0}, 0},
#define HA_outfile 0

	{"debug", "Print extra comments in the output",
	 RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0},
#define HA_debug 1

	{"omit-headers", "Do not print the header section (spice/file_header symbol attributes)",
	 RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0},
#define HA_omit_headers 2

	{"omit-includes", "Do not print the includes (spice/model_include symbol attributes)",
	 RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0},
#define HA_omit_includes 3

	{"omit-model-cards", "Do not print the model cards (either inline of lib-copied; spice/model_card, spice/model symbol attributes)",
	 RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0},
#define HA_omit_model_cards 4

	{"omit-commands", "Do not print spice commands (spice/command symbol attributes)",
	 RND_HATT_BOOL, 0, 0, {0, 0, 0}, 0},
#define HA_omit_commands 5

	{"view", "Name of the view to export (use first view when not specified)",
	 RND_HATT_STRING, 0, 0, {0, 0, 0}, 0},
#define HA_view 6
};

#define NUM_OPTIONS (sizeof(spice_options)/sizeof(spice_options[0]))

rnd_hid_attr_val_t spice_values[NUM_OPTIONS];

int export_spice_is_dbg(void)
{
	return spice_values[HA_debug].lng;
}

int export_spice_omit(const char *what)
{
	switch(*what) {
		case 'h': return spice_values[HA_omit_headers].lng;
		case 'i': return spice_values[HA_omit_includes].lng;
		case 'm': return spice_values[HA_omit_model_cards].lng;
		case 'c': return spice_values[HA_omit_commands].lng;
	}
	return 0;
}

static const rnd_export_opt_t *spice_get_export_options(rnd_hid_t *hid, int *n, rnd_design_t *dsg, void *appspec)
{
	const char *val = spice_values[HA_outfile].str;

	if ((dsg != NULL) && ((val == NULL) || (*val == '\0')))
		csch_derive_default_filename(dsg, 1, &spice_values[HA_outfile], ".cir");

	if (n)
		*n = NUM_OPTIONS;
	return spice_options;
}

static void spice_do_export(rnd_hid_t *hid, rnd_design_t *design, rnd_hid_attr_val_t *options, void *appspec)
{
	csch_sheet_t *sheet = (csch_sheet_t *)design;
	int viewid = CSCH_VIEW_DEFAULT;

	if (!options) {
		spice_get_export_options(hid, 0, design, appspec);
		options = spice_values;
	}

	if ((options[HA_view].str != NULL) && (options[HA_view].str[0] != '\0')) {
		viewid = csch_view_get_id((csch_project_t *)sheet->hidlib.project, options[HA_view].str);
		if (viewid < 0) {
			rnd_message(RND_MSG_ERROR, "No such view in the project: '%s'\n", options[HA_view].str);
			return;
		}
	}

	sch_rnd_export_prj_abst((csch_project_t *)sheet->hidlib.project, sheet, viewid, "spice", options[HA_outfile].str, options);
}

static int spice_usage(rnd_hid_t *hid, const char *topic)
{
	fprintf(stderr, "\nSPICE exporter command line arguments:\n\n");
	rnd_hid_usage(spice_options, sizeof(spice_options) / sizeof(spice_options[0]));
	fprintf(stderr, "\nUsage: sch-rnd [generic_options] -x spice [options] foo.rs\n\n");
	return 0;
}


static int spice_parse_arguments(rnd_hid_t *hid, int *argc, char ***argv)
{
	rnd_export_register_opts2(hid, spice_options, sizeof(spice_options) / sizeof(spice_options[0]), spice_cookie, 0);
	return rnd_hid_parse_command_line(argc, argv);
}

rnd_hid_t spice_hid = {0};
