#include "_scriptapi_argument.h"
#include "_scriptapi_module.h"
#include "argument.h"

SCRIPT_EXPORT bool Script::Argument::Add(duint start, duint end, bool manual, duint instructionCount)
{
    return ArgumentAdd(start, end, manual, instructionCount);
}

SCRIPT_EXPORT bool Script::Argument::Add(const ArgumentInfo* info)
{
    if(!info)
        return false;
    auto base = Module::BaseFromName(info->mod);
    if(!base)
        return false;
    return Add(base + info->rvaStart, base + info->rvaEnd, info->manual, info->instructioncount);
}

SCRIPT_EXPORT bool Script::Argument::Get(duint addr, duint* start, duint* end, duint* instructionCount)
{
    return ArgumentGet(addr, start, end, instructionCount);
}

SCRIPT_EXPORT bool Script::Argument::GetInfo(duint addr, ArgumentInfo* info)
{
    ARGUMENTSINFO argument;
    if(!ArgumentGetInfo(addr, argument))
        return false;
    if(info)
    {
        strcpy_s(info->mod, argument.mod().c_str());
        info->rvaStart = argument.start;
        info->rvaEnd = argument.end;
        info->manual = argument.manual;
        info->instructioncount = argument.instructioncount;
    }
    return true;
}

SCRIPT_EXPORT bool Script::Argument::Overlaps(duint start, duint end)
{
    return ArgumentOverlaps(start, end);
}

SCRIPT_EXPORT bool Script::Argument::Delete(duint address)
{
    return ArgumentDelete(address);
}

SCRIPT_EXPORT void Script::Argument::DeleteRange(duint start, duint end, bool deleteManual)
{
    ArgumentDelRange(start, end, deleteManual);
}

SCRIPT_EXPORT void Script::Argument::Clear()
{
    ArgumentClear();
}

SCRIPT_EXPORT bool Script::Argument::GetList(ListOf(ArgumentInfo) list)
{
    std::vector<ARGUMENTSINFO> argumentList;
    ArgumentGetList(argumentList);
    std::vector<ArgumentInfo> argumentScriptList;
    argumentScriptList.reserve(argumentList.size());
    for(const auto & argument : argumentList)
    {
        ArgumentInfo scriptArgument;
        strcpy_s(scriptArgument.mod, argument.mod().c_str());
        scriptArgument.rvaStart = argument.start;
        scriptArgument.rvaEnd = argument.end;
        scriptArgument.manual = argument.manual;
        scriptArgument.instructioncount = argument.instructioncount;
        argumentScriptList.push_back(scriptArgument);
    }
    return BridgeList<ArgumentInfo>::CopyData(list, argumentScriptList);
}