#include <stdlib.h>
#include <stdio.h>
#include "utils.h"


pyReal distSquared(const pyReal * u, const pyReal * v, const pyWord nFeatures) {
    pyWord n;
    pyReal s = 0.0, t;
    
    for( n = 0 ; n < nFeatures ; n ++) {
        t = u[n] - v[n];
        s += t * t;
    }
    
    return s;
}


void freeNbhHeaps(SearchParams * params) {
    if(params->nbhHeaps.heaps) {
       free(params->nbhHeaps.heaps);
        params->nbhHeaps.heaps = NULL;
    }
    
    if(params->nbhHeaps.distances) {
        free(params->nbhHeaps.distances);
        params->nbhHeaps.distances = NULL;
    }
}


int initNbhHeaps(SearchParams * params) {
    pyWord i, j;
    
    pyWord * nbhI;
    pyReal * distsI;

    params->nbhHeaps.heaps = NULL;
    params->nbhHeaps.distances = NULL;

    params->nbhHeaps.distances = (pyReal*) malloc((params->nPoints + 1) * params->nbhSize * sizeof(pyReal));
    if(params->nbhHeaps.distances == NULL) {
        puts("Out of memory!");
        return 1;
    }

    params->nbhHeaps.heaps = (MaxHeap*) malloc((params->nPoints + 1) * sizeof(MaxHeap));
    if(params->nbhHeaps.heaps == NULL) {
        free(params->nbhHeaps.distances);
        params->nbhHeaps.distances = NULL;
        puts("Out of memory!");
        return 1;
    }
    
    // Initialisiere Distanzen und Nachbarschaften
    for(i = 0; i < params->nPoints; i ++) {
        distsI = &(params->nbhHeaps.distances[i * params->nbhSize]);
        nbhI = &(params->neighborhoods[i * params->nbhSize]);
        params->nbhHeaps.heaps[i].distances = distsI;
        params->nbhHeaps.heaps[i].indices = nbhI;
        params->nbhHeaps.heaps[i].maxItems = params->nbhSize;
        params->nbhHeaps.heaps[i].size = 1;

        for(j = 0; j < params->nbhSize; j ++) {
            nbhI[j] = i;
            distsI[j] = 0.0;
        }
    }

    return 0;
}


