/*****************************************************************************
#   Copyright (C) 1994-2008 by David Gordon.
#   All rights reserved.                           
#                                                                           
#   This software is part of a beta-test version of the Consed/Autofinish
#   package.  It should not be redistributed or
#   used for any commercial purpose, including commercially funded
#   sequencing, without written permission from the author and the
#   University of Washington.
#   
#   This software is provided ``AS IS'' and any express or implied
#   warranties, including, but not limited to, the implied warranties of
#   merchantability and fitness for a particular purpose, are disclaimed.
#   In no event shall the authors or the University of Washington be
#   liable for any direct, indirect, incidental, special, exemplary, or
#   consequential damages (including, but not limited to, procurement of
#   substitute goods or services; loss of use, data, or profits; or
#   business interruption) however caused and on any theory of liability,
#   whether in contract, strict liability, or tort (including negligence
#   or otherwise) arising in any way out of the use of this software, even
#   if advised of the possibility of such damage.
#
#   Building Consed from source is error prone and not simple which is
#   why I provide executables.  Due to time limitations I cannot
#   provide any assistance in building Consed.  Even if you do not
#   modify the source, you may introduce errors due to using a
#   different version of the compiler, a different version of motif,
#   different versions of other libraries than I used, etc.  For this
#   reason, if you discover Consed bugs, I can only offer help with
#   those bugs if you first reproduce those bugs with an executable
#   provided by me--not an executable you have built.
# 
#   Modifying Consed is also difficult.  Although Consed is modular,
#   some modules are used by many other modules.  Thus making a change
#   in one place can have unforeseen effects on many other features.
#   It may takes months for you to notice these other side-effects
#   which may not seen connected at all.  It is not feasable for me to
#   provide help with modifying Consed sources because of the
#   potentially huge amount of time involved.
#
#*****************************************************************************/
//
// please_wait.cpp
//
// implementation for PleaseWait object
//
// David Gordon June 1995 
//




#include    <Xm/Xm.h>
#include    <Xm/MessageB.h>
#include    "guiapp.h"
#include    "please_wait.h"
#include    <unistd.h>
#include    <X11/Xlib.h>
#include    <Xm/Form.h>
#include    <Xm/Label.h>
#include    "busy_cursor.h"
#include    <Xm/MwmUtil.h>


static    int  aButton[] = { XmDIALOG_OK_BUTTON, XmDIALOG_CANCEL_BUTTON,
                             XmDIALOG_HELP_BUTTON };

static char* szInitialString = "Please wait...";

PleaseWait  ::  PleaseWait( Widget widTopLevelShellOfParent ) {


   widTopLevelShell_ =
      XtVaCreatePopupShell(
                           "Please wait...",
                           topLevelShellWidgetClass,
                           widTopLevelShellOfParent,
                           XmNdeleteResponse, XmDO_NOTHING,
                           XmNtransient, True,
                           XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE,
                           NULL );

   
   XmString xmsErrorMessage = XmStringCreateLtoR( "Please wait...",
                                                  XmFONTLIST_DEFAULT_TAG );

   
   Widget widMessageBox = XtVaCreateManagedWidget(
                                                  "Please wait...",
                                                  xmMessageBoxWidgetClass,
                                                  widTopLevelShell_,
                                                  XmNdialogType, XmDIALOG_WORKING,
                                                  XmNmessageString, xmsErrorMessage,
                                                  NULL );

   XmStringFree( xmsErrorMessage );


   for( int n = 0; n < sizeof( aButton ) / sizeof (int); ++n ) {
      Widget wid = XmMessageBoxGetChild( widMessageBox, aButton[n] );
      XtUnmanageChild( wid );
   }


   XtPopup( widTopLevelShell_, XtGrabNone );


   Widget diashell;
   Widget topshell;
   Window diawindow;
   Window topwindow;
   Display *dpy;
   XWindowAttributes xwa;
   XEvent event;
   XtAppContext cxt;



   /* Locate the shell we are interested in.  In a particular instance, you
    * may know these shells already.
    */
 
   //    for( diashell = widTopLevelShell_;
   //         !XtIsShell( diashell );
   //         diashell = XtParent( diashell ));


   /* Locate its primary window's shell (which may be the same) */
 
   //    for(topshell = diashell;
   //         !XtIsTopLevelShell(topshell);
   //        topshell = XtParent( topshell ) );


   topshell = GuiApp::pGetGuiApp()->widGetTopLevel();

   diashell = widTopLevelShell_;

   if (XtIsRealized(diashell) && XtIsRealized(topshell)) {
      dpy = XtDisplay(topshell);
      diawindow = XtWindow(diashell);
      topwindow = XtWindow(topshell);
      cxt = XtWidgetToApplicationContext(diashell);
 
      /* Wait for the dialog to be mapped.  It's guaranteed to become so unless... */
 
      while (XGetWindowAttributes(dpy, diawindow, &xwa),
             xwa.map_state != IsViewable) {
 
         /* ...if the primary is (or becomes) unviewable or unmapped, it's
            probably iconified, and nothing will happen. */
 
         if (XGetWindowAttributes(dpy, topwindow, &xwa),
             xwa.map_state != IsViewable)
            break;
 
         /* At this stage, we are guaranteed there will be an event of some kind.
            Beware; we are presumably in a callback, so this can recurse. */
 
         XtAppNextEvent(cxt, &event);
         XtDispatchEvent(&event);
      }
   }
 
   /* The next XSync() will get an expose event if the dialog was unmapped. */
 
   XmUpdateDisplay(topshell);


   busyCursor();

   //   GuiApp::pGetGuiApp()->mainLoop();

}

   

PleaseWait :: ~PleaseWait() {
   unbusyCursor();
   XtPopdown( widTopLevelShell_ );
   XtDestroyWidget( widTopLevelShell_ );
}