__author__ = 'jdaniel'

from Algorithms import serial
from GaiaSolve.algorithm import Algorithm


class SERIAL(Algorithm):
    def __init__(self):
        """
        Wrapped version of the serial NSGA-2 algorithm
        :return: None
        """
        super(SERIAL, self).__init__()

    def run(self):
        """
        Run the algorithm
        :return:
        """
        opt = serial.Serial(self.objective_function)

        # Add the design variables
        for i in xrange(self.model.number_of_design_variables):
            name = self.model.decision_variable_names[i]
            lower = self.model.lower_bound[i]
            upper = self.model.upper_bound[i]
            opt.register_variable(name, lower, upper)

        if self.model.has_equality_constraints:
            for i in xrange(self.model.number_of_equality_constraints):
                name = self.model.equality_constraint_variable_names[i]
                opt.register_constraint(name, 'e')

        if self.model.has_inequality_constraints:
            for i in xrange(self.model.number_of_inequality_constraints):
                name = self.model.inequality_constraint_variable_names[i]
                opt.register_constraint(name, 'i')

        for i in xrange(self.model.number_of_objectives):
            name = self.model.objective_variable_names[i]
            opt.register_objective(name)

        for key, value in zip(self.options.keys(), self.options.values()):
            opt.set_options(key, value)

        soln, meta, gen, arch, hist = opt.run()

        return soln, meta, gen, arch, hist

    def objective_function(self, x):
        """
        Objective function for evaluating the model
        :param x:
        :return:
        """
        self.model.x = x
        f = self.model.obj
        h = self.model.eqcon
        g = self.model.neqcon

        return f, h, g

if __name__ == '__main__':
    opt = SERIAL()
    print (opt.__class__)

