///////////////////////////////////////////////////////////////////////////////
//////   Copyright 1992, Silicon Graphics, Inc.  All Rights Reserved.   ///////
//                                                                           //
// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;    //
// the contents of this file may not be disclosed to third parties, copied   //
// or duplicated in any form, in whole or in part, without the prior written //
// permission of Silicon Graphics, Inc.                                      //
//                                                                           //
// RESTRICTED RIGHTS LEGEND:                                                 //
// Use,duplication or disclosure by the Government is subject to restrictions /
// as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data    //
// and Computer Software clause at DFARS 252.227-7013, and/or in similar or  //
// successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -   //
// rights reserved under the Copyright Laws of the United States.            //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#ifndef VKSCREEN_H
#define VKSCREEN_H

///////////////////////////////////////////////////////////////////////////////
// VkScreen.h

#include <X11/Xlib.h>
#include <Vk/VkComponent.h>
#include <Vk/VkComponentList.h>
#include <Vk/VkAppProto.h>

class VkApp;
class VkDisplay;
class VkSimpleWindow;
class VkBusyDialog;
class VkDialogManager;
class VkGlobalData;
class VkCursorList;
class VkColormap;


/*******************************************************
CLASS
    VkScreen

OVERVIEW

    this class encapsulates the application data which
    is "screen" related...

    - every app has at least one "screen" object...

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

class VkScreen : public VkAppProto {

    friend class VkApp;
    friend class VkDisplay;
    friend class VkSimpleWindow;
    friend class VkQuickHelp;

  public:

  // Normal constructor -- most apps should use this one
    VkScreen(char              *name, 
	     VkDisplay         *vdpy,
	     ArgList           argList   = NULL,
	     Cardinal          argCount  = 0
	     );

  // This constructor is rarely needed.  The pricipal use is to allow setting
  // resources when creating the first shell.
  //	* Any resource that can be passed on the arglist, such as default
  //	  font list, should be passed in that way.
  //
  //	* Visual information cannot be known until after the display is
  //	  opened.  preRealizeFunction(w) will be called with the
  //	  baseWidget (i.e the shell).  This is after widget creation, but
  //	  before it is realized.
  //
  //	  At that time, the application can find the visual information
  //	  it needs, and do a setValues call.  The manual not withstanding,
  //	  since the widget has not yet been realized, this is OK -- provided
  //	  that the call sets *all* visual resources consistently.
  //
  // The motivation for all of this is that without it you could not have
  // a non-default-visual, single-visual, application.

    VkScreen(char             *name,
	     VkDisplay        *vdpy,
	     ArgList           argList,
	     Cardinal          argCount,
	     void            (*preRealizeFunction)(Widget w)
	     );

      virtual      ~VkScreen();

      virtual VkScreen  *getScreen();

    ////////////
    // Callback invoked when a new window registers itself
    // with the application object
    static const char *const newWindowCallback;

    ////////////
    // Callback invoked when a window unregisters itself
    // with the application object, normally when the
    // window object has been deleted
    static const char *const windowDestroyedCallback;

    virtual void terminate(int status = 0);

    ////////////
    // This sets a flag, determining whether subsequent VkSimpleWindow's
    // will be in the overlay planes or not.  This only works if it is
    // called before the application's VKApp is constructed.
    void useOverlayApps(const Boolean flag = TRUE);
    void useOverlayDialogs(const Boolean flag = TRUE);
    void useOverlayHelp(const Boolean flag = TRUE);
    void useOverlayMenus(const Boolean flag = TRUE);

    Boolean usingOverlayApps()     { return _useOverlayApps;    }
    Boolean usingOverlayDialogs()  { return _useOverlayDialogs; }
    Boolean usingOverlayHelp()     { return _useOverlayHelp;    }
    Boolean usingOverlayMenus()    { return _useOverlayMenus;   }

    void         handleRawHelpEvent(XEvent *event);
    void         handleRawEvent(XEvent *event);

    virtual void quitYourself();
    static  void useSchemes(const char*);

  
    // Let the app know that a particular "window" is the main one
    void         setMainWindow(VkSimpleWindow *);

    int          windowCount();
    Boolean      hasWindows();

    // Operations on all windows

    virtual void raise();
    virtual void lower();
    virtual void iconify();
    virtual void open();
    virtual void show();
    virtual void hide();

    void    startupIconified(const Boolean flag) { _startupIconified = flag; }

    virtual Cursor  busyCursor();
    virtual Cursor  normalCursor();
    void    setNormalCursor(const Cursor);
    void    setBusyCursor(const Cursor);
    void    setBusyCursor(VkCursorList *);
    void    showCursor(const Cursor);
    void    setAboutDialog(VkDialogManager *d) { _aboutDialog = d; }
    VkDialogManager*  aboutDialog() { return (_aboutDialog); }

    void    setStartupDialog(VkDialogManager *d) { _startupDialog = d; }
    VkDialogManager*  startupDialog() { return (_startupDialog); }

    virtual void         busy(const char *msg = NULL,     VkSimpleWindow *parent = NULL);
    virtual void         veryBusy(const char *msg = NULL, VkSimpleWindow *parent = NULL);
    virtual void         notBusy();

    virtual void         progressing(const char *msg = NULL);

    void           setBusyDialog(VkBusyDialog *);

    // NOTE: new API... [ used by "internal" SGI ViewKit classes ]
    //
    virtual VkGlobalData  *getGlobalData();

    XtAppContext        appContext();
    char               *name() const;
    Display            *display() const { return _dpy;}
    Screen             *screen();
    VkColormap         *cmap() const { return _vkcmap;}

    VkSimpleWindow     *mainWindow() const;
    char               *shellGeometry() const;  // The size of the hidden shell
    Boolean             startupIconified() const { return _startupIconified; }
    Boolean             isBusy() { return (_busyCounter > 0); }
    virtual const char *className();

    static void setFallbacks(char **);

    VkComponentList *windowList();

    ////////////
    // Support for providing help.
    // 
    // Historically, the way to provide help from a ViewKit
    // application has been to link the application with a library
    // that implemented the C functions SGIHelpInit(), SGIHelpMsg(),
    // and SGIHelpIndexMsg().  ViewKit and the application would call
    // these functions in response to users' requests for help.
    //
    // Starting in IRIX 6.5, help can also be provided by adding
    // callbacks to the "helpInitCallback", "helpMsgCallback", and
    // "helpIndexMsgCallback" lists.  Instead of calling the
    // SGIHelp*() functions, ViewKit and the application call the
    // VkScreen methods helpInit(), helpMsg(), and helpIndexMsg().
    //
    // If there are no callbacks installed on the corresponding
    // callback lists, the VkScreen help methods call the corresponding
    // SGIHelp*() methods so that old applications continue to work.
    // If callbacks are installed, the callbacks are called instead.
    //
    // An application that provides help using the sgihelp program can
    // call the VkScreen method useSGIHelp(), which will install:
    //
    //  sgiHelpInit() on the "helpInitCallback" list
    //  sgiHelpMsg() on the "helpMsgCallback" list
    //  sgiHelpIndexMsg() on the "helpIndexMsgCallback" list
    //
    // sgiHelpInit(), sgiHelpMsg(), and sgiHelpIndexMsg() interact
    // with the sgihelp program to provide the same help that
    // applications used to get by linking with -lhelpmsg.
    //
    // An application wishing to provide its own help mechanism can add
    // its own callbacks to the callback lists.  The following table
    // lists the callback names and the type for the "callData" argument
    // to the callbacks:
    //
    //  Name                 	callData
    //  ----------------------------------
    //  helpInitCallback	HelpInitArgs*
    //  helpMsgCallback		HelpMsgArgs*
    //  helpIndexMsgCallback	HelpIndexMsgArgs*
    //
    // After installing these callbacks, helpInit() will need to be
    // called.
    //

    ////////////
    // API for applications and ViewKit to use to invoke help.
    int helpInit(char *client, char *sep);
    int helpMsg(char *key, char *book, char *userData);
    int helpIndexMsg(char *key, char *book);

    ////////////
    // Callback lists for help.
    static const char *const helpInitCallback;
    static const char *const helpMsgCallback;
    static const char *const helpIndexMsgCallback;

    ////////////
    // API for applications that want to provide help using the
    // sgihelp program.
    void useSGIHelp();

    ////////////
    // Callbacks which when installed on the help callback lists
    // implement help using the sgihelp program.
    static void sgiHelpInit(VkCallbackObject* caller, void* clientData,
			    void* callData);
    static void sgiHelpMsg(VkCallbackObject* caller, void* clientData,
			   void* callData);
    static void sgiHelpIndexMsg(VkCallbackObject* caller, void* clientData,
				void* callData);

    VkDisplay  *getDisplay() { return _dpyBptr; }

  protected:

    VkComponentList   *_winList;
    Boolean            _default;

    // opaque...
    VkContextPtr       _contextData;

    int parseCommandLine(XrmOptionDescRec  *, Cardinal); 
    virtual void afterRealizeHook();
    Boolean _quitSemaphore;

    VkCursorList  *_busyCursorList;

    Boolean	   _useOverlayApps;
    Boolean	   _useOverlayDialogs;
    Boolean	   _useOverlayHelp;
    Boolean	   _useOverlayMenus;

    // NOTE:  these are the Vk 1.5.2 extension records... [ VkApp ]
    //
    Boolean	_helpEnabled;
    Boolean     _busyDialogVisible;
    Boolean     _manageShowHide;

    // helpEnabled() is called by the QuickHelp consructor.  It could be
    // public, but it is an internal imlementation detail tht we do not want
    // user apps to use.  So we make VkQuickHelp a friend of VkScreen.
    void helpEnabled (Boolean);

  private:

    static  XtResource _resSpec[];
    static  String _resources[];

    Cursor _busyCursor;
    Cursor _normalCursor;

    VkDialogManager *_aboutDialog;
    VkDialogManager *_startupDialog;

    void        createCursors();
    Boolean     manageShowHide();
  // Constructors' real initialization code
    void VkScreenInitialize( char             *name,
			     VkDisplay        *vdpy, 
			     ArgList           argList,
			     Cardinal          argCount,
			     void            (*preRealizeFunction)(Widget w)
			     );

    // Various data needed by other parts of an application

    char               *_shellGeometry;
    VkSimpleWindow     *_mainWindow;
    Display            *_dpy;
    char               *_scrName;

    // the backpointer (Bptr) to the VkDisplay which owns this VkScreen...
    //
    VkDisplay          *_dpyBptr;

    void                 addWindow ( VkSimpleWindow * );
    void                 removeWindow( VkSimpleWindow * );

    int                 _busyCounter;
    VkSimpleWindow     *_busyWindow;

    Boolean             _startupIconified;
    Boolean             _usePopupPlanes;
    static const char  *_useSchemes;
    static String      *_fallbacks;

    VkColormap         *_vkcmap;

    // NOTE: new mechanism... [ used by "internal" SGI ViewKit classes ]
    //
    VkGlobalData       *_globalData;

  private:

    // This class is not intended to be copied.  Strangers will get a
    // compile-time error.  Because there is no implementing code, friends
    // and inadvertant local use will get an ld-time error.  If a copy
    // constructor or operator= is ever needed, simply write them and
    // make these entries public.
    VkScreen(const VkScreen&);
    VkScreen &operator =(const VkScreen&);
}; 

#endif /* VKSCREEN_H */
