package net.woodyfolsom.msproj.ann2;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;

import net.woodyfolsom.msproj.ann2.math.ActivationFunction;
import net.woodyfolsom.msproj.ann2.math.Sigmoid;

public class Neuron {
	private ActivationFunction activationFunction;
	private int id;
	private transient double input = 0.0;
	private transient double error = 0.0;
	
	public Neuron() {
		//no-arg constructor for JAXB
	}
	
	public Neuron(ActivationFunction activationFunction, int id) {
		this.activationFunction = activationFunction;
		this.id = id;
	}
	
	public void addInput(double value) {
		input += value;
	}
	
	@XmlElement(type=Sigmoid.class)
	public ActivationFunction getActivationFunction() {
		return activationFunction;
	}
	
	@XmlAttribute
	public int getId() {
		return id;
	}
	
	@XmlTransient
	public double getError() {
		return error;
	}
	
	@XmlTransient
	public double getInput() {
		return input;
	}
	
	public double getOutput() {
		return activationFunction.calculate(input);
	}
	
	public void setError(double value) {
		this.error = value;
	}
	
	public void setInput(double input) {
		this.input = input;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((activationFunction == null) ? 0 : activationFunction
						.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Neuron other = (Neuron) obj;
		if (activationFunction == null) {
			if (other.activationFunction != null)
				return false;
		} else if (!activationFunction.equals(other.activationFunction))
			return false;
		return true;
	}
	
	public void setActivationFunction(ActivationFunction activationFunction) {
		this.activationFunction = activationFunction;
	}
	
	@Override
	public String toString() {
		return "Neuron #" + id +", input: " + input + ", error: " + error;
	}

}