/*
 *                            COPYRIGHT
 *
 *  sch-rnd - modular/flexible schematics editor - renumber dialog
 *  Copyright (C) 2022 Tibor 'Igor2' Palinkas
 *
 *  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 <genvector/gds_char.h>
#include <librnd/core/actions.h>
#include <librnd/core/file_loaded.h>
#include <librnd/hid/hid_dad.h>
#include <librnd/core/rnd_printf.h>

#include <sch-rnd/build_run.h>

static const char *scope_names[] = {"all on sheet", "selected on sheet", "all in project", "selected in project", NULL};
static const char *scopes[] = {"all", "selected", "allProject", "selectedProject", NULL};
static const char *sorts[]  = {"left->right (top->bottom within)", "right->left (top->bottom within)", "top->bottom (left->right within)", "bottom->top (left->right within)", NULL };
static const char *sorts2[] = {"lr", "rl", "tb", "bt", NULL};

typedef struct{
	RND_DAD_DECL_NOINIT(dlg)
	int wscope, wsort, wbase;
	int active; /* already open - allow only one instance */
} renumdlg_ctx_t;

static renumdlg_ctx_t renumdlg_ctx;

static void renumdlg_close_cb(void *caller_data, rnd_hid_attr_ev_t ev)
{
	renumdlg_ctx_t *ctx = caller_data;
	RND_DAD_FREE(ctx->dlg);
	memset(ctx, 0, sizeof(renumdlg_ctx_t)); /* reset all states to the initial - includes ctx->active = 0; */
}

static void renum_dlg_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr_btn)
{
	rnd_design_t *hl = rnd_multi_get_current();
	fgw_arg_t res, argv[5];

	argv[1].type = FGW_STR; argv[1].val.cstr = scopes[renumdlg_ctx.dlg[renumdlg_ctx.wscope].val.lng];
	argv[2].type = FGW_STR; argv[2].val.cstr = sorts2[renumdlg_ctx.dlg[renumdlg_ctx.wsort].val.lng];
	argv[3].type = FGW_INT; argv[3].val.nat_int = renumdlg_ctx.dlg[renumdlg_ctx.wbase].val.lng;
	rnd_actionv_bin(hl, "renumber", &res, 4, argv);
	fgw_arg_free(&rnd_fgw, &res);
}


static void sch_rnd_dlg_renumdlg(int init_scope)
{
	int init_scope_en;
	rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}};
	static const char *hscope = "Operate on which symbols";
	static const char *hsort = "Ascending order of numbers assigned";
	static const char *hbase = "First number assigned per prefix\ne.g. a value of 100 means resistors\nare numbered from R100";

	if (renumdlg_ctx.active)
		return;

	switch(init_scope) {
		case F_All:             init_scope_en = 0; break;
		case F_Selected:        init_scope_en = 1; break;
		case F_AllProject:      init_scope_en = 2; break;
		case F_SelectedProject: init_scope_en = 3; break;
		default:                rnd_message(RND_MSG_ERROR, "Invalid scope for RenumberDialog()\n"); return;
	}

	RND_DAD_BEGIN_VBOX(renumdlg_ctx.dlg);
		RND_DAD_COMPFLAG(renumdlg_ctx.dlg, RND_HATF_EXPFILL);
		RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg);
			RND_DAD_LABEL(renumdlg_ctx.dlg, "Scope:");
				RND_DAD_HELP(renumdlg_ctx.dlg, hscope);
			RND_DAD_ENUM(renumdlg_ctx.dlg, scope_names);
				renumdlg_ctx.wscope = RND_DAD_CURRENT(renumdlg_ctx.dlg);
				RND_DAD_DEFAULT_NUM(renumdlg_ctx.dlg, init_scope_en);
				RND_DAD_HELP(renumdlg_ctx.dlg, hscope);
		RND_DAD_END(renumdlg_ctx.dlg);
		RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg);
			RND_DAD_LABEL(renumdlg_ctx.dlg, "Sort:");
				RND_DAD_HELP(renumdlg_ctx.dlg, hsort);
			RND_DAD_ENUM(renumdlg_ctx.dlg, sorts);
				renumdlg_ctx.wsort = RND_DAD_CURRENT(renumdlg_ctx.dlg);
				RND_DAD_HELP(renumdlg_ctx.dlg, hsort);
		RND_DAD_END(renumdlg_ctx.dlg);
		RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg);
			RND_DAD_LABEL(renumdlg_ctx.dlg, "Base:");
				RND_DAD_HELP(renumdlg_ctx.dlg, hbase);
			RND_DAD_INTEGER(renumdlg_ctx.dlg);
				RND_DAD_DEFAULT_NUM(renumdlg_ctx.dlg, 1);
				renumdlg_ctx.wbase = RND_DAD_CURRENT(renumdlg_ctx.dlg);
				RND_DAD_HELP(renumdlg_ctx.dlg, hbase);
		RND_DAD_END(renumdlg_ctx.dlg);

		RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg);
			RND_DAD_BEGIN_HBOX(renumdlg_ctx.dlg);
				RND_DAD_COMPFLAG(renumdlg_ctx.dlg, RND_HATF_EXPFILL);
			RND_DAD_END(renumdlg_ctx.dlg);
			RND_DAD_BUTTON(renumdlg_ctx.dlg, "Renumber!");
				RND_DAD_CHANGE_CB(renumdlg_ctx.dlg, renum_dlg_cb);
			RND_DAD_BUTTON_CLOSES(renumdlg_ctx.dlg, clbtn);
		RND_DAD_END(renumdlg_ctx.dlg);
	RND_DAD_END(renumdlg_ctx.dlg);

	/* set up the context */
	renumdlg_ctx.active = 1;

	RND_DAD_NEW("renumdlg", renumdlg_ctx.dlg, "Renumber (rename) symbols", &renumdlg_ctx, rnd_false, renumdlg_close_cb); /* type=global */
}

