#ifndef PORYGONLANG_USERDATAFUNCTION_HPP
#define PORYGONLANG_USERDATAFUNCTION_HPP

#include "../Evaluator/EvalValues/ScriptFunctionEvalValue.hpp"
#include "UserDataFunctionType.hpp"
#include "../ScriptTypes/FunctionScriptType.hpp"
#include "../ScriptOptions.hpp"

namespace Porygon::UserData{
    class UserDataFunction : public Evaluation::GenericFunctionOption {
        const Evaluation::EvalValue* (*_call)(void* obj, const ScriptOptions*, const Evaluation::EvalValue* parameters[],
                int parameterCount);
        void *_obj;

        UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const ScriptOptions*,
                const Evaluation::EvalValue* parameters[], int parameterCount), void* obj,
                         const shared_ptr<GenericFunctionScriptType>& type, size_t hash) : GenericFunctionOption(){
            _call = call;
            _obj = obj;
        }
    public:
        UserDataFunction(const Evaluation::EvalValue* (*call)(void* obj, const ScriptOptions*,
                const Evaluation::EvalValue* parameters[], int parameterCount), void* obj) :
                GenericFunctionOption(){
            _call = call;
            _obj = obj;
        }

        ~UserDataFunction() final = default;

        [[nodiscard]]
        inline const Evaluation::EvalValue* Call(const ScriptOptions* script,
                const Evaluation::EvalValue* parameters[], int parameterCount) const{
            return _call(_obj, script, parameters, parameterCount);
        }
    };
}


#endif //PORYGONLANG_USERDATAFUNCTION_HPP
