/*
 *                            COPYRIGHT
 *
 *  sch-rnd - modular/flexible schematics editor - GUI
 *  Copyright (C) 2020,2023 Tibor 'Igor2' Palinkas
 *  (loosely based on camv-rnd's implementation)
 *
 *  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 <libcschem/config.h>

#include <librnd/config.h>

#include <genvector/vti0.h>
#include <genvector/vtp0.h>

#include <librnd/hid/hid.h>
#include <librnd/core/hid_cfg.h>
#include <librnd/hid/hid_dad.h>

#include <librnd/core/actions.h>
#include <librnd/core/event.h>
#include <librnd/core/rnd_conf.h>

#include <libcschem/concrete.h>

#include <sch-rnd/draw.h>

#include "layersel.h"

typedef struct layersel_ctx_s layersel_ctx_t;

typedef struct {
	int wvis, wlab;
	int lid;
	layersel_ctx_t *ls;
} ls_layer_t;


struct layersel_ctx_s {
	rnd_hid_dad_subdialog_t sub;
	int sub_inited;
	int lock_vis, lock_sel;
	int selected; /* layer idx (lid) of the currently selected layer */
	ls_layer_t layers[CSCH_DSPLY_max];
};

static layersel_ctx_t layersel;

static void lys_update_vis(ls_layer_t *lys)
{
	rnd_hid_attr_val_t hv;
	hv.lng = !!csch_layer_vis[lys->lid];
	rnd_gui->attr_dlg_set_value(lys->ls->sub.dlg_hid_ctx, lys->wvis, &hv);
}

static void layer_vis_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)
{
	ls_layer_t *lys = attr->user_data;
	if (lys == NULL)
		return;

	lys->ls->lock_vis++;
	csch_layer_vis[lys->lid] = !csch_layer_vis[lys->lid];
	lys->ls->lock_vis--;

	lys_update_vis(lys);
	sch_rnd_redraw(NULL);
}

static void layer_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr)
{
	TODO("set popup layer to: (ls_layer_t *)attr->user_data");
	rnd_actionl("Popup", "layer", NULL);
}

static void layersel_create_layer(layersel_ctx_t *ls, ls_layer_t *lys, const char *name)
{
	RND_DAD_BEGIN_HBOX(ls->sub.dlg);
		RND_DAD_BOOL(ls->sub.dlg);
			lys->wvis = RND_DAD_CURRENT(ls->sub.dlg);
			RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys);
			RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb);
		RND_DAD_LABEL(ls->sub.dlg, name);
			lys->wlab = RND_DAD_CURRENT(ls->sub.dlg);
			RND_DAD_SET_ATTR_FIELD(ls->sub.dlg, user_data, lys);
			RND_DAD_CHANGE_CB(ls->sub.dlg, layer_vis_cb);
			RND_DAD_RIGHT_CB(ls->sub.dlg, layer_right_cb);
	RND_DAD_END(ls->sub.dlg);
}

static void layersel_docked_create(layersel_ctx_t *ls)
{
	int n, i; /* must be signed */

	RND_DAD_BEGIN_VBOX(ls->sub.dlg);
		RND_DAD_COMPFLAG(ls->sub.dlg, RND_HATF_EXPFILL | RND_HATF_SCROLL);

		for(i = 0, n = 0; n < CSCH_DSPLY_max; n++) {
			ls_layer_t *lys = &ls->layers[n];
			lys->lid = n;
			lys->ls = ls;
			layersel_create_layer(ls, lys, csch_dsply_name(n));
			i++;
		}
	RND_DAD_END(ls->sub.dlg);
	RND_DAD_DEFSIZE(ls->sub.dlg, 210, 200);
	RND_DAD_MINSIZE(ls->sub.dlg, 100, 100);
}

static void layersel_update_vis(layersel_ctx_t *ls)
{
	int n;
	for(n = 0; n < CSCH_DSPLY_max; n++)
		lys_update_vis(&ls->layers[n]);
}

static void layersel_build(void)
{
	layersel_docked_create(&layersel);
	if (rnd_hid_dock_enter(&layersel.sub, RND_HID_DOCK_LEFT, "layersel") == 0) {
		layersel.sub_inited = 1;
		layersel_update_vis(&layersel);
	}
}

void sch_rnd_layersel_gui_init_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[])
{
	if ((RND_HAVE_GUI_ATTR_DLG) && (rnd_gui->get_menu_cfg != NULL)) {
		layersel_build();
	}
}

void sch_rnd_layersel_vis_chg_ev(rnd_design_t *hidlib, void *user_data, int argc, rnd_event_arg_t argv[])
{
	if ((!layersel.sub_inited) || (layersel.lock_vis > 0))
		return;
	layersel_update_vis(&layersel);
}
