// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// 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 "../formrt/formrt.h"

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

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

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

// IDE preference sections and keys shared by the project code and the
// IDE preferences dialog (ideMain.c).
#define IDE_PREF_SECTION_DEFAULTS   "defaults"
#define IDE_PREF_KEY_AUTHOR         "author"
#define IDE_PREF_KEY_PUBLISHER      "publisher"
#define IDE_PREF_KEY_VERSION        "version"
#define IDE_PREF_KEY_COPYRIGHT      "copyright"
#define IDE_PREF_KEY_DESCRIPTION    "description"
#define IDE_PREF_DEFAULT_VERSION    "1.0"
#define IDE_PREF_SECTION_EDITOR     "editor"
#define IDE_PREF_KEY_OPTION_EXPLICIT "optionExplicit"

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

typedef struct {
    // Fields are ordered by alignment to minimize struct padding.
    char    *buffer;             // in-memory edit buffer (malloc'd, NULL = not loaded)
    char     path[DVX_MAX_PATH]; // relative path (8.3 DOS name)
    char     formName[BAS_MAX_IDENT]; // form object name (from "Begin Form <name>")
    bool     isForm;             // true = .frm, false = .bas
    bool     modified;           // true = buffer has unsaved changes
} 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 {
    // Fields are ordered by alignment to minimize struct padding.
    PrjFileT       *files;                      // stb_ds dynamic array
    PrjSourceMapT  *sourceMap;                  // stb_ds dynamic array
    int32_t         fileCount;
    int32_t         sourceMapCount;
    int32_t         activeFileIdx; // index of file open in editor (-1 = none)
    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[BAS_MAX_IDENT];
    // Project metadata (for binary generation)
    char            author[PRJ_MAX_STRING];
    char            publisher[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
    char            helpFile[DVX_MAX_PATH];    // relative path to .hlp file
    bool            optionExplicit;            // require DIM before use
    bool            dirty;
} PrjStateT;

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

void    prjInit(PrjStateT *prj);
bool    prjLoad(PrjStateT *prj, const char *dbpPath);
bool    prjSave(const PrjStateT *prj);
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
