const DEFAULT_PARENTS = {
    modded: "", // must be provided
    component: "ScriptComponent",
    gamemode: "SCR_BaseGameMode",
    action: "ScriptedUserAction",
    entity: "GenericEntity",
    manager: "", // static class, no parent
    basic: "", // no parent
};
const COMPONENT_METHODS = [
    {
        signature: "override void EOnInit(IEntity owner)",
        body: "    // Called when the component is initialized",
    },
    {
        signature: "override void OnPostInit(IEntity owner)",
        body: "    // Called after all components are initialized",
    },
    {
        signature: "override void OnDelete(IEntity owner)",
        body: "    // Called when the entity is deleted",
    },
];
const GAMEMODE_METHODS = [
    {
        signature: "override void OnGameStart()",
        body: "    super.OnGameStart();\n    // Called when the game mode starts",
    },
    {
        signature: "override void OnPlayerConnected(int playerId)",
        body: "    super.OnPlayerConnected(playerId);\n    // Called when a player connects",
    },
    {
        signature: "override void OnPlayerDisconnected(int playerId, KickCauseGroup cause, int timeout)",
        body: "    super.OnPlayerDisconnected(playerId, cause, timeout);\n    // Called when a player disconnects",
    },
    {
        signature: "override void OnPlayerSpawned(int playerId, IEntity controlledEntity)",
        body: "    super.OnPlayerSpawned(playerId, controlledEntity);\n    // Called when a player spawns",
    },
];
const ACTION_METHODS = [
    {
        signature: "override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)",
        body: "    // Called when the action is performed by the user",
    },
    {
        signature: "override bool CanBePerformedScript(IEntity user)",
        body: "    // Return true if the action can be performed\n    return true;",
    },
    {
        signature: "override bool CanBeShownScript(IEntity user)",
        body: "    // Return true if the action should be visible\n    return true;",
    },
    {
        signature: "override bool HasLocalEffectOnlyScript()",
        body: "    // Return true if the action only has local effects (no replication)\n    return false;",
    },
];
const ENTITY_METHODS = [
    {
        signature: "override void EOnInit(IEntity owner)",
        body: "    // Called when the entity is initialized\n    SetEventMask(EntityEvent.FRAME);",
    },
    {
        signature: "override void EOnFrame(IEntity owner, float timeSlice)",
        body: "    // Called every frame (requires EntityEvent.FRAME flag)",
    },
];
/**
 * Generate an Enforce Script (.c) file from a template.
 */
