/*
 * File:   problema.h
 * Author: Andréa
 *
 * Created on 8 octobre 2010, 20:44
 */

#ifndef PROBLEMA_H
#define	PROBLEMA_H

#include <stdlib.h>

#include "configuration.h"
#include "persistentItem.h"

typedef enum constraintType {
	EQUALITY,
	INEQUALITY
} ConstraintType;

typedef struct _constraint_list {
	problem_constraint       constraint;
	char                    *text;
	ConstraintType           type;
	struct _constraint_list *next;
} ConstraintList;

/**
 * Probleme mathématique 'extends PersistentItem'
 */
typedef struct _problema
{
    //data
    PersistentItem*  _db_item;                             	     /* Database id */
    char             *name;                    /* Libellé */
    char             *functionRepresentation;  /* Representation de la fonction */
    unsigned short   _dimension;                                 /* Dimension de la fonction objectif */
    problem_function _function;                                  /* Fonction à optimiser */

    ConstraintList  *_constraints;  							 /* Contraintes de domaine */
    problem_function _derivees[MAX_ITEM];                        /* dérivées de la fonction */

    double*          _solution;                            /* solution du problème */

    //method
    													/*Calculation function*/
    double*      (* compute)                 (struct _problema*, const double[], size_t);
                                                        /* toString */
    char*        (* display)                 (struct _problema*);
    													/* setter for db_id */
    void         (* setId)					 (struct _problema*,unsigned long);
                                                        /* getter for db_id */
    unsigned long(* getId)                   (struct _problema*);
                                                        /* setter for an problem solution */
    void         (* setSolution)             (struct _problema*,const double[]);
} Problema;

// Constructor~Destructor
Problema* createProblemaSkeleton();

/**
 *  Build a problem with parameters
 *
 * @param id
 *  database id
 * @param name
 *  problem name
 * @param function_representation
 *  string which reprensents the function's equation
 * @param dimension
 *  dimension of input's space
 * @param function
 *  pointer to the function
 * @return
 *  result problem
 */
Problema* createProblema(
        unsigned long id,
        char*         name,
        char*         function_representation,
        unsigned int  dimension,
        problem_function function);

/**
 * Free the space taken by this pointer
 * @param pb
 *  problem
 */
void      destroyProblema(Problema *);


/**
 * Add a constraint to given problem
 * @param pb
 *  problem
 * @param function
 *  constraint function
 * @return
 *  problem with the constraint added if succeed, null otherwise
 */
Problema* addConstraint(Problema *, char*, ConstraintType, problem_constraint);


/**
 * Add a derivee to given problem
 * @param pb
 *  problem
 * @param function
 *  derivee function
 * @param order
 *  derivee order
 * @return
 *  problem with the derivee added if succeed, null otherwise
 */
Problema* addDerivee    (Problema *, double* (*)(const double[]), unsigned int);

#endif	/* PROBLEMA_H */

