#ifndef RPG_COMMON_H
#define RPG_COMMON_H

#include "raylib.h"
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

// Suppress strncpy/snprintf truncation warnings — all usage includes null-termination
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#pragma GCC diagnostic ignored "-Wformat-truncation"
// Each tab_*.c only uses a subset of the shared data tables below —
// suppress the resulting "defined but not used" noise per translation unit.
#pragma GCC diagnostic ignored "-Wunused-variable"

#define REGISTER_SKILL_COUNT  6
#define SKILL_COUNT          22
#define ATTRIBUTES_COUNT      6
#define MAX_LEVEL           101
#define TAB_COUNT            10
#define STATS_COUNT          12

#define IDX_MINING        0
#define IDX_COMBAT        1
#define IDX_CASTING      10
#define IDX_EXPLORATION  15
#define IDX_DUNGEONEERING 20
#define IDX_QUESTING     21

#define MAX_QUESTS       200
#define MAX_QNAME         64
#define MAX_QDESC        300
#define MAX_QNUM           8
#define QUEST_SAVE_FILE  "saves/quest_save.txt"
#define QUEST_ROW_H       58

// Quest Generator ("Quests" sub-tab only, not Story/Chain/Tree) — every list below
// is loaded from a plain text file (one entry per line) so new content needs no code change.
#define MAX_GEN_ENTRIES      256
#define MAX_GEN_NAME          48
#define MAX_OBJECTIVES         4
#define MAX_REWARD_ITEMS       3
#define QGEN_MOBS_FILE      "quests/mobs.txt"
#define QGEN_ITEMS_FILE     "quests/items.txt"
#define QGEN_LOCATIONS_FILE "quests/locations.txt"
#define QGEN_TITLES_FILE    "quests/titles.txt"
#define QGEN_BOSS_FILE      "quests/boss.txt"
#define QGEN_FARMING_FILE   "quests/farming_items.txt"
#define QGEN_FISHING_FILE   "quests/fishing_items.txt"
#define QGEN_MINING_FILE    "quests/mining_items.txt"
#define QGEN_NPC_NAMES_FILE "quests/npc_names.txt"

#define MAX_CLASSES          32
#define MAX_CLASS_LEVELS     20
#define MAX_CLASS_NAME       64
#define CLASS_SAVE_FILE     "saves/rpg_save.dat"
#define CLASS_LEVELS_DIR    "levels/"

// Chain Quests: default is a straight line, "Advanced" creation unlocks branching/merging
// (a node can unlock several children, and several nodes can together gate one child).
#define MAX_CHAINS           30
#define MAX_CHAIN_NODES      24
#define MAX_NODE_PARENTS      4
#define MAX_NODE_CHILDREN     6
#define CHAIN_SAVE_FILE     "saves/chain_quests.txt"

// Guild system
#define MAX_GUILDS           64
#define MAX_GUILD_MEMBERS    50          // roster cap (incl. the player when joined)
#define MAX_GNAME            48
#define MAX_GUILD_REQS       (ATTRIBUTES_COUNT + SKILL_COUNT + STATS_COUNT)
#define GUILD_SAVE_FILE     "saves/guild_save.txt"
#define FIRST_NAMES_FILE    "data/first_names.txt"   // one first name per line
#define LAST_NAMES_FILE     "data/last_names.txt"    // one last name per line
#define MAX_FIRST_NAMES      1024
#define MAX_LAST_NAMES       1024

// Virtual (design) resolution — everything is drawn in this space, then scaled to the window.
// Do not change these: every hard-coded UI coordinate assumes a 900x600 canvas.
#define VW 900
#define VH 600

// Actual default OS window size on launch (same 3:2 aspect as VW/VH, just bigger).
// The window is resizable, so this only affects the initial size.
#define DEFAULT_WIN_W 1440
#define DEFAULT_WIN_H  960

// Colours
static const Color C_BG      = { 10,  10,  20, 255};
static const Color C_PANEL   = { 18,  18,  34, 255};
static const Color C_PANEL2  = { 24,  24,  44, 255};
static const Color C_PANEL3  = { 33,  33,  57, 255};
static const Color C_GOLD    = {178, 138,  42, 255};
static const Color C_GOLD_L  = {232, 188,  72, 255};
static const Color C_GOLD_D  = { 90,  66,  14, 255};
static const Color C_TEXT    = {224, 218, 196, 255};
static const Color C_MUTED   = {118, 113,  98, 255};
static const Color C_GREEN   = { 62, 148,  58, 255};
static const Color C_GREEN_L = {175, 238, 170, 255};
static const Color C_RED     = {182,  56,  56, 255};
static const Color C_RED_L   = {240, 140, 140, 255};
static const Color C_BLUE    = { 62, 112, 192, 255};
static const Color C_BLUE_L  = {140, 185, 240, 255};
static const Color C_BORDER  = { 40,  40,  68, 255};
static const Color C_HEADER  = { 14,  14,  28, 255};
static const Color C_INPUT   = { 12,  12,  24, 255};
static const Color Q_HOVER   = { 35,  27,  65, 255};
static const Color Q_BORDER2 = { 80,  60, 130, 255};
static const Color Q_XP      = { 80, 175, 255, 255};
static const Color Q_XP_DIM  = { 20,  55,  95, 255};
static const Color Q_CP      = {255, 200,  50, 255};
static const Color Q_CP_DIM  = { 85,  62,  10, 255};
static const Color Q_INBG    = {  7,   5,  14, 255};
static const Color Q_OVERLAY = {  3,   2,  10, 230};
static const Color Q_DONEBG  = { 10,  35,  18, 255};
static const Color Q_NOTIF   = { 40, 170,  80, 255};
static const Color Q_TDIM    = {110, 100,  80, 255};
static const Color Q_TDARK   = { 50,  45,  35, 255};
static const Color Q_GPALE   = {235, 200, 110, 255};
static const Color Q_GDIM    = { 90,  72,  15, 255};