export function generateScript(opts) {
    const parent = opts.parentClass || DEFAULT_PARENTS[opts.scriptType];
    const lines = [];
    // Header comment
    if (opts.description) {
        lines.push(`// ${opts.description}`);
        lines.push("");
    }
    switch (opts.scriptType) {
        case "modded":
            lines.push(...generateModded(opts.className, parent, opts.methods));
            break;
        case "component":
            lines.push(...generateComponent(opts.className, parent, opts.methods));
            break;
        case "gamemode":
            lines.push(...generateGamemode(opts.className, parent, opts.methods));
            break;
        case "action":
            lines.push(...generateAction(opts.className, parent, opts.methods));
            break;
        case "entity":
            lines.push(...generateEntity(opts.className, parent, opts.methods));
            break;
        case "manager":
            lines.push(...generateManager(opts.className, opts.methods));
            break;
        case "basic":
            lines.push(...generateBasic(opts.className, parent, opts.methods));
            break;
    }
    lines.push(""); // trailing newline
    return lines.join("\n");
}
function generateModded(className, parent, methods) {
    if (!parent) {
        throw new Error("Modded scripts require a parentClass to mod");
    }
    const lines = [];
    lines.push(`modded class ${parent}`);
    lines.push("{");
    if (methods && methods.length > 0) {
        for (const method of methods) {
            const clean = stripOverride(method);
            const name = extractMethodName(clean);
            const params = extractParamNames(clean);
            lines.push(`  override ${clean}`);
            lines.push("  {");
            lines.push(`    super.${name}(${params});`);
            lines.push("  }");
            lines.push("");
        }
    }
    else {
        lines.push("  // Add your overrides here");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
function generateComponent(className, parent, methods) {
    const lines = [];
    lines.push("[ComponentEditorProps(category: \"GameScripted\", description: \"\")]");
    lines.push(`class ${className} : ${parent}`);
    lines.push("{");
    lines.push("  // Member variables");
    lines.push("");
    const methodList = methods?.length
        ? methods.map((m) => {
            const clean = stripOverride(m);
            return { signature: `override ${clean}`, body: `    // TODO: implement ${extractMethodName(clean)}` };
        })
        : COMPONENT_METHODS;
    for (const m of methodList) {
        lines.push(`  ${m.signature}`);
        lines.push("  {");
        lines.push(m.body);
        lines.push("  }");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
function generateGamemode(className, parent, methods) {
    const lines = [];
    lines.push(`class ${className} : ${parent}`);
    lines.push("{");
    lines.push("  // Member variables");
    lines.push("");
    const methodList = methods?.length
        ? methods.map((m) => {
            const clean = stripOverride(m);
            const name = extractMethodName(clean);
            const params = extractParamNames(clean);
            return { signature: `override ${clean}`, body: `    super.${name}(${params});\n    // TODO: implement` };
        })
        : GAMEMODE_METHODS;
    for (const m of methodList) {
        lines.push(`  ${m.signature}`);
        lines.push("  {");
        lines.push(m.body);
        lines.push("  }");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
function generateAction(className, parent, methods) {
    const lines = [];
    lines.push(`class ${className} : ${parent}`);
    lines.push("{");
    const methodList = methods?.length
        ? methods.map((m) => {
            const clean = stripOverride(m);
            return { signature: `override ${clean}`, body: `    // TODO: implement ${extractMethodName(clean)}` };
        })
        : ACTION_METHODS;
    for (const m of methodList) {
        lines.push(`  ${m.signature}`);
        lines.push("  {");
        lines.push(m.body);
        lines.push("  }");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
function generateEntity(className, parent, methods) {
    const lines = [];
    lines.push(`class ${className} : ${parent}`);
    lines.push("{");
    lines.push("  // Member variables");
    lines.push("");
    const methodList = methods?.length
        ? methods.map((m) => {
            const clean = stripOverride(m);
            return { signature: `override ${clean}`, body: `    // TODO: implement ${extractMethodName(clean)}` };
        })
        : ENTITY_METHODS;
    for (const m of methodList) {
        lines.push(`  ${m.signature}`);
        lines.push("  {");
        lines.push(m.body);
        lines.push("  }");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
function generateManager(className, methods) {
    const lines = [];
    lines.push(`class ${className}`);
    lines.push("{");
    lines.push(`  private static ref ${className} s_Instance;`);
    lines.push("");
    lines.push(`  static ${className} GetInstance()`);
    lines.push("  {");
    lines.push("    if (!s_Instance)");
    lines.push(`      s_Instance = new ${className}();`);
    lines.push("    return s_Instance;");
    lines.push("  }");
    lines.push("");
    if (methods && methods.length > 0) {
        for (const method of methods) {
            lines.push(`  ${method}`);
            lines.push("  {");
            lines.push("    // TODO: implement");
            lines.push("  }");
            lines.push("");
        }
    }
    lines.push("}");
    return lines;
}
function generateBasic(className, parent, methods) {
    const lines = [];
    if (parent) {
        lines.push(`class ${className} : ${parent}`);
    }
    else {
        lines.push(`class ${className}`);
    }
    lines.push("{");
    if (methods && methods.length > 0) {
        for (const method of methods) {
            const clean = stripOverride(method);
            const keyword = parent ? "override " : "";
            lines.push(`  ${keyword}${clean}`);
            lines.push("  {");
            lines.push("    // TODO: implement");
            lines.push("  }");
            lines.push("");
        }
    }
    else {
        lines.push("  // TODO: implement");
        lines.push("");
    }
    lines.push("}");
    return lines;
}
/** Strip leading "override" keyword if already present */
function stripOverride(sig) {
    return sig.replace(/^\s*override\s+/, "");
}
/** Extract the method name from a signature like "void OnInit(int x)" → "OnInit" */
function extractMethodName(sig) {
    const clean = stripOverride(sig);
    const match = clean.match(/(\w+)\s*\(/);
    return match ? match[1] : clean;
}
/** Extract parameter names from a signature for super forwarding.
 *  "void OnDamage(float damage, int type)" → "damage, type"
 *  "void OnInit()" → ""
 */
function extractParamNames(sig) {
    const match = sig.match(/\(([^)]*)\)/);
    if (!match || !match[1].trim())
        return "";
    return match[1]
        .split(",")
        .map((p) => {
        // Each param is like "float damage" or "IEntity owner" — take the last word
        const parts = p.trim().split(/\s+/);
        return parts[parts.length - 1];
    })
        .join(", ");
}
/**
 * Get the correct module subfolder for a script type.
 * Scripts must be in the right folder or they're silently ignored.
 */
export function getScriptModuleFolder(scriptType) {
    // All standard mod scripts go in Scripts/Game/
    // WorkbenchGame/ is only for editor plugins
    // GameLib/ is for engine extensions (rare)
    return "Scripts/Game";
}
/**
 * Derive a filename from the class name.
 */
export function getScriptFilename(className) {
    return `${className}.c`;
}
//# sourceMappingURL=script.js.map