/* 
   Project: coevolutionary GP moto driving
   Dana Vrajitoru
   moto_geometry.h
   
   The geometrical implementation of the motorcycle containing the
   necessary OpenGL commands.  
*/
   
#ifndef MOTO_GEOMETRY_H
#define MOTO_GEOMETRY_H

#include <GL/glut.h>
#include "point3f.h"

class Moto_geometry {
 protected:
  // IDs for the display listscontaining the OpenGL commands for the
  // independent parts of the motorcycle.
  GLuint fix_parts_id, wheel_id, handlebar_id;

  // The precision of the rendering.
  int precision;

  // The colors we are using so that we can set them the way we want.
  GLfloat saddle_r, saddle_g, saddle_b;
  GLfloat engine_r, engine_g, engine_b;
  GLfloat tire_r, tire_g, tire_b;
  GLfloat headlight_r, headlight_g, headlight_b;

  // Some positions and dimensions. We don't have a right wheel
  // position since it's the same as the handlebar.
  Point3f handlebar_pos, left_wheel_pos;
  float wheel_radius, wheel_distance;
  float mass;

 public:
  // Default constructor. Sets the id numbers and the default
  // colors. Does not create the display lists to be sure that we
  // don't want to set the colors to different values and draw the
  // motorcycle only afterwards. It should not be invoked before the
  // gl is initialized because it will create a segmentation fault.
  Moto_geometry();
  
  // Destructor. Delete the display lists hoping that it will restore
  // the memory.
  virtual ~Moto_geometry();

  // Set the ids of the display lists in case we have more than one
  // motorcycle.
  void set_ids();

  // Set the precision of the rendering. 1 would be wireframe type, 2
  // surfaced with raw polygons, 3 surfaced with lots of polygons.
  void set_precision(int value = 2);

  // Setting each of the colors and default values for each of them.
  void set_saddle_rgb(GLfloat r = 0.5, GLfloat g = 0.5, GLfloat b = 0.9);
  void set_engine_rgb(GLfloat r = 0.65, GLfloat g = 0.65, GLfloat b = 0.65);
  void set_tire_rgb(GLfloat r = 0.4, GLfloat g = 0.4, GLfloat b = 0.8);
  void set_headlight_rgb(GLfloat r = 1.0, GLfloat g = 1.0, GLfloat b = 0.2);

  // Set the positions.
  void set_handlebar_pos(GLfloat x = 2.0, GLfloat y = 1.0, GLfloat z = 0.0);
  void set_left_wheel_pos(GLfloat x = -2.0, GLfloat y = 1.0, GLfloat z = 0.0);

  // Define some dimensions
  float length();
  float width();
  float height();

  // Print some of these values
  void cout_headlight_rgb();

  // 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();
  // We may need to diplay individual components. These functions
  // should only call the display lists.
  void display_wheel();
  void display_handlebar();
  void display_fix_parts();

  // Position the handlebar and wheel so that we don't have to call
  // the gl command explicitly every time.
  void position_handlebar();
  void position_left_wheel();

  // The OpenGL commands for the fix parts. Not intended to be used by
  // themselves.
  void saddle();
  void engine();
  void fork();
  void frame();
  void engine_center();

  // The wheel centered in the origin of the space so as to rotate it
  // easily. When drawing it, we have to translate it to 2 locations.
  void wheel();

  // The handlebar
  void handlebar();
};

#endif
