/*****************************************************************************
#   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.
#
#*****************************************************************************/
#include    <Xm/Xm.h>
#include    <Xm/MessageB.h>
#include    "guiapp.h"
#include    "popupErrorMessage.h"
#include    <Xm/MwmUtil.h>
#include    "consed.h"
#include    "consedParameters.h"
#include    "fileDefines.h"
#include    "breakIntoShorterLines.h"
#include    <unistd.h>
#include    "waitUntilDialogIsVisible.h"

extern int nNumberOfErrorWindowsCurrentlyUp; // defined in main



static void cbPopupMessage(Widget widEb, 
                    XtPointer pClientData,
                    XtPointer pCallData) {

   XtDestroyWidget( (Widget) pClientData );
   --nNumberOfErrorWindowsCurrentlyUp;

}



void popupInfoOrErrorMessageNoFormat( Widget widShellOfParent,
                                      const bool bErrorNotInfo,
                                      const char* szErrorMessage,
                                      const bool bAssemblyObjectValid ) {

   // if too many error messages already, don't report anything--even
   // just to stderr

   if ( pCP->bLimitNumberOfErrorsReported_ &&
        ( pCP->nNumberOfStartupErrors_ >  
          pCP->nMaximumStartupErrorsToReport_ ) )
      return;


   // send to standard error, even if autofinish is running (Feb 2004)
   cerr << szErrorMessage << endl;
   cerr << ConsEd:: pGetConsEd()->szGetConsedVersion() << endl;
   cerr.flush();

   if ( pCP->nWhatIsRunning_ == nAutoFinishIsRunning ) {
      fprintf( pAO, "%s\n", szErrorMessage );
      fprintf( pAO, "%s\n", 
               (const char*) ConsEd:: pGetConsEd()->szGetConsedVersion() );
      if ( bAssemblyObjectValid ) {
         Assembly* pAssembly = ConsEd::pGetAssembly();
         if ( pAssembly ) {

            fprintf( pAO, "ace file: %s\n",
                  (const char*) pAssembly->soGetAceFileName() );
         }
      }
      if ( bErrorNotInfo )
         fflush( pAO );
      return;
   }


   if ( bAssemblyObjectValid ) {
      Assembly* pAssembly = ConsEd::pGetAssembly();
      if ( pAssembly ) {
         cerr << "ace file: " << pAssembly->soGetAceFileName() << endl;
      }
   }

   if ( !consedParameters::pGetConsedParameters()->bOKToUseGui_ )
      return;


   if ( nNumberOfErrorWindowsCurrentlyUp == 20 ) {
      RWCString soErrorMessage2 = "Warning:  no more errors will be reported to you unless you dismiss some error message boxes.";
      int nTempNumberOfErrorWindowsCurrentlyUp = 
         nNumberOfErrorWindowsCurrentlyUp;  
      nNumberOfErrorWindowsCurrentlyUp = 0; // this lets this message 
      // be displayed.
      popupInfoOrErrorMessageNoFormat( widShellOfParent, 
                                       true, // bErrorNotInfo
                                       soErrorMessage2.data(),
                                       bAssemblyObjectValid );

      nNumberOfErrorWindowsCurrentlyUp = 
         nTempNumberOfErrorWindowsCurrentlyUp + 1;
      return;
   }
   

   if ( nNumberOfErrorWindowsCurrentlyUp > 20 )
      return;

   ++nNumberOfErrorWindowsCurrentlyUp;



   if ( widShellOfParent == NULL )
      widShellOfParent = GuiApp::pGetGuiApp()->widGetTopLevel();




   Widget widTopLevelShell = 
      XtVaCreatePopupShell( 
         ( bErrorNotInfo ? "error" : "info" ),
         topLevelShellWidgetClass,
         widShellOfParent,
         XmNdeleteResponse, XmDO_NOTHING,
         XmNtransient, True,
         XmNmwmDecorations, MWM_DECOR_ALL | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE,
         NULL );

   RWCString soMessage( szErrorMessage );

   // if there are any lines longer than 50 characters, break them up
   // into smaller lines
   const int nMaxLineLength = 50;

   breakIntoShorterLines( soMessage, nMaxLineLength );

   XmString xmsErrorMessage = XmStringCreateLtoR( (char*) soMessage.data(),
                                                  XmFONTLIST_DEFAULT_TAG );


   Widget widMessageBox = XtVaCreateManagedWidget(
                                 "messagebox",
                                 xmMessageBoxWidgetClass,
                                 widTopLevelShell,
                                 XmNmessageString, xmsErrorMessage,
                                 XmNdialogType, 
                    ( bErrorNotInfo ? XmDIALOG_ERROR : XmDIALOG_INFORMATION ),
                                 NULL );

   XmStringFree( xmsErrorMessage );

   Widget widOK = XmMessageBoxGetChild( widMessageBox,
                                        XmDIALOG_OK_BUTTON );

   XmString xms = XmStringCreateSimple( "Dismiss" );
   XtVaSetValues( widOK, XmNlabelString, xms, NULL );
   XmStringFree( xms );

   Widget widCancel = XmMessageBoxGetChild( widMessageBox,
                                            XmDIALOG_CANCEL_BUTTON );
   XtUnmanageChild( widCancel );

   Widget widHelp = XmMessageBoxGetChild( widMessageBox,
                                          XmDIALOG_HELP_BUTTON );
   XtUnmanageChild( widHelp );

   XtAddCallback( widMessageBox,
                  XmNokCallback,
                  (XtCallbackProc) cbPopupMessage,
                  (XtPointer) widTopLevelShell );

   XtPopup( widTopLevelShell, XtGrabNone );

   // Dispatch events until the message is drawn on the screen
   // This is important if an error message is to be displayed 
   // while doing a long amount of processing so that the event
   // loop will not be entered for a while.

   waitUntilDialogIsVisible( widTopLevelShell );


   XRaiseWindow(
                XtDisplay( widTopLevelShell ),
                XtWindow( widTopLevelShell )
                );


}