/* 
   Project: coevolutionary GP moto driving
   Dana Vrajitoru
   manager.h
   
   The class that manages the motorcycle, the driver, and the road.
  
**/

#ifndef MANAGER_H
#define MANAGER_H

#include <ctime>
#include "moto_behave.h"
#include "driver_behave.h"
#include "road_manager.h"
#include "pilot_manager.h"

class Manager {
 protected:
 public:

  // Making these public vecause otherwise it would be too messy to
  // build the interface. Maybe they could become protected later.
  Moto_behave *moto;
  Driver_behave *driver;
  Road_manager *road;
  Pilot_manager *pilot;

  int marker_id;
  int triangle, old_triangle;
  bool pilot_on, time_on,circuit_completed,input_taken;
  int flag;
  time_t timer;                   
  // Evaluation data
  double speed_sum, speed_max;
  double lateral_sum, total_ds;
  int frame_count; 
  float off_road_count, off_road_time;
  float old_left_push, old_right_push;
  int left_turn_count, right_turn_count;
  float old_lean;
  float left_lean_sum, right_lean_sum;
  float left_lean_frame_count, right_lean_frame_count;
  float left_lean_count, right_lean_count;
  float off_road_average;

  Point3f horizon, position, left_pos, right_pos, pos, fpos;
  Point3f forward_left_pos, forward_right_pos;
  Point3f left_horizon, right_horizon;                           
  Point3f second_left_horizon, second_right_horizon;

  float slope;
  float thr_slope_low, thr_slope_high;
  float side_watch, front_watch;

  // Default constructor: make all the pointers null.
  Manager();
  // Destructor: delete all the pointers.
  ~Manager();
  
  //-------------------------------------------------
  // added by pk
  //Toggle the pilot on and off for number of
  // trials
  void toggle_pilot1(int sflag);
  //------------------------------------------------ 
  // Toggle the pilot on and off.
  void toggle_pilot();

  // Toggle the timer on and off.
  void toggle_timer();

  // Default initializer. Move all the murky stuff from the
  // application in here. Initialize the moto, driver, and road, and
  // make the display lists for each of them.
  void init();

  // To be called to initialize the objects for the small window.
  void redraw_small();

  // Draw a lil sphere that we can use to mark the horizon point and the
  // lateral distances. For debugging purposes mostly.
  void draw_marker(float radius);

  // Display the marker with a given color an position.
  void display_marker(Point3f &position, 
		      float r=1.0, float g=0.0, float b=0.0);

  // Computes the intersection of the direction of movement with the
  // border of the road, as well as of two lateral vectors going left
  // and right at a little distance in front of the motorcycle.
  // It takes the current triangle as a parameter.
  void compute_horizon(int trig);

  // Compute some statistics. For now just the average and maximal speed.
  void compute_stats();

  // Output the statistics
  void output_stats();

  // Reset all the statistics values so we can start again
  void reset_stats();

  // Reset the values checking for the circuit being completed.
  void reset_complete(int length);

  // Move all the objects.
  void move();

  // Call the display functions of all the components.
  void display();

  // Print the status of the motorcycle on the road
  void status();

  // Discretize the slope to 5 values, from -2 to 2.
  int discrete_slope();

  friend class Agent;
};

#endif
