#include <vector.h>
#include <Graphics.hpp>

#ifndef NET_H
#define NET_H

#define neuron_x_size 20        // width in pixels
#define neuron_y_size 20        // height in pixels

/* all of the class that we are going to be using */
class axon_class;
class neuron_class;
class neural_network_class;


typedef enum {_in, _out, _or, _and, _not} neuron_type;


/* neuron connector */
class axon_class
{
  public:
     // return a an axon with a certin weight connected to a certin neuron
    axon_class(unsigned int the_id, double theweight);

    neuron_class *source;       // where the neuron is connected to
    unsigned int source_id;     // unique ID of the source neuron
    double weight;              // the weight of this connection
};


/* neuron */
class neuron_class
{
  public:
    // creates returns a neuron at the position
    neuron_class( int the_x_pos, int the_y_pos, neuron_type the_type, unsigned int the_id );
  
    // process this neuron
    void process ( void );

    // form an axon to another neuron
    void connect (unsigned int the_id, double theweight);
    void remove ( void );

    vector<axon_class> axons;   // all of the connections to other neurons

    unsigned id;

    double output;              // the cuttent output

    neuron_type type;

    unsigned int level;                  // number of levels away from an input



    // gui functions
    void display ( void );
    void erase(void);
    void move (int the_x_pos, int the_y_pos );
    void toggle ( void );

    // gui variables
    int x_pos, y_pos;
    int selected;
};



/* the neural network */
class neural_network_class
{
  public:
    // network constructor
    neural_network_class ( void );
    // calculate all of the neuron outputs
    void resolve_axons ( void );



    void process( void );
    // display the entire network
    void display( void );
    // clear all of the network variables
    void reset( void );
    // adds a neuron to the network at the passed position
    void add( int the_x_pos, int the_y_pos, neuron_type the_type, unsigned int id );

    neuron_class *get_neuron_pointer(unsigned int the_id);


    // remove a neuron from the network
    void remove( void );

    // gui functions (not network related)
    void select_object(int the_x_pos, int the_y_pos);
    neuron_class * get_neuron_mouse_over(int the_x_pos, int the_y_pos);
    void unselect_all ( void );

    // gui variables (not network related)
    unsigned int move_x_ofs, move_y_ofs;
    unsigned int num_selected;
    unsigned int num_neurons;
    unsigned int num_axons;

    unsigned int next_id;

    // neural network variables
    vector<neuron_class> neurons; // all o fht neurons
};

#endif


