/*
 *                            COPYRIGHT
 *
 *  cschem - modular/flexible schematics editor - GUI
 *  Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas (in pcb-rnd)
 *  Copyright (C) 2022 Tibor 'Igor2' Palinkas
 *  (copied from pcb-rnd by the author)
 *
 *  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/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
 */

/* advanced search dialog - expressioin wizard tables; intended to be
   included from the search dialog only */

typedef enum {
	RIGHT_STR,
	RIGHT_INT,
	RIGHT_DOUBLE,
	RIGHT_COORD,
	RIGHT_CONST,
	RIGHT_max
} right_type;

typedef enum {
	OPS_ANY,
	OPS_EQ,
	OPS_STR
} op_type_t;

static const char *ops_any[] = {"==", "!=", ">=", "<=", ">", "<", NULL};
static const char *ops_eq[]  = {"==", "!=", NULL};
static const char *ops_str[] = {"==", "!=", "~", NULL};

typedef struct expr_wizard_op_s expr_wizard_op_t;
struct expr_wizard_op_s {
	const char **ops;
};

static expr_wizard_op_t op_tab[] = {
	{ops_any},
	{ops_eq},
	{ops_str},
	{NULL}
};

typedef struct expr_wizard_s expr_wizard_t;
struct expr_wizard_s {
	const char *left_var;
	const char *left_desc;
	const expr_wizard_op_t *op;
	right_type rtype;
	const expr_wizard_op_t *right_const;
};

static const char *right_const_objtype[] = { "LINE", "ARC", "POLY", "TEXT", "BITMAP", "CONN", "GRP", "GRP_REF", "PEN", NULL };
static const char *right_const_yesno[] = {"YES", "NO", NULL};
static const char *right_const_10[] = {"1", "0", NULL};
static const char *right_const_halign[] = {"LEFT", "CENTER", "RIGHT", "WORD_JUST", "JUST", NULL};
static const char *right_const_role[] = {"\"symbol\"", "\"wire-net\"", "\"terminal\"", NULL};

enum {
	RC_OBJTYPE,
	RC_YESNO,
	RC_10,
	RC_HALIGN,
	RC_ROLE
};

static expr_wizard_op_t right_const_tab[] = {
	{right_const_objtype},
	{right_const_yesno},
	{right_const_10},
	{right_const_halign},
	{right_const_role},
	{NULL}
};

static const expr_wizard_t expr_tab[] = {
	{"@.a.name",          "name (attribute)", &op_tab[OPS_STR], RIGHT_STR, NULL},
	{"@.a.value",         "value (attribute)",&op_tab[OPS_STR], RIGHT_STR, NULL},
	{"@.a.role",          "role (attribute)", &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_ROLE]},

	{"@.ID",              "object ID",        &op_tab[OPS_ANY], RIGHT_INT, NULL},
	{"@.type",            "object type",      &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_OBJTYPE]},
	{"@.selected",        "selected",         &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.locked",          "explicitly locked",&op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.anylocked",       "locked in any way",&op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.floater",         "obj is floater",   &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.displayer",       "display layer ID", &op_tab[OPS_EQ],  RIGHT_INT, NULL},
	{"@.displayer_name",  "display layer name",&op_tab[OPS_EQ], RIGHT_STR, NULL},

	{NULL,                "bounding box",     NULL,             0, NULL},
	{"@.bbox.x1",         "X1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.bbox.y1",         "Y1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.bbox.x2",         "X2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.bbox.y2",         "Y2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.bbox.w",          "width",            &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.bbox.h",          "height",           &op_tab[OPS_ANY], RIGHT_COORD, NULL},

	{NULL,                "stroke pen",       NULL,             0, NULL},
	{"@.stroke.is_round", "shape is round",   &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.stroke.size",     "tip size",         &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.stroke.dash",     "dash pattern",     &op_tab[OPS_EQ],  RIGHT_INT, NULL},
	{"@.stroke.dash_period", "dash period",   &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.stroke.font_height", "font height",   &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.stroke.font_family", "font family",   &op_tab[OPS_EQ], RIGHT_STR, NULL},
	{"@.stroke.font_style",  "font style",    &op_tab[OPS_EQ], RIGHT_STR, NULL},


	{NULL,                "line",             NULL,             0, NULL},
	{"@.x1",              "X1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y1",              "Y1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.x2",              "X2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y2",              "Y2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.lenght",          "length",           &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.area",            "area",             &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},

	{NULL,                "arc",              NULL,             0, NULL},
	{"@.x",               "center X",         &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y",               "center Y",         &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.r",               "radius",           &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.angle.start",     "start angle",      &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},
	{"@.angle.delta",     "delta angle",      &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},
	{"@.lenght",          "length",           &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.area",            "area",             &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},

	{NULL,                "text",             NULL,             0, NULL},
	{"@.x",               "X",                &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y",               "Y",                &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.x2",              "X2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y2",              "Y2",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.string",          "string (entered)", &op_tab[OPS_STR], RIGHT_STR, NULL},
	{"@.render",          "string (rendered)",&op_tab[OPS_STR], RIGHT_STR, NULL},
	{"@.rotation",        "rotation",         &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},
	{"@.has_bbox",        "bbox specified",   &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.dyntext",         "dynamic text template",&op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.halign",          "horizontal alignment",&op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_HALIGN]},

	{NULL,                "polygon",          NULL,             0, NULL},
	{"@.points",          "points",           &op_tab[OPS_ANY], RIGHT_INT, NULL},

	{NULL,                "grp",              NULL,             0, NULL},
	{"@.x",               "X",                &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y",               "Y",                &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.rotation",        "rotation",         &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},
	{"@.mirx",            "X mirror",         &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.miry",            "Y mirror",         &op_tab[OPS_EQ],  RIGHT_CONST, &right_const_tab[RC_10]},
	{"@.area",            "area",             &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL},
	{"@.a.name",          "name",             &op_tab[OPS_STR], RIGHT_STR, NULL},
	{"@.a.value",         "value",            &op_tab[OPS_STR], RIGHT_STR, NULL},

	{NULL,                "bitmap",           NULL,             0, NULL},
	{"@.x1",              "x1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},
	{"@.y1",              "y1",               &op_tab[OPS_ANY], RIGHT_COORD, NULL},

	{NULL, NULL, NULL, 0, NULL}
};

