

#ifndef antH
#define antH

#include <vcl.h>

#include "point.h"
#include "network.h"
#include "obstacle.h"
#include "utility.h"

#define f_speed 0.25

#define last_move_size 8

class ant_class;

class sensor_class
{
  public:
    void set(float the_dist, int the_dir, TColor the_act_color);
    bool get_value(void) {return value; };

    void update_vector( point ant_pos, int ant_dir );

    void update_value( vector<obstacle_class> &obstacles, vector<ant_class *> &ants);

    void draw(Graphics::TBitmap *buffer);

    bool* value_ptr( void ) { return &value; };


  private:
    float dist;
    int dir;
    point pos;
    bool value;
    TColor act_color;
};


class ant_class
{
  public:
    ant_class(  vector<obstacle_class> &obstacles, vector<ant_class *> &ants );
    ~ant_class(void);


    void __fastcall update(vector<obstacle_class> &obstacles, vector<ant_class *> &ants);
    void __fastcall update_vectors( void );

    void __fastcall update_sensor_values( vector<obstacle_class> &obstacles, vector<ant_class *> &ants);

    void __fastcall update_movement( vector<obstacle_class> &obstacles);
    void __fastcall toggle_self ( void );

    void __fastcall mutate_node( void );

    void __fastcall check_dead( void );
    void __fastcall check_pain( void );

    bool __fastcall point_inside( point p );

    float __fastcall next_move_check(float m);

    void __fastcall draw(Graphics::TBitmap *buffer);

    void __fastcall setup_sensors( void );


    bool __fastcall get_self_control( void ) { return (self_control); };
    bool __fastcall get_selected( void ) { return (selected); };
    void __fastcall get_stat(char *stat);
    point __fastcall get_pos( void ) { return(pos); };
    int __fastcall get_dir( void ) { return(dir); };

    trig_data_type get_trig_data(void) { return trig_data; }; 

    int __fastcall get_y_dir( void ) { return(y_dir); };

    void __fastcall set_selected( bool s ) { selected = s; };
    void __fastcall toggle_selected( void ) { selected = !selected; };


    void move(move_type move);

    void setup_network( void );
    void process_network( void );

    void update_trig_data( void );

private:
    // the bounding box
    point bound_forward_right;
    point bound_forward_left;
    point bound_rear_right;
    point bound_rear_left;

    // arrow points
    point arrow_front;
    point arrow_rear;
    point arrow_left;
    point arrow_right;

    // sensors
    sensor_class f_warning[6];
    sensor_class f_pain[6];
    sensor_class r_warning[6];
    sensor_class r_pain[6];

    network_class net;  // the neural network

    float last_moves[last_move_size]; // buffer to check for oscillation

    int stuck_count, pain_count,  mutate_count;

    float forward, turn;

    float dir;      // world direction
    float y_dir;      // world direction

    trig_data_type  trig_data;

    point pos;      // world position

    bool  self_control, selected;

};

#endif
