/* 
   Project: coevolutionary GP moto driving
   Dana Vrajitoru
   moto_animate.h
   
   The control of the basic animation of the motorcycle without any
   physical considerations.
  
*/
   
#ifndef MOTO_ANIMATE_H
#define MOTO_ANIMATE_H

#include "moto_geometry.h"

class Moto_animate: public Moto_geometry {
 protected:
  GLfloat wheel_speed, handlebar_speed, lateral_speed;
  // These should not be explicitly set by the user.
  GLfloat wheel_angle, handlebar_angle, lateral_angle;

  // The position on the road and the orientation angle.
  Point3f road_pos;
  GLfloat orientation_angle, slope;

  // Just to make sure we know what this is.
  Point3f handlebar_axis;
  float max_handlebar_angle;
  
 public:
  // Default constructor. Sets all the speeds and angles to 0 and all
  // of the other parameters to their default values. Since it invokes
  // the constructor for Moto_geometry, it should not be invoked
  // before the gl is initialized.
  Moto_animate();

  // Destructor. Probably nothing to do.
  virtual ~Moto_animate();

  // Reset all the speeds and angles to 0.
  void reset();

  // Set and get the speeds.
  void set_wheel_speed(float speed);
  void set_handlebar_speed(float speed);
  void set_lateral_speed(float speed);
  GLfloat get_wheel_speed();
  GLfloat get_handlebar_speed();
  GLfloat get_lateral_speed();

  // Set and get the slope.
  void set_slope(float val);
  float get_slope();

  // Manipulate the handlebar angle.
  void set_handlebar_angle(float val=0);
  void add_handlebar_angle(float val=1);
  GLfloat get_handlebar_angle();

  // Initialize the road position and orientation angle.
  void set_road_pos(GLfloat x = 0.0, GLfloat y = 0.0, GLfloat z = 0.0);
  void add_road_pos(GLfloat x = 0.0, GLfloat y = 0.0, GLfloat z = 0.0);
  Point3f &get_road_pos();
  void set_orientation_angle(GLfloat angle = 0.0);
  void add_orientation_angle(GLfloat angle = 0.0);
  GLfloat get_orientation_angle();
  
  // Set this axis once and for all.
  void set_handlebar_axis(GLfloat x = -1.5, 
			  GLfloat y = 2.7, 
			  GLfloat z = 0.0);

  // The degree of freedom of the handlebar.
  void set_max_handlebar_angle(float angle = 30);

  // Creates the display lists containing the OpenGL commands for the
  // independent parts of the motorcycle.
  virtual void draw();
  
  // Calls all of the display lists.
  virtual void display();

  // Perform the general rotation and translation. We have to apply
  // these equally to the driver.
  void rotate_trans_all();

  // Performs one move of the motorcycle according to the speeds and
  // angles. Just updates the angles for now.
  void move();

  // Making this a function so we don't have to do it manually every
  // time.
  void rotate_handlebar();

  // Updating the speeds and angles.
  void update_angles();

  // Handlebar loop left-right. Written for testing purposes.
  void handlebar_loop();

  // get lateral angle  
  GLfloat get_lateral_angle();
};

#endif
