#ifndef _APP_H__
#define _APP_H__

// eric amram's public domain GLform library 
#include "glforms/glforms.H"
#include "kdtreeVis.h"

// library includes
#include "gprims/vector.H"


// include geometry typedefs, class defs
// #include "object.H"


/*
 * This structure is available to the event callbacks 
 *
 *
 * typedef struct MOUSEINFO_tag {
 *
 *      // current mouse X Position
 *      int   curX;         
 *      // current mouse X Position
 *      int   curY;         
 *      // previous mouse X Position
 *      int   prevX;        
 *      // previous mouse X Position
 *      int   prevY;   
 *      // ID of button which was clicked
 *      int   mouseButton;   
 *      // flag for button motion:  
 *      //   1 if button motion occurred between ButtonPress and ButtonRelease
 *      //   0 otherwise                     
 *      int   buttonMotion;  
 *      // event which generated this callback { ButtonPress, ButtonRelease }
 *      int   event;         
 *
 * } MOUSEINFO, *PMOUSEINFO;
 *
 *
 */

char* usr_msg;


// defined herein

class App;
class AppView;

// from object.H
typedef float Point3D[3]; // to avoid including object.H
typedef float Vector3D[3]; // to avoid including object.H
class GeomObject;
class XYRect;
class Sphere;


/*
 *  class AppView
 *
 * This is the base viewing class.  It handles the basic user-interaction
 * of a OpenGL canvases ( the windows in the application which display graphics ).
 * The basic application has two OpenGL canvases, which can be seen when the
 * program is run.  
 *
 * In the application, one canvas is for  "Two-Dimensional Orthographic" viewing, 
 * and the other is for "Three-Dimensional Perspective" viewing.
 *
 * Each of these canvases has been subclassed from AppView.  Default object
 * handling/selecting is implemented in AppView by the following functions:
 *
 *
 *  // draw the contents of user scene, in world space (GL setup/finish done for you)
 *  virtual void       UserDraw              ( void );
 *
 *  // handle Mouse ButtonPress, ButtonRelease, MotionNotify events, with eye/far ray
 *  // return 1 iff object has been modified, to force a deferred redraw
 *  virtual int        UserAction            ( float*, float*, PMOUSEINFO, PHANDLE );
 *
 *  // return opaque pointer to currently selected object, if any
 *  virtual PHANDLE    UserHandle            ( void );
 *
 *
 */
class AppView : public DisplayGLCanvas {

  // constructors
public:
  AppView                                  ( App * );
  AppView                                  ( App *, AppView * );
  AppView                                  ( void );
  

  // User functions derived from DisplayGLCanvas
public:
  virtual void       UserBounds            ( Point3&, Point3& );
  virtual void       UserDraw              ( void );
  virtual PHANDLE    UserHandle            ( void );
  virtual int        UserAction            ( const Point3&, const Point3&, 
					     PMOUSEINFO, PHANDLE );

  // UserGLInit is called once per canvas during the  
  // initialization of the application to setup OpenGL
  virtual void       UserGLInit            ( void );

public:
  // this is called back whenever a refresh is warranted
  // all user code to draw their scene, etc., goes here
  int                UserRefresh            ( void );
  void               logStuff               ( void );

public:
  App                *_app;                 // the associated App
};




//
// class App3DView 
//
// An App3DView is a subclass of an AppView, with only slight differences:
//   1) App3DView overloads UserGLInit() to effect a perspective view.
//
class App3DView : public AppView {
public:
  App3DView                                  ( App *, AppView * );
  App3DView                                  ( App * );
  
public:
  virtual void       UserGLInit              ( void );
};
  


// 
// App 
//
// This is the main application structure.
// Its job is to maintain the objects which are being displayed.
// It also contains the AppView objects necessary for viewing.
//
//
class App {
public:
  App                                        ( );
  
public:
  static int         Select                  ( float *, float *, int );
  void               initGLforms             ( void );
  void               createObject            ( const Point3& );
  void               deleteObject            ( GeomObject * );
  
public:
  App3DView           *app3DView;            // derived 3D view (hack) XXX
  
  GeomObject         **_objects;             // array of pointers to GeomObject
  int                  _numObjects;          // number of such objects in array
  Point3               _capteye;             // captured eyepoint
  Point3               _captfar;             // captured farpoint

  PHANDLE              _currObject;   // opaque pointer to object to be highlighted, or NULL

  XForms < FD_main >  *_appForm;      // the xforms from which all events arise (see ui.C)
};

// endif APP_H_
#endif








