// -*- C++ -*-
#ifndef RIWINDOW_H
#define RIWINDOW_H
/* Copyright 1996 
 * Wed Jan 28 14:00:42 1998  Brian Smits  (bes@phoenix.cs.utah.edu)
 * 
 * RiWindow.H
 * 
 *	
 * 
 * $Id: RiWindow.H,v 1.1 1998/08/12 20:17:30 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

class RiWindow;

/***************************************************************
CLASS
    RiWindowAction
    Holds actions for the RiWindow class and it's subclasses

DESCRIPTION
     This class helps implement a convoluted process.  When the app
     wants to send a command to the windowing thread it calls a member
     function on the RiWindow.  The member function creates an RiWindowAction
     that holds the RiWindow and a pointer to a (RiWindow static member) function
     that takes an RiWindow pointer.  The static member function calls the correct
     member function on the RiWindow.  The RiWindowAction is queued up to be
     processed by the Gui thread.

****************************************************************/

class RiWindowAction {
  public:
				////
    typedef void ActionFunction(RiWindow *);
    // GROUP: Constructors and assignment
    //// Default Constructor
    RiWindowAction(RiWindow *win, ActionFunction *act);
    // GROUP: Members
				//// Call the action function with the window.
    void 	Act();
  protected:
    RiWindow 		*win;
    ActionFunction	*act;
};




/***************************************************************
CLASS
    RiWindow
     <one line summary> 

DESCRIPTION
     <Detailed description with any warnings>

KEYBOARD BINDINGS
     q  quit (close window)
     s  save to file <winname>.tif

     
****************************************************************/

class RiWindow {
  public:
    // GROUP: Constructors and assignment
    //// Default Constructor
    RiWindow(int sizeX = -1, int sizeY = -1, int posX = -1, int posY = -1);
    //// Destructor
    virtual ~RiWindow() {};
    // GROUP: Accessors
				////
    int		GetWidth();
				////
    int		GetHeight();
				////
    int		GetXPosition();
				////
    int 	GetYPosition();
    // GROUP: Members
				//// open the window
    void Open(const char *name);
				//// close the window
    void Close();
				//// save the contents of the window
    void Save();
				//// Tell the gui that the window needs to be redrawn
    void NeedsRedraw();
				//// Tell the gui to resize the window.
    void SetSize(int width, int height);
				//// Trigger the Timeout method in ms milleseconds
    void AddTimeout(int ms);
				//// Useful for knowing when to kill the app
    static int GetNumOpenWindows();
  protected:
				////  Print info about any mouse and keyboard commands that apply (should
				//   call parent although this will cause ugly formating)
    virtual void PrintHelp();
				////  Opens window if not already opened.
    void  MakeCurrent();
				////									
    virtual void Keyboard(unsigned char key, int x, int y);						
				////									
    virtual void Mouse(int button, int state, int x, int y);						
				//// Timeout returns the time in milleseconds until the next timeout
				// use negative values for no more timeouts
				// This implementation does nothing and returns -1.  Overload as needed.
    virtual int Timeout();
				////
    virtual void Redraw();										
				//// actions to be performed upon reshaping the window			
				// size[XY] and pos[XY] will have been updated.				
    virtual void Reshape();										
				//// really open the window						
    virtual void DoOpen();										
				//// really close the window						
    virtual void DoClose();										
				//// really save the window						
    virtual void DoSave();										
				//// really notify the system that the window needs to be redrawn	
    virtual void DoNeedsRedraw();
				//// really notify the system that the window needs to be redrawn	
    virtual void DoSetSize();
				//// really insert the timeout function for the window.
    virtual void DoAddTimeout();
				////  Insert an action to be processed by the gui thread
    static void InsertAction(const RiWindowAction &act);
				////
    static void GuiLock();
				////
    static void GuiUnlock();
				////
    static RiWindow *GetCurrentWindow();
  private:
				////  current sizes for the window
    int  sizeX, sizeY, posX, posY;
				////
    bool opened;
				////
    bool mode;
				////
    char name[21];
				////
    int  winID;
				//// initial timeout time in ms
    int timeoutTime;
    
  private:			// GROUP: Static Class Members
				////Copy Constructor
    RiWindow(const RiWindow &);
				//// Assignment
    RiWindow &operator=(const RiWindow &);
				//// Initialize the glut stuff exactly once.
    static void InitGLUT();
				////  Thread function
    static void GuiThread(int *);
				////
    static int numWindowsOpen;
				////
    static bool inited;
				////  Deal with queued up actions (only called by gui thread)
    static void ProcessActions(int dummy);
				//// Dispatches the redraw virtual function
    static void RedrawFunction();
				//// Dispatches the reshape virtual function after changing the
				//   window's size and pos
    static void ReshapeFunction(int w, int h);
				//// Dispatches the keyhandler  virtual function 
    static void KeyboardFunction(unsigned char key, int x, int y);
				//// Dispatches the mouse  virtual function 
    static void MouseFunction(int button, int state, int x, int y);
				// GROUP: Action functions
				////  
    static void OpenAction(RiWindow *win);
				////  
    static void CloseAction(RiWindow *win);
				////  
    static void SaveAction(RiWindow *win);
				////  
    static void NeedsRedrawAction(RiWindow *win);
				////  
    static void SetSizeAction(RiWindow *win);
				////
    static void AddTimeoutAction(RiWindow *win);
				////  The function registered in the callback.  dispatches Timeout
    static void TimeoutFunction(int winID);
};


/***************************************************************
CLASS
    Ri2DWindow
     Encapsulates a glut window for 2D drawing.

DESCRIPTION

KEYBOARD BINDINGS
     u  zoom in
     o  zoom out
     i  move up
     j  move left
     k  move down
     l  move right

****************************************************************/

class Ri2DWindow : public RiWindow {
  public:
				// GROUP: Constructors and assignment
				//// Default Constructor
    Ri2DWindow(int sizeX = -1, int sizeY = -1, int posX = -1, int posY = -1);
				// GROUP: Accessors
				//// Set the fraction of the window to translate with each key press
    void SetTranslateFraction(RiReal newFraction);
				//// Set scale base for scaling.  2 means double/half each time.
    void SetScaleBase(RiReal newBase);
				// GROUP: Members
  protected:
				//// Print the help for this window.
    virtual   void  PrintHelp();
				////  Handle keyboard input
    virtual void Keyboard(unsigned char key, int x, int y);
				//// actions to be performed upon reshaping the window
				// size[XY] and pos[XY] will have been updated.
    virtual void Reshape();
				//// really open the window						
    virtual void DoOpen();
				//// really notify the system that the window needs to be redrawn	
    virtual void DoSetSize();
				////
    RiReal 	GetTranslateX();
				////
    RiReal 	GetTranslateY();
				////
    RiReal 	GetScale();

  private:
				//// Variables controling display.
    RiReal transX, transY, scale;
				//// base for changing scale
    RiReal base;
				//// fraction of the screen dimension to translate by.
    RiReal transFraction;
};

 
#endif /* RIWINDOW_H */