// Data tables shared across tabs
static const char *stats_names[STATS_COUNT] = {
    "HEALTH","DEFENSE","STRENGTH","ATTACK SPEED","CRIT DAMAGE","SPEED","MANA","REGENERATION","RANGE","FORTUNE","BREAKING POWER","LABOR SPEED"};
static const char *stats_units[STATS_COUNT] = {
    "HP","DEF","STR","%","%","SPD","MP","HP/min","m","LUCK","BP","LSPD"};
static const char *attributes_names[ATTRIBUTES_COUNT] = {
    "STRENGTH","AGILITY","VITALITY","INTELLECT","RESOLVE","KARMA"};
static const char *skill_names[SKILL_COUNT] = {
    "Mining","Combat","Trading","Farming","Crafting","Building","Forestry","Enchanting","Alchemy","Fishing","Casting","Cooking","Taming","Stealth","Music","Exploration","Excavation","Archery","Defense","Agility","Dungeoneering","Questing"};
static const char *tab_names[TAB_COUNT] = {
    "Stats","Attributes","Skills","Classes","Quests","Guild","Abilities","Gear","Enhancements","Register"};

// Small text-input widget shared by several tabs
typedef struct {
    char buf[128]; bool active;
} TBox;

// ---- Cross-tab state (owned/defined by the respective tab_*.c file) ----
extern bool showModal;     // Classes tab: "add class" modal open?  (tab_classes.c)
extern bool quest_create;  // Quests tab:  "create quest" modal open?  (tab_quests.c)
extern int  quest_view;    // Quests tab:  index of quest being viewed, or -1  (tab_quests.c)
extern int  quest_tab;     // Quests tab:  active sub-tab, used to pick create-modal type  (tab_quests.c)
extern int  guild_view;    // Guild tab:   0 menu / 1 yours / 2 join / 3 create  (tab_guild.c)
extern int  guild_req_modal; // Guild tab: index of guild whose requirements table is open, or -1  (tab_guild.c)

// ---- Shared helpers (common.c) ----
void safe_strncpy(char *dst, const char *src, size_t dstsize);
void ShowNotif(const char *msg);
void DrawNotifToast(float dt);

Color Brighten(Color c, float f);
void  Panel(Rectangle r, Color bg, Color border);
void  Badge(int x, int y, const char *txt, Color bg, Color fg);
void  ClsBadge(int x, int y, const char *txt, Color bg, Color fg);
bool  Btn(Rectangle r, const char *txt, Color bg, Color fg);
bool  SmallBtn(Rectangle r, const char *txt, Color bg, Color fg);
void  ProgBar(Rectangle r, float pct, Color fill);
void  HDivider(int x, int y, int w);
void  DrawXMark(Rectangle box, float thickness, Color color);  // a drawn X (two crossing lines), inset within box

void TBoxTick(TBox *t, Rectangle r);
void TBoxDraw(const TBox *t, Rectangle r, const char *ph);

// Removes duplicate lines (case-insensitive) and sorts the rest alphabetically,
// leaving any leading "#" comment block untouched. Runs automatically whenever
// a list file is loaded or appended to — see QuestGenInit / EnsureNamePool /
// PoolAppend — so mobs.txt, items.txt, etc. stay clean without manual upkeep.
void DedupeSortTextFile(const char *path);

// ---- Tab entry points ----
void DrawTabClasses(int cX, int cY);
void DrawClassModal(void);
void CancelClassModal(void);   // closes the "add class" modal and clears its input
void SaveClassState(void);
void LoadClassState(void);
void UpdateTotalXP(int level, int xp, int *tnl);

void DrawTabStats(int cX, int cY, int *base_stats, int *gear_stats, int selected_stat, bool edit_mode);

void DrawTabAttributes(int cX, int cY, int *attributes, int selected_attr, bool edit_mode);

void DrawTabSkills(int cX, int cY, int *skills, int selected_skill, bool edit_mode);

void DrawTabRegister(int cX, int cY, int *skills);

void DrawComingSoon(int cX, int cY, int tabIdx);

void DrawTabQuests(int cX, int cY, float dt, int playerLevel);
void DrawQuestCreateModal(int quest_type, float dt);
void DrawQuestViewModal(void);
void QuestLoad(void);
void ChainLoad(void);
bool ChainModalOpen(void);     // any chain-quest modal (create / add-node) currently open?
void ChainHandleEscape(void);  // ESC while a chain-quest modal is open
void DrawChainModals(float dt); // draws whichever chain-quest modal is currently open, if any
void QuestGenInit(void);       // loads (or seeds) the Quest Generator's config text files
void DrawQuestBuilderModal(float dt); // "+ New Quest": build a quest by hand-picking generator parameters
void ResetQuestBuilder(int playerLevel);  // clears the builder's working state; defaults Level to the player's

void DrawTabGuild(int cX, int cY, const int *attrs, const int *skills, const int *stats);
void DrawGuildReqModal(const int *attrs, const int *skills, const int *stats);
void GuildLoad(void);
void GuildSave(void);
void EnsureNamePool(void);
void GuildHandleEscape(void);  // ESC in the Guild tab: unfocus the name box, else back out a view

#endif // RPG_COMMON_H
