#ifndef LSYSGLCANVAS_H
#define LSYSGLCANVAS_H

#include <vector>
#include "wx/defs.h"
#include "wx/string.h"
#include "wx/glcanvas.h"

#include "vect3.h"

#include "UIBaseClass.h"
#include "GL_Lsystem.h"

struct viewpoint_info 
{
  viewpoint_info operator=(const viewpoint_info &vi);
  GLfloat quat[4];        // orientation of object
  GLfloat centre[3];      // centre of object
  GLfloat zoom;           // field of view in degrees
};

class LsysGLCanvas: public wxGLCanvas, public UIClass
{
 public:
  LsysGLCanvas(wxWindow                 *parent,
	       // Lturtle parameters
	       float                    *min_thick_value, 
	       vector <vect3<GLfloat> > *C_arr,
	       // display parameters
	       vect3<GLfloat>           *BackgroundColour,
	       vector<LightClass>       *Lights, 
	       MutationParameters       *mut_param,
	       // others
	       LsysGLCanvas             **s, 
	       vect3<GLfloat>           *BorderCol          = NULL,
	       vect3<GLfloat>           *HighlightBorderCol = NULL,
	       const wxPoint&           pos  = wxDefaultPosition, 
	       const wxSize&            size = wxDefaultSize);
  ~LsysGLCanvas(void);
  
  void Paint();
  void OnPaint(wxPaintEvent& event);
  void OnSize(wxSizeEvent& event);
  void OnKeyDown( wxKeyEvent& event );
  void OnEraseBackground(wxEraseEvent& event);
  void OnMouse( wxMouseEvent& event );
  
  //canvas size manipulation
  void SetNormalSize(int x, int y, int width, int height);
  void SetToNormalSize();

  // viewing manipulation
  void   display_Lstring_growing();
  void   zoom(float amount);
  void   spin(float *spin_quat);
  void   set_viewpoint_to(LsysGLCanvas &c);
  void   reset_viewpoint(void);
  void   scale_to_fit();


  // breeding
  void   take_Picture(GLint x, GLint y, GLsizei width, GLsizei height, GLvoid *storage);
  void   copy(LsysGLCanvas &c);
  void   mutate(mutations mut);
  void   copy_with_mutation(LsysGLCanvas &c, mutations mut);
  
  // general  
  bool Selected();

  // UI Class derivatives
  unsigned int get_MaxStringSize();
  unsigned int get_MaxLineLength();
  r32  get_min_thick();
  bool is_rand_set();
  bool is_trope_set();
  r32  get_trope_amount();
  r32  get_tr();
  r32  get_dis();
  r32  rand_amount();
  
  //error messages
  void ProgrammingError(char *method, char *text);
  void Error(ERRORS err);
 private:

  //data
  viewpoint_info info;
  float          *min_thick;
  LsysGLCanvas   **the_Selected;
  vect3<GLfloat> *b_col;
  vect3<GLfloat> *h_col;
  GLfloat        AspectRatio;
  sizing_type    sizing;
  int            normal_size_x, normal_size_y, normal_size_w, normal_size_h;
 public: 
  GL_Lsystem     *the_Lsystem; 

  DECLARE_EVENT_TABLE()
};

#endif
