/*
 *                            COPYRIGHT
 *
 *  cschem - modular/flexible schematics editor - libcschem (core library)
 *  Copyright (C) 2023 Tibor 'Igor2' Palinkas
 *
 *  (Supported by NLnet NGI0 Entrust Fund in 2023)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.*
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; 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 "project_p4.h"
#include <assert.h>

/* all currently active plugin configs; NULL means plugin got unregistered */
static vtp0_t p4cfgs;

static csch_p4id_t p4id_find_unused(void)
{
	csch_p4id_t n;
	for(n = 0; n < p4cfgs.used; n++)
		if (p4cfgs.array[n] == NULL)
			return n;
	return -1;
}

void csch_p4_reg_plugin(csch_p4cfg_t *cfg)
{
	csch_p4id_t id;

	/* figure the ID, store cfg */
	id = p4id_find_unused();
	if (id < 0) {
		id = p4cfgs.used;
		vtp0_append(&p4cfgs, cfg);
	}
	else
		p4cfgs.array[id] = cfg;
	cfg->id = id;

	if (cfg->project_init != NULL) {
		htsp_entry_t *e;
		for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) {
			csch_project_t *prj = e->value;
			cfg->project_init(cfg, prj);
		}
	}
}

void csch_p4_unreg_plugin(csch_p4cfg_t *cfg)
{
	htsp_entry_t *e;
	assert(cfg->id >= 0);
	assert(cfg->id < p4cfgs.used);

	for(e = htsp_first(&rnd_projects); e != NULL; e = htsp_next(&rnd_projects, e)) {
		csch_project_t *prj = e->value;
		if (cfg->project_uninit != NULL)
			cfg->project_uninit(cfg, prj);
		if (prj->p4data.used > cfg->id)
			prj->p4data.array[cfg->id] = NULL;
	}

	p4cfgs.array[cfg->id] = NULL;
	cfg->id = -1;
}


void csch_p4_set_by_project(csch_p4cfg_t *cfg, csch_project_t *prj, void *data)
{
	assert(cfg->id >= 0);
	assert(cfg->id < p4cfgs.used);
	vtp0_set(&prj->p4data, cfg->id, data);
}

void csch_p4_call_project_init(csch_project_t *prj)
{
	csch_p4id_t n;
	for(n = 0; n < p4cfgs.used; n++) {
		csch_p4cfg_t *cfg = p4cfgs.array[n];
		if (cfg->project_init != NULL)
			cfg->project_init(cfg, prj);
	}
}

void csch_p4_call_project_uninit(csch_project_t *prj)
{
	csch_p4id_t n;
	for(n = 0; n < p4cfgs.used; n++) {
		csch_p4cfg_t *cfg = p4cfgs.array[n];
		if (cfg->project_uninit != NULL)
			cfg->project_uninit(cfg, prj);
		if (prj->p4data.used > cfg->id)
			prj->p4data.array[cfg->id] = NULL;
	}
}

void csch_p4_uninit(void)
{
	vtp0_uninit(&p4cfgs);
}
