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

#include "utilities.h"
#include "logger.h"

#include "method.h"
#include "persistentItem.h"

static
void clearAllResult(struct _method* m)
{
	int i;
	for(i=0;i<MAX_ITEM;i++)
		free(m->parameters.parameters[i]);

	m->parameters.data_loaded = 0;

    free(m->_last_result);
    m->_last_result = NULL;

    m->_last_result_function_value = -1.0;
    m->_last_absolute_error        = -1.0;
    m->_last_complexity            = -1;

    m->_result_loaded = FALSE;
}

static
void setDatabaseId(struct _method* method, unsigned long id)
{
	if( !method->_db_item )
		method->_db_item = createPersistentItem(id);
	else
		method->_db_item->_db_id = id;
}

static
unsigned long getDatabaseId(struct _method* method)
{
	if( method->_db_item )
		return method->_db_item->getId(method->_db_item);
	else
		return 0;
}

static
Method* createMethodSkeleton()
{
    Method * entity = (Method * )malloc(sizeof(Method));

    // error
    handleError(
            !entity,
            NULL,
            "method creation",
            "error during pointer allocation");

    // initialize
    // - dummy id
    entity->_db_item = NULL;
    // - clear name tab
    entity->_name = NULL;
    // - method function
    entity->_method_function = NULL;
    entity->_last_result     = NULL;

    // methods
    entity->clearResult = clearAllResult;
    entity->setId       = setDatabaseId;
    entity->getId       = getDatabaseId;

    return entity;
}

// Public
Method* createMethod(
        unsigned long    id,
        char*            name,
        algorithm_method function
)
{
    Method* m = NULL;
    int i;

    m = createMethodSkeleton();

    m->_db_item = createPersistentItem(id);
    m->_name =(char *)malloc(strlen(name)*sizeof(char));
    strcpy(m->_name,name);
    m->_method_function = function;
	m->_result_loaded   = FALSE;

	for(i=0;i<MAX_ITEM;i++)
		m->parameters.parameters[i] = NULL;
	m->parameters.data_loaded = 0;

    return m;
}

void    destroyMethod(Method * m)
{
	int i;
	destroyPersistentItem(m->_db_item);
    free(m->_name);
	for(i=0;i<MAX_ITEM;i++)
		free(m->parameters.parameters[i]);
    free(m->_last_result);
    free(m);
}
