#include "OptimizerBase.h"
#include <iostream>

namespace mdd{
	OptimizerBase::opt_state OptimizerBase::updateOutputs()
	{
		opt_state ret;
		ret.module_state = _module->update();
		if (ret.module_state != state::STATE_ERROR)
		{
			for (size_t i = 0; i < _output_vals.size(); ++i)
			{
				_output_vals[i] = _outputs[i]->getValue()[0];
				//std::cout << "get: " << i << ": " << _output_vals[i] << std::endl;
			}
			ret.opt_value = _func_expr.value();
			//std::cout << "get: " << "opt" << ": " << ret.opt_value << std::endl;
		}
		
		return ret;
	}

	void OptimizerBase::updateLayout()
	{
		_inputs = _module->getOptimizableInputs();
		_outputs = _module->getOptimizableOutputs();
		_output_vals.clear();
		for (auto& out : _outputs)
		{
			_output_vals.push_back(out->getValue()[0]);
		}
	}
	
	bool OptimizerBase::setEvaluation(std::string func)
	{
		updateLayout();
		exprtk::symbol_table<double> symbol_table;
		for (size_t i = 0; i < _output_vals.size(); ++i)
		{
			symbol_table.add_variable("out" + std::to_string(i), _output_vals[i]);
		}
		symbol_table.add_constants();
	
		_func_expr.register_symbol_table(symbol_table);
	
		exprtk::parser<double> parser;
		return parser.compile(func, _func_expr);
	}
	
}