package com.naaturel.ANN.domain.model.helpers;

import com.naaturel.ANN.domain.abstraction.ActivationFunction;
import com.naaturel.ANN.domain.abstraction.Model;
import com.naaturel.ANN.domain.model.neuron.*;
import com.naaturel.ANN.implementation.simplePerceptron.Heaviside;

import java.util.ArrayList;
import java.util.List;

public class ModelCreator {

    public static Model createPerceptron(int nbrInputs){
        List<Synapse> syns = new ArrayList<>();
        for (int k = 0; k < nbrInputs; k++){
            syns.add(new Synapse(new Input(0), new Weight(0)));
        }

        Bias bias =  new Bias(new Weight(0));
        return new Neuron(0, syns.toArray(new Synapse[0]), bias, new Heaviside());
    }

    public static Model createModel(int[] neuronPerLayer, int nbrInput, ActivationFunction func){
        int neuronId = 0;
        List<Layer> layers = new ArrayList<>();
        for (int i = 0; i < neuronPerLayer.length; i++){

            List<Neuron> neurons = new ArrayList<>();
            for (int j = 0; j < neuronPerLayer[i]; j++){

                int nbrSyn = i == 0 ? nbrInput: neuronPerLayer[i-1];

                List<Synapse> syns = new ArrayList<>();
                for (int k=0; k < nbrSyn; k++){
                    syns.add(new Synapse(new Input(0), new Weight()));
                }

                Bias bias =  new Bias(new Weight());

                Neuron n = new Neuron(neuronId, syns.toArray(new Synapse[0]), bias, func);
                neurons.add(n);
                neuronId++;
            }
            Layer layer = new Layer(neurons.toArray(new Neuron[0]));
            layers.add(layer);
        }

        return new FullyConnectedNetwork(layers.toArray(new Layer[0]));
    }
}
