#include <stdlib.h>
#include <string.h>

#include "FunctionMap.h"

void fmInit(FunctionMap* fm) {
    fm->capacity = 16;
    fm->entries = 0;
    fm->data = malloc(sizeof(Function) * fm->capacity);
    fm->queueCapacity = 16;
    fm->queueEntries = 0;
    fm->queue = malloc(sizeof(LingeringFunction) * fm->queueCapacity);
}

void fmDelete(FunctionMap* fm) {
    free(fm->data);
    free(fm->queue);
}

Function* fmSearch(FunctionMap* fm, const char* name, int arguments) {
    for(int i = 0; i < fm->entries; i++) {
        if(fm->data[i].arguments == arguments && strcmp(fm->data[i].name, name) == 0) {
            return fm->data + i;
        }
    }
    return NULL;
}

bool fmAdd(FunctionMap* fm, const char* name, int arguments, int address, bool returns) {
    if(fmSearch(fm, name, arguments) != NULL) {
        return false;
    }
    if(fm->entries >= fm->capacity) {
        fm->capacity *= 2;
        fm->data = realloc(fm->data, sizeof(Function) * fm->capacity);
    }
    int index = fm->entries++;
    fm->data[index].name = name;
    fm->data[index].arguments = arguments;
    fm->data[index].address = address;
    fm->data[index].returns = returns;
    return true;
}

void fmEnqueue(FunctionMap* fm, const char* name, int arguments, int line, int reserved, bool noReturn) {
    if(fm->queueEntries >= fm->queueCapacity) {
        fm->queueCapacity *= 2;
        fm->queue = realloc(fm->queue, sizeof(LingeringFunction) * fm->queueCapacity);
    }
    int index = fm->queueEntries++;
    fm->queue[index].name = name;
    fm->queue[index].arguments = arguments;
    fm->queue[index].line = line;
    fm->queue[index].reserved = reserved;
    fm->queue[index].noReturn = noReturn;
}