#ifndef NEURAL_NET_H
#define NEURAL_NET_H

#include <vector>
#include "neuron.h"
#include "linear_neuron.h"

//class Neuron;

struct TrainingSetEntry{
	std::vector<double> features;
	double result;
};

//typedef std::vector<Neuron> Layer;
typedef std::vector<double> NetTopology;
typedef std::vector<TrainingSetEntry> NNTrainingSet;

class NeuralNet{
public:
	NeuralNet(const NetTopology &topology);
	virtual ~NeuralNet() = default;
	/**
	 * Takes a vector of input values and feeds them forward through the network.
	 * The output can be retrieved with the method get_results().
	 */
	void feed_forward(const std::vector<double> &input_values);

	/**
	 * Give the network the expected results. The network then back propagates the expected value and adjusts the weights in the network.
	 */
	void back_propagation(const std::vector<double> &expected_results);
	void get_results(std::vector<double> &out_results) const;
	double get_error() const;
	virtual void calculate_error(const std::vector<double> &delta);
	void add_training_set_entry(const std::vector<double> &features, double result);
	void train_network(int num_epochs);
	void train_network();
	void dump_training_set();
	void set_epochs(int epochs);
private:
	std::vector<Layer> layers;
	double error;
	NNTrainingSet training_set;
	int epochs = 500;
	double av_error = 0;
};

#endif
