////////////////////////////////////////////////////////////////////
// Name:        App.h
// Purpose:     Blind Watchmaker-like L system viewer
// Author:      Yan Wong
// Licence:   	GPL
////////////////////////////////////////////////////////////////////

#ifndef _APP_H
#define _APP_H

#define ROWS 3
#define COLS 5
#define P_ROW 1
#define P_COL 2


enum {ID_EXIT=500,
      ID_OPEN,
      ID_SAVE,
      ID_EXPORT,
      ID_CHG_SEED,
      ID_GROW,
      ID_VIEW_TEXTFRAME,
      ID_VIEW_DETAILED,
      ID_SCALE_TO_FIT,
      ID_UNIFY_VIEW,
      ID_BREED,
      ID_NO_ANIMATION,
      ID_MUTATE_RAT,
      ID_MUTATE_PARAM,
      ID_MUTATE_ADD_R,
      ID_MUTATE_DEL_R,
      ID_MUTATE_ADD_TO,
      ID_MUTATE_DEL_FROM,
      ID_ABOUT,
      ID_HELP_BASIC,
      ID_HELP_MENU,
      ID_HELP_LSYSTEM,
      ID_HELP_MUTATIONS,
      ID_HELP_TUTORIAL,
};


#include "vect3.h"
#include "LsysGLCanvas.h"
#include "AnimateGLCanvas.h"
#include "MyTextFrame.h"
#include "wx/defs.h"
#include "wx/app.h"
#include "wx/menu.h"
#include "wx/string.h"
#include "wx/frame.h"

/* Define a new application type */
class MyApp: public wxApp
{
public:
  bool OnInit(void);
};

DECLARE_APP(MyApp);

/* Define a new frame type */
class MyFrame: public wxFrame
{
 public:
  MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, 
	  const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
  ~MyFrame();

  void OnSize(wxSizeEvent &event);
  void OnExit(wxCommandEvent& event);
  void OnOpen(wxCommandEvent& event);
  void OnSave(wxCommandEvent& event);
  void OnExport(wxCommandEvent& event);
  void OnChangeSeed(wxCommandEvent& event);
  void OnGrow(wxCommandEvent& event);
  void OnBreed(wxCommandEvent& event);
  void OnUnifyView(wxCommandEvent& event);
  void OnViewDetailed(wxCommandEvent& event);
  void OnScaleToFit(wxCommandEvent& event);
  void OnMutateRAT(wxCommandEvent& event);
  void OnMutateParam(wxCommandEvent& event);
  void OnMutateAddR(wxCommandEvent& event);
  void OnMutateDelR(wxCommandEvent& event);
  void OnMutateAddTo(wxCommandEvent& event);
  void OnMutateDelFrom(wxCommandEvent& event);
  void OnToggleTextFrame(wxCommandEvent& event);
  void OnAbout(wxCommandEvent& event);
  void OnHelp(wxCommandEvent& event);
  void OnLTextChanged(wxCommandEvent& event);
  void OnKeyDown( wxKeyEvent& event );
  void OnMouse( wxMouseEvent& event );

  //non-event based methods
  void UnifyView(LsysGLCanvas *the_Selected);
  void UnifyView(unsigned int i, unsigned int j);
  void UnifyView();
  void ChangeSelected(LsysGLCanvas *new_Selected);
  void ChangeSelected(unsigned int i, unsigned int j);
  void ToggleTextFrame();

 private:
  void size_up();
  void breed_from(LsysGLCanvas *the_Selected);
  void breed_from(unsigned int i, unsigned int j);
  
  void Exit();
  bool open(wxString name, LsysGLCanvas *the_Selected);
  void save(wxString name, LsysGLCanvas *the_Selected);
  bool findSelected(unsigned int &i, unsigned int &j, LsysGLCanvas *the_Selected);
  bool findSelected(unsigned int &i, unsigned int &j);
  void mutate(LsysGLCanvas *the_Selected, mutations mut);
  bool mutate(mutations mut);
  bool zoom(float amount);
  bool display_Lstring_growing();
  void view_detailed(LsysGLCanvas *the_Selected);
  void scale_to_fit(LsysGLCanvas *the_Selected);
  void ParentToChildren();
  void ErrorUnselected();

 public:
  LsysGLCanvas     *Lsys[COLS][ROWS];
  AnimateGLCanvas  *AnimationCanvas;
  LsysGLCanvas     *Selected;
  MyTextFrame      *TextFrame;

DECLARE_EVENT_TABLE()
  private:
 unsigned int            Rows, Cols, p_width, p_height; 
 vector<vect3<GLfloat> > colours;
 vector<LightClass>      Lights;
 MutationParameters      *MutParam;
 vect3<GLfloat>          ParentBGColour;
 vect3<GLfloat>          AMutantBGColour;
 vect3<GLfloat>          PMutantBGColour;
 vect3<GLfloat>          *col_red;
 vect3<GLfloat>          *col_black;
 GLuint                  *PixBuffer;
 LsysGLCanvas            *maximised_view;
 float                   min_thick;
};

#endif
