// ideProject.h -- DVX BASIC project file management and project window

#ifndef IDE_PROJECT_H
#define IDE_PROJECT_H

#include "dvxApp.h"
#include "dvxPrefs.h"
#include "dvxTypes.h"

#include <stdbool.h>
#include <stdint.h>

// ============================================================
// Constants
// ============================================================

#define PRJ_MAX_NAME      32
#define PRJ_MAX_STRING    128
#define PRJ_MAX_DESC      512

// ============================================================
// Project file entry
// ============================================================

typedef struct {
    char     path[DVX_MAX_PATH]; // relative path (8.3 DOS name)
    bool     isForm;             // true = .frm, false = .bas
    char    *buffer;             // in-memory edit buffer (malloc'd, NULL = not loaded)
    bool     modified;           // true = buffer has unsaved changes
    char     formName[PRJ_MAX_NAME]; // form object name (from "Begin Form <name>")
} PrjFileT;

// ============================================================
// Source map entry (for multi-file error reporting)
// ============================================================

typedef struct {
    int32_t startLine; // 1-based line in concatenated source
    int32_t lineCount; // lines contributed by this file
    int32_t fileIdx;   // index in PrjStateT.files[]
} PrjSourceMapT;

// ============================================================
// Project state
// ============================================================

typedef struct {
    char            name[PRJ_MAX_NAME];
    char            projectPath[DVX_MAX_PATH]; // full path to .dbp file
    char            projectDir[DVX_MAX_PATH];  // directory containing .dbp
    char            startupForm[PRJ_MAX_NAME];
    // Project metadata (for binary generation)
    char            author[PRJ_MAX_STRING];
    char            company[PRJ_MAX_STRING];
    char            version[PRJ_MAX_NAME];
    char            copyright[PRJ_MAX_STRING];
    char            description[PRJ_MAX_DESC];
    char            iconPath[DVX_MAX_PATH];    // relative path to icon BMP
    PrjFileT       *files;                      // stb_ds dynamic array
    int32_t         fileCount;
    PrjSourceMapT  *sourceMap;                  // stb_ds dynamic array
    int32_t         sourceMapCount;
    bool            dirty;
    int32_t         activeFileIdx; // index of file open in editor (-1 = none)
} PrjStateT;

// ============================================================
// Project management
// ============================================================

void    prjInit(PrjStateT *prj);
bool    prjLoad(PrjStateT *prj, const char *dbpPath);
bool    prjSave(const PrjStateT *prj);
bool    prjSaveAs(PrjStateT *prj, const char *dbpPath);
void    prjNew(PrjStateT *prj, const char *name, const char *directory, PrefsHandleT *prefs);
void    prjClose(PrjStateT *prj);
int32_t prjAddFile(PrjStateT *prj, const char *relativePath, bool isForm);
void    prjLoadAllFiles(PrjStateT *prj, AppContextT *ctx);
void    prjRemoveFile(PrjStateT *prj, int32_t idx);
void    prjFullPath(const PrjStateT *prj, int32_t fileIdx, char *outPath, int32_t outSize);

// ============================================================
// Source map -- translate concatenated line to file + local line
// ============================================================

// Returns true if the line was found in the map. Sets outFileIdx and
// outLocalLine to the originating file and line within that file.
bool prjMapLine(const PrjStateT *prj, int32_t concatLine, int32_t *outFileIdx, int32_t *outLocalLine);

// ============================================================
// Project window UI
// ============================================================

typedef void (*PrjFileClickFnT)(int32_t fileIdx, bool isForm);
typedef void (*PrjSelChangeFnT)(void);

WindowT *prjCreateWindow(AppContextT *ctx, PrjStateT *prj, PrjFileClickFnT onClick, PrjSelChangeFnT onSelChange);
void     prjDestroyWindow(AppContextT *ctx, WindowT *win);
void     prjRebuildTree(PrjStateT *prj);
int32_t  prjGetSelectedFileIdx(void);

// ============================================================
// Project properties dialog
// ============================================================

// Show a modal dialog for editing project metadata. Returns true if
// the user clicked OK (fields in prj are updated), false if cancelled.
bool prjPropertiesDialog(AppContextT *ctx, PrjStateT *prj, const char *appPath);

#endif // IDE_PROJECT_H
